diff --git a/.github/workflows/release-deploy.yml b/.github/workflows/release-deploy.yml index c7b718e61..76ff3306d 100644 --- a/.github/workflows/release-deploy.yml +++ b/.github/workflows/release-deploy.yml @@ -5,9 +5,6 @@ on: branches: ['releases/v*'] types: [closed] -env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - jobs: release-deploy: @@ -15,10 +12,8 @@ jobs: runs-on: ubuntu-latest steps: - - name: Grab PR Title + - name: Configure release run: | - set -e - PR_TITLE=$(jq -r ".pull_request.title" $GITHUB_EVENT_PATH) PR_BODY=$(jq -r ".pull_request.body" $GITHUB_EVENT_PATH) RELEASE_TAG=$(echo "${PR_TITLE}" | grep -oP "(?<=^Release: )v\d+\.\d+\.\d+(-rc\.\d+)?$") @@ -37,14 +32,12 @@ jobs: echo "${PR_BODY}" >> $GITHUB_ENV echo 'END_OF_PR_BODY' >> $GITHUB_ENV - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create release + uses: ncipollo/release-action@v1 with: - tag_name: '${{ env.RELEASE_TAG }}' - release_name: '${{ env.RELEASE_TAG }}' + token: ${{ secrets.GITHUB_TOKEN }} + commit: '${{ github.sha }}' + tag: '${{ env.RELEASE_TAG }}' body: '${{ env.PR_BODY }}' draft: false prerelease: ${{ env.RELEASE_PRERELEASE }} diff --git a/.github/workflows/release-validate.yml b/.github/workflows/release-validate.yml index 8b79b7a48..1df8a00ec 100644 --- a/.github/workflows/release-validate.yml +++ b/.github/workflows/release-validate.yml @@ -14,10 +14,8 @@ jobs: runs-on: ubuntu-latest steps: - - name: Grab PR Title + - name: Validate PR title run: | - set -e - PR_TITLE=$(jq -r ".pull_request.title" $GITHUB_EVENT_PATH) # check title format and extract tag @@ -30,7 +28,7 @@ jobs: fi # check that tag doesn't exist - if git ls-remote --exit-code origin "refs/tags/${RELEASE_TAG}"; then + if git ls-remote --exit-code "https://${GITHUB_ACTOR}:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}" "refs/tags/${RELEASE_TAG}"; then echo "The PR title's version exists already" exit 1 fi diff --git a/.github/workflows/test-e2e.yml b/.github/workflows/test-e2e.yml new file mode 100644 index 000000000..30e76c96f --- /dev/null +++ b/.github/workflows/test-e2e.yml @@ -0,0 +1,111 @@ +name: 'Test: End-to-end' + +on: pull_request + +env: + HAB_LICENSE: accept-no-persist + HOLO_CACHE_TO: origin + HOLO_CACHE_FROM: origin + +jobs: + test-e2e: + + runs-on: ubuntu-latest + steps: + + - uses: actions/checkout@v2 + + # TODO: wrap the next three steps an an emergence-studio action + - name: 'Stop default mysql service' + run: sudo service mysql stop + + - name: 'Initialize Chef Habitat environment' + uses: JarvusInnovations/habitat-action@action/v1 + env: + HAB_NGINX: | + [http.listen] + port = 7080 + HAB_MYSQL: | + app_username = 'appadmin' + app_password = 'appadmin' + bind = '0.0.0.0' + HAB_PHP_RUNTIME: | + [sites.default.holo] + gitDir = '${{ github.workspace }}/.git' + with: + deps: | + jarvus/hologit + supervisor: | + core/mysql + emergence/php-runtime --bind="database:mysql.default" + emergence/nginx --bind="backend:php-runtime.default" + + - name: Waiting for MySQL + run: | + until nc -z localhost 3306; do + sleep 0.5 + echo -n "." + done + + - name: Waiting for Emergence runtime + run: | + until nc -z localhost 9123; do + sleep 0.5 + echo -n "." + done + + - name: Configure command-line client access + run: | + sudo chmod ugo+xr \ + /hab/svc/mysql/config \ + /hab/svc/mysql/config/client.cnf \ + /hab/svc/php-runtime/config \ + /hab/svc/php-runtime/config/fpm-exec + + ln -sf /hab/svc/mysql/config/client.cnf ~/.my.cnf + + - name: Load site projection into emergence runtime + env: + HOLO_CACHE_FROM: origin + HOLO_CACHE_TO: origin + run: | + SITE_TREE="$(hab pkg exec jarvus/hologit git-holo project emergence-site)" + [ -n "${SITE_TREE}" ] || exit 1 + hab pkg exec emergence/php-runtime emergence-php-load "${SITE_TREE}" + + - name: Set up Cypress workspace + run: | + CYPRESS_TREE="$(hab pkg exec jarvus/hologit git-holo project cypress-workspace)" + [ -n "${CYPRESS_TREE}" ] || exit 1 + mkdir "${GITHUB_WORKSPACE}.cypress-workspace" + git archive --format=tar "${CYPRESS_TREE}" | (cd "${GITHUB_WORKSPACE}.cypress-workspace" && tar xf -) + + - name: Run Cypress tests + uses: cypress-io/github-action@v2 + env: + GIT_DIR: ${{ github.workspace }}/.git + GIT_WORK_TREE: ${{ github.workspace }} + with: + env: STUDIO_CONTAINER=,STUDIO_SSH= + working-directory: ${{ github.workspace }}.cypress-workspace + + - name: Upload supervisor log + uses: actions/upload-artifact@v1 + if: always() + with: + name: supervisor-log + path: /hab/sup/default/sup.log + + - name: Upload Cypress screenshots + uses: actions/upload-artifact@v1 + if: failure() + with: + name: cypress-screenshots + path: ${{ github.workspace }}.cypress-workspace/cypress/screenshots + + - name: Upload Cypress videos + uses: actions/upload-artifact@v1 + if: always() + with: + name: cypress-videos + path: ${{ github.workspace }}.cypress-workspace/cypress/videos diff --git a/.holo/branches/cypress-workspace/_skeleton-v1.toml b/.holo/branches/cypress-workspace/_skeleton-v1.toml new file mode 100644 index 000000000..e140b0b00 --- /dev/null +++ b/.holo/branches/cypress-workspace/_skeleton-v1.toml @@ -0,0 +1,7 @@ +[holomapping] +files = [ + "cypress/**", + "cypress.json", + "package.json", + "package-lock.json", +] diff --git a/.holo/lenses/emergence-cms-editor.toml b/.holo/lenses/emergence-cms-editor.toml index 8fe40ce79..584f5d782 100644 --- a/.holo/lenses/emergence-cms-editor.toml +++ b/.holo/lenses/emergence-cms-editor.toml @@ -10,7 +10,6 @@ files = [ "EmergenceContentEditor/**", "packages/emr-skeleton-theme/**", "packages/emergence-cms/**", - "packages/emergence-cms-summaries/**", "packages/emergence-apikit/**", "packages/jarvus-apikit/**", "packages/jarvus-fileupload/**", diff --git a/cypress.json b/cypress.json index ee00dda33..c59c4a1c4 100644 --- a/cypress.json +++ b/cypress.json @@ -2,7 +2,7 @@ "baseUrl": "http://localhost:7080", "env": { "STUDIO_SSH": null, - "STUDIO_CONTAINER": "emergence-studio" + "STUDIO_CONTAINER": "skeleton-studio" }, "viewportWidth": 1200, "viewportHeight": 660 diff --git a/cypress/integration/blog.js b/cypress/integration/blog.js new file mode 100644 index 000000000..72d5564b1 --- /dev/null +++ b/cypress/integration/blog.js @@ -0,0 +1,110 @@ +describe('Blogging', () => { + + // reset database before tests + before(() => { + cy.resetDatabase(); + }); + + it('Create post', () => { + cy.loginAs('user', 'user'); + + cy.visit('/blog'); + + cy.contains('Create a Post').click(); + + cy.get('.x-panel.emergence-cms-editor .x-btn[id^=emergence-cms-toolbar-][id$=-menu-trigger]') + .click(); + + cy.contains('.x-menu-item-text[id^=menuitem-]', 'Publish on save') + .click(); + + cy.contains('.x-menu-item-text[id^=menucheckitem-]', 'Publish on save') + .click(); + + cy.get('input[id^=datefield-]') + .type('{selectall}01/02/2030'); + + cy.get('input[id^=timefield-]') + .type('{selectall}4:05 pm{enter}'); + + cy.get('.x-component.emergence-cms-preview time[data-ref="timeEl"]') + .should('contain', 'Wednesday, January 2, 2030 at 4:05 pm') + .click(); + + cy.get('.x-panel.emergence-cms-editor .x-btn[id^=emergence-cms-toolbar-][id$=-menu-trigger]') + .click(); + + cy.contains('.x-menu-item-text[id^=menuitem-]', '1/2/2030 4:05 pm'); + + cy.get('.x-field.field-title input') + .type('Hello world!') + .tab(); + + cy.focused() + .should('contain', 'Save') + .tab(); + + cy.focused() + .wait(500) + .type('tag1{enter}tag2'); + + cy.get('.x-panel-body .x-field textarea') + .type('## Header 2{enter}{enter}### Header 3{enter}{enter}- point 1{enter}- point2{enter}'); + + cy.contains('.x-btn.save-btn', 'Save') + .click(); + + cy.location('pathname').should('eq', '/blog/hello_world/edit'); + cy.location('search').should('be.empty'); + + cy.get('.x-component.emergence-cms-preview').within(() => { + + cy.get('time[data-ref="timeEl"]') + .should('contain', 'Wednesday, January 2, 2030 at 4:05 pm'); + + cy.get('[data-ref=tagsCt] a') + .should('have.length', 2) + .first() + .should('have.attr', 'href', '/tags/tag1') + .should('have.text', 'tag1') + .next() + .should('have.attr', 'href', '/tags/tag2') + .should('have.text', 'tag2'); + }); + }); + + it('Edit post', () => { + cy.loginAs('user', 'user'); + + cy.visit('/drafts'); + + cy.contains('Hello world!') + .should('have.attr', 'href', '/blog/hello_world') + .click(); + + cy.contains('Edit') + .should('have.attr', 'href', '/blog/hello_world/edit') + .click(); + + cy.get('.x-panel.emergence-cms-editor .x-btn[id^=emergence-cms-toolbar-][id$=-menu-trigger]') + .click(); + + cy.contains('.x-menu-item-text[id^=menuitem-]', '1/2/2030 4:05 pm') + .click(); + + cy.get('input[id^=timefield-]') + .type('{selectall}6:07 pm{enter}'); + + cy.get('.x-component.emergence-cms-preview time[data-ref="timeEl"]') + .should('contain', 'Wednesday, January 2, 2030 at 6:07 pm') + .click(); + + cy.contains('.x-btn.save-btn', 'Save') + .click(); + + cy.reload(); + + cy.get('.x-component.emergence-cms-preview time[data-ref="timeEl"]') + .should('contain', 'Wednesday, January 2, 2030 at 6:07 pm'); + }); +}); \ No newline at end of file diff --git a/cypress/integration/register.js b/cypress/integration/register.js index b9f29d19e..ea3010acd 100644 --- a/cypress/integration/register.js +++ b/cypress/integration/register.js @@ -1,66 +1,78 @@ -describe('Admin login test', () => { +describe('Registration and profile', () => { // reset database before tests before(() => { cy.dropDatabase(); }); - it('Register and set up profile', () => { + it('Register user', () => { cy.visit('/'); cy.contains('Register').click(); cy.location('pathname').should('eq', '/register'); - cy.focused() + cy.get('input[name=FirstName]') + .focus() .should('have.attr', 'name', 'FirstName') .type('Fname') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'LastName') .type('Lname') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'Email') .type('email@example.org') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'Username') .type('zerocool') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'Password') .type('password123') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'PasswordConfirm') - .type('password1234{enter}') - ; + .type('password1234{enter}'); cy.location('pathname').should('eq', '/register'); cy.get('.error'); - cy.focused() + cy.get('input[name=Password]') + .should('have.value', 'password123'); + + cy.get('input[name=PasswordConfirm]') + .should('have.value', 'password1234') + .parent('.field') + .should('have.class', 'has-error') + .find('.error-text') + .contains('Please enter your password a second time for confirmation'); + + cy.get('input[name=FirstName]') + .focus() .should('have.attr', 'name', 'FirstName') .tab() .tab() .tab() .tab() .tab() - .type('password123{enter}') - ; + .type('password123{enter}'); cy.contains('Fill out your profile').click(); + cy.location('pathname').should('eq', '/profile'); + cy.location('search').should('be.empty'); + }); + + it('Upload profile photos', () => { + cy.loginAs('zerocool', 'password123'); + cy.visit('/profile'); // upload same photo twice cy.upload_file('photo.jpg', 'image/jpeg', 'input[type=file]'); @@ -72,69 +84,56 @@ describe('Admin login test', () => { .should('have.class', 'highlight') .should('not.contain', 'Make Default') .next('.photo') - .should('not.have.class', 'highlight') - .contains('Make Default') - .click() - ; + .should('not.have.class', 'highlight') + .contains('Make Default') + .click(); cy.get('.photosGallery .photo:first-child') .should('not.have.class', 'highlight') .should('contain', 'Make Default') .next('.photo') - .should('have.class', 'highlight') - .should('not.contain', 'Make Default') - .find('img') - .should('have.attr', 'src', '/thumbnail/2/100x100') - .should('have.prop', 'width', 100) - .should('have.prop', 'height', 75) - ; - - // edit profile + .should('have.class', 'highlight') + .should('not.contain', 'Make Default') + .find('img') + .should('have.attr', 'src', '/thumbnail/2/100x100') + .should('have.prop', 'width', 100) + .should('have.prop', 'height', 75); + }); + + it('Fill out profile', () => { + cy.loginAs('zerocool', 'password123'); + cy.visit('/profile'); + cy.get('input[name=Location]') .type('Philadelphia, PA') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'About') .type('Meow') - .tab() - ; + .tab(); cy.focused() .should('contain', 'Markdown codes') .should('have.attr', 'target', '_blank') - .tab() - ; + .tab(); cy.focused() .should('contain', 'Save profile') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'Email') .type('email@example.com') - .tab() - ; + .tab(); cy.focused() .should('have.attr', 'name', 'Phone') - .type('(123) 456-7890{enter}') - ; + .type('(123) 456-7890{enter}'); cy.location('pathname').should('eq', '/profile'); cy.location('search').should('eq', '?status=saved'); - // verify profile display page - cy.visit('/profile/view'); - cy.location('pathname').should('eq', '/people/zerocool'); - cy.get('.header-title').should('contain', 'Fname Lname'); - cy.get('a[href^="http://maps.google.com/"]').should('contain', 'Philadelphia, PA'); - cy.get('#display-photo-link').should('have.attr', 'href', '/media/open/2'); - cy.get('.photo-thumb').should('have.length', 2); - cy.get('#info .about').should('contain', 'Meow'); - // verify profile API data cy.request('/profile?format=json').its('body.data').then(data => { expect(data).to.have.property('ID', 1); @@ -150,4 +149,18 @@ describe('Admin login test', () => { expect(data).to.have.property('AccountLevel', 'User'); }); }); + + it('View profile', () => { + cy.loginAs('zerocool', 'password123'); + cy.visit('/profile'); + + // verify profile display page + cy.visit('/profile/view'); + cy.location('pathname').should('eq', '/people/zerocool'); + cy.get('.header-title').should('contain', 'Fname Lname'); + cy.get('a[href^="http://maps.google.com/"]').should('contain', 'Philadelphia, PA'); + cy.get('#display-photo-link').should('have.attr', 'href', '/media/open/2'); + cy.get('.photo-thumb').should('have.length', 2); + cy.get('#info .about').should('contain', 'Meow'); + }); }); \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js index f96e080a6..a74ca6dd9 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -27,71 +27,86 @@ // from https://github.com/javieraviles/cypress-upload-file-post-form Cypress.Commands.add('upload_file', (fileName, fileType = ' ', selector) => { cy.get(selector).then(subject => { - cy.fixture(fileName, 'base64') - .then(Cypress.Blob.base64StringToBlob) - .then(blob => { - const el = subject[0] - const testFile = new File([blob], fileName, { type: fileType }) - const dataTransfer = new DataTransfer() - dataTransfer.items.add(testFile) - el.files = dataTransfer.files - }) + cy.fixture(fileName, 'base64') + .then(Cypress.Blob.base64StringToBlob) + .then(blob => { + const el = subject[0] + const testFile = new File([blob], fileName, { type: fileType }) + const dataTransfer = new DataTransfer() + dataTransfer.items.add(testFile) + el.files = dataTransfer.files + }) }) - }); +}); // Login command -Cypress.Commands.add('loginAs', (user) => { - cy.visit('/'); - cy.request({ - method: 'POST', - url: '/login/?format=json', - form: true, - body: { - '_LOGIN[username]': user, - '_LOGIN[password]': user, - '_LOGIN[returnMethod]': 'POST' - } - }); +Cypress.Commands.add('loginAs', (user, password) => { + cy.visit('/'); + cy.request({ + method: 'POST', + url: '/login/?format=json', + form: true, + body: { + '_LOGIN[username]': user, + '_LOGIN[password]': password || user, + '_LOGIN[returnMethod]': 'POST' + } + }); }); // Drop and load database in one step Cypress.Commands.add('resetDatabase', () => { - cy.dropDatabase(); - cy.loadDatabase(); + cy.dropDatabase(); + cy.loadDatabase(); }); // Drops the entire Cypress.Commands.add('dropDatabase', () => { - cy.exec(`echo 'DROP DATABASE IF EXISTS \`default\`; CREATE DATABASE \`default\`;' | ${_buildHabExec('core/mysql', 'mysql')} -u root -h 127.0.0.1`); + cy.exec(`echo 'DROP DATABASE IF EXISTS \`default\`; CREATE DATABASE \`default\`;' | ${_buildHabExec('core/mysql', 'mysql')} -u root -h 127.0.0.1`); }); // Reload the original data fixtures Cypress.Commands.add('loadDatabase', () => { - cy.exec(`cat cypress/fixtures/database/*.sql | ${_buildHabExec('core/mysql', 'mysql')} -u root -h 127.0.0.1 default`); + cy.exec(`${_buildHabExec('jarvus/hologit', 'git')} holo project fixtures --working`) + .then(({ stdout: treeHash }) => { + if (!treeHash) { + throw new Error('unable to compute tree hash for fixtures data'); + } + + cy.exec(`${_buildHabExec('emergence/php-runtime', 'bash')} -c ' + ( + for fixture_file in $(git ls-tree -r --name-only ${treeHash}); do + git cat-file -p "${treeHash}:\${fixture_file}" + done + ) | mysql default + '`); + + cy.exec(`${_buildHabExec('emergence/php-runtime', 'emergence-console-run')} migrations:execute --all`); + }); }); // Ext command getter Cypress.Commands.add('withExt', () => { - cy.window().then((win) => { - const Ext = win.Ext; - return { - Ext: win.Ext, - extQuerySelector: query => Ext.ComponentQuery.query(query)[0], - extQuerySelectorAll: query => Ext.ComponentQuery.query(query) - }; - }); + cy.window().then((win) => { + const Ext = win.Ext; + return { + Ext: win.Ext, + extQuerySelector: query => Ext.ComponentQuery.query(query)[0], + extQuerySelectorAll: query => Ext.ComponentQuery.query(query) + }; + }); }); // private method function _buildHabExec(pkg, pkgCmd) { - const studioContainer = Cypress.env('STUDIO_CONTAINER') || null; - const studioSSH = Cypress.env('STUDIO_SSH') || null; + const studioContainer = Cypress.env('STUDIO_CONTAINER') || null; + const studioSSH = Cypress.env('STUDIO_SSH') || null; - let cmd = `hab pkg exec ${pkg} ${pkgCmd}`; + let cmd = `hab pkg exec ${pkg} ${pkgCmd}`; - if (studioContainer) { - cmd = `${studioSSH ? `ssh ${studioSSH}` : ''} docker exec -i ${studioContainer} ${cmd}`; - } + if (studioContainer) { + cmd = `${studioSSH ? `ssh ${studioSSH}` : ''} docker exec -i ${studioContainer} ${cmd}`; + } - return cmd; + return cmd; } diff --git a/docs/development/getting-started/content-editor.md b/docs/development/getting-started/content-editor.md index 23733e45b..d0420711d 100644 --- a/docs/development/getting-started/content-editor.md +++ b/docs/development/getting-started/content-editor.md @@ -5,7 +5,6 @@ - `sencha-workspace/` - `packages/` - `emergence-cms/`: Primary location for content editor UI code - - `emergence-cms-summaries/`: Optional plugin that adds UI for attaching summaries to content - `emr-skeleton-theme/`: The Sencha theme used when rendering the content editor - `EmergenceContentEditor/`: A thin Sencha application used to make development easier and to provide a build target for generating the theme - `html-templates/` diff --git a/docs/development/testing/e2e.md b/docs/development/testing/e2e.md index 263925f76..aad5700bb 100644 --- a/docs/development/testing/e2e.md +++ b/docs/development/testing/e2e.md @@ -6,10 +6,46 @@ To get started, from a terminal **outside the studio** in the root of the repository: -```bash -# install development tooling locally -npm install +1. Install development tooling locally: -# launch cypress app -npm run cypress:open -``` + ```bash + npm install + ``` + +2. Launch the Cypress GUI: + + ```bash + npm run cypress:open + ``` + +## Testing against a remote server + +By setting environment variables before launching the Cypress GUI, the E2E test suite can be configured to execute against a backend studio hosted on a remote machine or server. + +On the local terminal **outside the studio** in the root of the repository: + +1. Set base URL to studo HTTP root reachable from local workstation: + + ```bash + export CYPRESS_BASE_URL='http://workstation.mydomain:7080' + ``` + +2. Configure the SSH host that the backend studio is running on: + + ```bash + export CYPRESS_STUDIO_SSH='workstation.mydomain' + ``` + + Your local terminal must be set up to connect to it without password. + +3. Configure the name of the Docker container running the backend studio: + + ```bash + export CYPRESS_STUDIO_CONTAINER='{{ studio.name }}' + ``` + +4. Launch the Cypress GUI: + + ```bash + npm run cypress:open + ``` diff --git a/html-templates/blog/blogPosts.tpl b/html-templates/blog/blogPosts.tpl index 586165e6d..5fdde1d6b 100644 --- a/html-templates/blog/blogPosts.tpl +++ b/html-templates/blog/blogPosts.tpl @@ -3,17 +3,17 @@ {block "content"} {load_templates "subtemplates/blog.tpl"} {load_templates "subtemplates/paging.tpl"} - + - +
{foreach item=BlogPost from=$data} - {blogPost $BlogPost headingLevel=h3} + {blogPost $BlogPost headingLevel=h3 useSummary=true} {foreachelse}

Stay tuned for the first post…

{/foreach} @@ -24,4 +24,4 @@ {$total|number_format} posts: {pagingLinks $total pageSize=$limit} {/if} -{/block} \ No newline at end of file +{/block} diff --git a/html-templates/designs/site.tpl b/html-templates/designs/site.tpl index b20b307b9..c77c07cbe 100644 --- a/html-templates/designs/site.tpl +++ b/html-templates/designs/site.tpl @@ -42,7 +42,7 @@ {block "header"} {* the things in here should probably be set up as configurable subtemplates in some way (especially nav) *}

- {$.Site.title|escape} + {$.Site.title|escape}

@@ -100,4 +100,4 @@ {log_report} - \ No newline at end of file + diff --git a/html-templates/register/register.tpl b/html-templates/register/register.tpl index 66484f3e3..437baa17a 100644 --- a/html-templates/register/register.tpl +++ b/html-templates/register/register.tpl @@ -29,17 +29,54 @@
- {* field name label='' error='' type=text placeholder='' hint='' required=false attribs='' default=null class=null *} - {field FirstName 'First Name' $errors.FirstName text '' '' true 'autofocus'} - {field LastName 'Last Name' $errors.LastName text '' '' true} + {field + inputName=FirstName + label='First Name' + error=$errors.FirstName + required=true + autofocus=true + } + + {field + inputName=LastName + label='Last Name' + error=$errors.LastName + required=true + }
- {field Email 'Email Address' $errors.Email email '' '' true} - {field Username 'Username' $errors.Username text '' '' true 'autocapitalize="none" autocorrect="off"'} + {field + inputName=Email + label='Email Address' + error=$errors.Email + type=email + required=true + } + + {field + inputName=Username + label='Username' + error=$errors.Username + required=true + attribs='autocapitalize="none" autocorrect="off"' + }
- {field Password 'Password' $errors.Password password '' '' true} - {field PasswordConfirm '(Confirm)' $errors.PasswordConfirm password '' '' true} + {field + inputName=Password + label='Password' + error=$errors.Password + type=password + required=true + } + + {field + inputName=PasswordConfirm + label='(Confirm)' + error=$errors.PasswordConfirm + type=password + required=true + }
{if RemoteSystems\ReCaptcha::$siteKey} diff --git a/mkdocs.yml b/mkdocs.yml index f79dbe2b6..44a7dd4bd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ extra: name: emergence-skeleton url: git@github.com:JarvusInnovations/emergence-skeleton.git studio: + name: skeleton-studio web_port: 7080 static_port: 7081 docs_port: 7088 diff --git a/package-lock.json b/package-lock.json index 80e5c6572..459c15571 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "slate-cbl-devtools", + "name": "emergence-skeleton-devtools", "version": "1.0.0", "lockfileVersion": 1, "requires": true, @@ -37,6 +37,34 @@ } } }, + "@cypress/request": { + "version": "2.88.5", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz", + "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, "@cypress/xvfb": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", @@ -45,21 +73,64 @@ "requires": { "debug": "^3.1.0", "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, + "@types/node": { + "version": "14.17.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.3.tgz", + "integrity": "sha512-e6ZowgGJmTuXa3GyaPbTGxX17tnThl2aSSizrFthQ7m9uLGZBXiGhgE55cjRZTF5kjZvYn9EOPOMljdjwbflxw==", + "dev": true + }, + "@types/sinonjs__fake-timers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.2.tgz", + "integrity": "sha512-dIPoZ3g5gcx9zZEszaxLSVTvMReD3xxyyDnQUjA6IYDG9Ba2AV0otMPs+77sG9ojB4Qr2N2Vk5RnKeuA0X/0bg==", + "dev": true + }, "@types/sizzle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", - "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", "dev": true }, + "@types/yauzl": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz", + "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" @@ -76,10 +147,13 @@ } }, "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "requires": { + "type-fest": "^0.21.3" + } }, "ansi-regex": { "version": "2.1.1", @@ -94,9 +168,9 @@ "dev": true }, "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", - "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", "dev": true }, "asn1": { @@ -114,14 +188,17 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", - "dev": true, - "requires": { - "lodash": "^4.17.10" - } + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "dev": true }, "asynckit": { "version": "0.4.0", @@ -129,6 +206,12 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -136,15 +219,15 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "bcrypt-pbkdf": { @@ -156,10 +239,16 @@ "tweetnacl": "^0.14.3" } }, + "blob-util": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/blob-util/-/blob-util-2.0.2.tgz", + "integrity": "sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==", + "dev": true + }, "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", "dev": true }, "brace-expansion": { @@ -178,20 +267,11 @@ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", "dev": true }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, "cachedir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", - "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", - "dev": true, - "requires": { - "os-homedir": "^1.0.1" - } + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", + "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", + "dev": true }, "caseless": { "version": "0.12.0", @@ -200,23 +280,31 @@ "dev": true }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "dependencies": { "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "has-flag": "^4.0.0" } } } @@ -228,9 +316,15 @@ "dev": true }, "ci-info": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", "dev": true }, "cli-cursor": { @@ -242,43 +336,55 @@ "restore-cursor": "^1.0.1" } }, - "cli-spinners": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", - "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", - "dev": true + "cli-table3": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", + "integrity": "sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ==", + "dev": true, + "requires": { + "colors": "^1.1.2", + "object-assign": "^4.1.0", + "string-width": "^4.2.0" + } }, "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "requires": { - "slice-ansi": "0.0.4", - "string-width": "^1.0.1" + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", "dev": true }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "optional": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -289,9 +395,9 @@ } }, "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", "dev": true }, "common-tags": { @@ -306,18 +412,6 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -325,16 +419,14 @@ "dev": true }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "css.escape": { @@ -344,50 +436,56 @@ "dev": true }, "cypress": { - "version": "3.8.2", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.8.2.tgz", - "integrity": "sha512-aTs0u3+dfEuLe0Ct0FVO5jD1ULqxbuqWUZwzBm0rxdLgLxIAOI/A9f/WkgY5Cfy1TEXe8pKC6Wal0ZpnkdGRSw==", - "dev": true, - "requires": { - "@cypress/listr-verbose-renderer": "0.4.1", - "@cypress/xvfb": "1.2.4", - "@types/sizzle": "2.3.2", - "arch": "2.1.1", - "bluebird": "3.5.0", - "cachedir": "1.3.0", - "chalk": "2.4.2", - "check-more-types": "2.24.0", - "commander": "2.15.1", - "common-tags": "1.8.0", - "debug": "3.2.6", - "eventemitter2": "4.1.2", - "execa": "0.10.0", - "executable": "4.1.1", - "extract-zip": "1.6.7", - "fs-extra": "5.0.0", - "getos": "3.1.1", - "is-ci": "1.2.1", - "is-installed-globally": "0.1.0", - "lazy-ass": "1.6.0", - "listr": "0.12.0", - "lodash": "4.17.15", - "log-symbols": "2.2.0", - "minimist": "1.2.0", - "moment": "2.24.0", - "ramda": "0.24.1", - "request": "2.88.0", - "request-progress": "3.0.0", - "supports-color": "5.5.0", - "tmp": "0.1.0", - "untildify": "3.0.3", - "url": "0.11.0", - "yauzl": "2.10.0" + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-7.5.0.tgz", + "integrity": "sha512-tw3v6nrTJoEzT37+Nf6RK+DvdTfhMb8EJYskZx7oskZ+J9qQ1QHWA4dH8Eoe/Mr/wE47o+7PK6O9tgqhRy6IHg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "^0.4.1", + "@cypress/request": "^2.88.5", + "@cypress/xvfb": "^1.2.4", + "@types/node": "^14.14.31", + "@types/sinonjs__fake-timers": "^6.0.2", + "@types/sizzle": "^2.3.2", + "arch": "^2.2.0", + "blob-util": "^2.0.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^4.1.0", + "check-more-types": "^2.24.0", + "cli-table3": "~0.6.0", + "commander": "^5.1.0", + "common-tags": "^1.8.0", + "dayjs": "^1.10.4", + "debug": "4.3.2", + "eventemitter2": "^6.4.3", + "execa": "4.1.0", + "executable": "^4.1.1", + "extract-zip": "2.0.1", + "fs-extra": "^9.1.0", + "getos": "^3.2.1", + "is-ci": "^3.0.0", + "is-installed-globally": "~0.4.0", + "lazy-ass": "^1.6.0", + "listr2": "^3.8.3", + "lodash": "^4.17.21", + "log-symbols": "^4.0.0", + "minimist": "^1.2.5", + "ospath": "^1.2.2", + "pretty-bytes": "^5.6.0", + "ramda": "~0.27.1", + "request-progress": "^3.0.0", + "supports-color": "^8.1.1", + "tmp": "~0.2.1", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" } }, "cypress-plugin-tab": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cypress-plugin-tab/-/cypress-plugin-tab-1.0.1.tgz", - "integrity": "sha512-DsRp10fegpxSP6oaJ3Sq/fjvXdr5rXXcZ9mGlmzLiHb5TZi5gszy34n/5tkcPYkdWphzZqJ+p74agWKqQ5A7Vw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/cypress-plugin-tab/-/cypress-plugin-tab-1.0.5.tgz", + "integrity": "sha512-QtTJcifOVwwbeMP3hsOzQOKf3EqKsLyjtg9ZAGlYDntrCRXrsQhe4ZQGIthRMRLKpnP6/tTk6G0gJ2sZUfRliQ==", "dev": true, "requires": { "ally.js": "^1.4.1" @@ -408,13 +506,27 @@ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", "dev": true }, + "dayjs": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz", + "integrity": "sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g==", + "dev": true + }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "delayed-stream": { @@ -433,12 +545,21 @@ "safer-buffer": "^2.1.0" } }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -446,24 +567,37 @@ "dev": true }, "eventemitter2": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz", - "integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU=", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.4.tgz", + "integrity": "sha512-HLU3NDY6wARrLCEwyGKRBvuWYyvW6mHYv72SJJAH3iJN3a6eVUvkjFkcxah1bcTgGVBBrFdIopBJPhCQFMLyXw==", "dev": true }, "execa": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", - "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + } } }, "executable": { @@ -488,41 +622,15 @@ "dev": true }, "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "dev": true, "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", - "dev": true, - "requires": { - "fd-slicer": "~1.0.1" - } - } + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" } }, "extsprintf": { @@ -532,9 +640,9 @@ "dev": true }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-json-stable-stringify": { @@ -544,9 +652,9 @@ "dev": true }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, "requires": { "pend": "~1.2.0" @@ -580,14 +688,15 @@ } }, "fs-extra": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", - "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" } }, "fs.realpath": { @@ -597,18 +706,21 @@ "dev": true }, "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } }, "getos": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.1.tgz", - "integrity": "sha512-oUP1rnEhAr97rkitiszGP9EgDVYnmchgFzfqRzSkgtfv7ai6tEi7Ko8GgjNXts7VLWEqrTWyhsOKLe5C5b/Zkg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.2.1.tgz", + "integrity": "sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==", "dev": true, "requires": { - "async": "2.6.1" + "async": "^3.2.0" } }, "getpass": { @@ -621,9 +733,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -635,18 +747,18 @@ } }, "global-dirs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz", + "integrity": "sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA==", "dev": true, "requires": { - "ini": "^1.3.4" + "ini": "2.0.0" } }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "har-schema": { @@ -656,12 +768,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -675,9 +787,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "http-signature": { @@ -691,14 +803,17 @@ "sshpk": "^1.7.0" } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true }, "inflight": { "version": "1.0.6", @@ -717,67 +832,46 @@ "dev": true }, "ini": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", - "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", "dev": true }, "is-ci": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", - "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", - "dev": true, - "requires": { - "ci-info": "^1.5.0" - } - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "ci-info": "^3.1.1" } }, "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "is-installed-globally": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", + "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", "dev": true, "requires": { - "global-dirs": "^0.1.0", - "is-path-inside": "^1.0.0" + "global-dirs": "^3.0.0", + "is-path-inside": "^3.0.2" } }, "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", - "dev": true, - "requires": { - "path-is-inside": "^1.0.1" - } - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", "dev": true }, "is-typedarray": { @@ -786,10 +880,10 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true }, "isexe": { @@ -829,12 +923,13 @@ "dev": true }, "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" } }, "jsprim": { @@ -855,197 +950,158 @@ "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", "dev": true }, - "listr": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", - "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "listr2": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.10.0.tgz", + "integrity": "sha512-eP40ZHihu70sSmqFNbNy2NL1YwImmlMmPh9WO5sLmPDleurMHt3n+SwEWNu2kzKScexZnkyFtc1VI0z/TGlmpw==", "dev": true, "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "figures": "^1.7.0", - "indent-string": "^2.1.0", - "is-promise": "^2.1.0", - "is-stream": "^1.1.0", - "listr-silent-renderer": "^1.1.1", - "listr-update-renderer": "^0.2.0", - "listr-verbose-renderer": "^0.4.0", - "log-symbols": "^1.0.2", - "log-update": "^1.0.2", - "ora": "^0.2.3", - "p-map": "^1.1.1", - "rxjs": "^5.0.0-beta.11", - "stream-to-observable": "^0.1.0", - "strip-ansi": "^3.0.1" + "cli-truncate": "^2.1.0", + "colorette": "^1.2.2", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rxjs": "^6.6.7", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" }, "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "color-convert": "^2.0.1" } }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "chalk": "^1.0.0" + "restore-cursor": "^3.1.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", - "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-truncate": "^0.2.1", - "elegant-spinner": "^1.0.1", - "figures": "^1.7.0", - "indent-string": "^3.0.0", - "log-symbols": "^1.0.2", - "log-update": "^1.0.2", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "mimic-fn": "^2.1.0" } }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "chalk": "^1.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-verbose-renderer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", - "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "cli-cursor": "^1.0.2", - "date-fns": "^1.27.2", - "figures": "^1.7.0" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-regex": "^5.0.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } } } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "log-update": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", - "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", - "dev": true, - "requires": { - "ansi-escapes": "^1.0.0", - "cli-cursor": "^1.0.2" - } - }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "version": "1.48.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", + "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", "dev": true }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.31", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", + "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", "dev": true, "requires": { - "mime-db": "1.43.0" + "mime-db": "1.48.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1056,61 +1112,26 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "moment": { - "version": "2.24.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", - "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -1138,56 +1159,20 @@ "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", "dev": true }, - "ora": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", - "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "cli-cursor": "^1.0.2", - "cli-spinners": "^0.1.2", - "object-assign": "^4.0.1" - }, - "dependencies": { - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "ospath": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz", + "integrity": "sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs=", "dev": true }, "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } }, "path-is-absolute": { "version": "1.0.1", @@ -1195,16 +1180,10 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "pend": { @@ -1231,18 +1210,28 @@ "integrity": "sha1-ZGx3ARiZhwtqCQPnXpl+jlHadGE=", "dev": true }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "pretty-bytes": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", + "integrity": "sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==", "dev": true }, "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -1262,63 +1251,11 @@ "dev": true }, "ramda": { - "version": "0.24.1", - "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", - "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz", + "integrity": "sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw==", "dev": true }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "^1.0.0" - } - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - } - }, "request-progress": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", @@ -1339,27 +1276,27 @@ } }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" } }, "rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", "dev": true, "requires": { - "symbol-observable": "1.0.1" + "tslib": "^1.9.0" } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "safer-buffer": { @@ -1368,38 +1305,48 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + } + } }, "sshpk": { "version": "1.16.1", @@ -1418,30 +1365,32 @@ "tweetnacl": "~0.14.0" } }, - "stream-to-observable": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", - "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", - "dev": true - }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } } }, "strip-ansi": { @@ -1453,60 +1402,58 @@ "ansi-regex": "^2.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" } }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", - "dev": true - }, "throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "tmp": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.1.0.tgz", - "integrity": "sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", "dev": true, "requires": { - "rimraf": "^2.6.3" + "rimraf": "^3.0.0" } }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -1522,28 +1469,28 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true }, "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "untildify": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.3.tgz", - "integrity": "sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz", + "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -1567,12 +1514,6 @@ } } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -1591,14 +1532,51 @@ } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -1613,17 +1591,6 @@ "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" - }, - "dependencies": { - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - } } } } diff --git a/package.json b/package.json index cd30dc386..f824de0cf 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "1.0.0", "description": "Development tooling for emergence-skeleton", "devDependencies": { - "cypress": "^3.8.2", - "cypress-plugin-tab": "^1.0.1" + "cypress": "^7.5.0", + "cypress-plugin-tab": "^1.0.5" }, "scripts": { "cypress:open": "cypress open" diff --git a/script/test b/script/test new file mode 100755 index 000000000..f7fe88644 --- /dev/null +++ b/script/test @@ -0,0 +1,48 @@ +#!/bin/bash + +# script/test: Run all tests + +set -e +cd "$(dirname "$0")/.." + + +temp_path="$(pwd)" +temp_path="${temp_path:1}" +temp_path="${temp_path//\//--}" +temp_path="/tmp/cypress-workspaces/${temp_path}" + + +echo +echo "==> test: setting up temporary workspace diretory…" +if [ -d "${temp_path}" ]; then + echo "removing existing content..." + rm -R "${temp_path}" +fi + +mkdir -pv "${temp_path}" + + +echo +echo "==> test: projecting Cypress workspace…" +workspace_tree="$(git holo project cypress-workspace)" + +if [ -z "${workspace_tree}" ]; then + echo + echo "==> test: failed to project Cypress workspace" + exit 1 +fi + + +echo +echo "==> test: writing Cypress workspace…" +git archive "${workspace_tree}" --format=tar | (cd "${temp_path}" && tar -xf -) + + +echo +echo "==> test: setting up node_modules…" +(cd "${temp_path}" && npm install) + + +echo +echo "==> test: executing \`cypress run\`…" +(cd "${temp_path}" && npx cypress run) diff --git a/script/test-interactive b/script/test-interactive new file mode 100755 index 000000000..192f0b255 --- /dev/null +++ b/script/test-interactive @@ -0,0 +1,83 @@ +#!/bin/bash + +# script/test-interactive: Run all tests interactively with Cypress GUI + +set -e +cd "$(dirname "$0")/.." + + +repo_path="$(pwd)" +temp_path="${repo_path}.cypress-workspace" + + +echo +echo "==> test-interactive: verifying unionfs…" + +if ! [ -x "$(command -v unionfs)" ]; then + echo "Please clone, build, and install the unionfs command:" + echo "git clone https://github.com/rpodgorny/unionfs-fuse" + echo "cd unionfs-fuse" + echo "make" + echo "sudo make install" + exit 1 +fi + + +echo +echo "==> test-interactive: setting up cleanup trap…" +function _cleanup { + echo + echo "cleaning up workspace..." + if [ -d "${temp_path}/merged" ] && mount | grep -q "${temp_path}/merged"; then + sudo umount -f "${temp_path}/merged" + fi + rm -rf "${temp_path}" +} +trap _cleanup EXIT + + +echo +echo "==> test-interactive: setting up temporary workspace diretory…" +if [ -d "${temp_path}" ]; then + _cleanup +fi + +mkdir -pv "${temp_path}/base" +mkdir -pv "${temp_path}/merged" + + +echo +echo "==> test-interactive: projecting Cypress workspace…" +workspace_tree="$(git holo project cypress-workspace)" + +if [ -z "${workspace_tree}" ]; then + echo + echo "==> test-interactive: failed to project Cypress workspace" + exit 1 +fi + + +echo +echo "==> test-interactive: writing Cypress workspace…" +git archive "${workspace_tree}" --format=tar | (cd "${temp_path}/base" && tar -xf -) + + +echo +echo "==> test-interactive: setting up overlay mount…" + +# unionfs was selected for mac+linux compatibility, though under Linux Kernel 4.10+ +# overlayfs might offer the advantage of propogating FS events from upperdir to mergedir +# (see https://github.com/libuv/libuv/issues/1201) +unionfs -o cow \ + "${repo_path}"=RW:"${temp_path}/base"=RO \ + "${temp_path}/merged" + + +echo +echo "==> test-interactive: installing node_modules…" +(cd "${temp_path}/merged" && npm install) + + +echo +echo "==> test-interactive: executing \`cypress open\`…" +(cd "${temp_path}/merged" && npx cypress open) diff --git a/sencha-workspace/EmergenceContentEditor/app.json b/sencha-workspace/EmergenceContentEditor/app.json index e693eee83..2f982d298 100644 --- a/sencha-workspace/EmergenceContentEditor/app.json +++ b/sencha-workspace/EmergenceContentEditor/app.json @@ -18,8 +18,7 @@ "requires": [ "font-awesome", "jarvus-hotfixes", - "emergence-cms", - "emergence-cms-summaries" + "emergence-cms" ], /** diff --git a/sencha-workspace/EmergenceContentEditor/index.html b/sencha-workspace/EmergenceContentEditor/index.html index 60705d10a..750302ba6 100644 --- a/sencha-workspace/EmergenceContentEditor/index.html +++ b/sencha-workspace/EmergenceContentEditor/index.html @@ -4,6 +4,7 @@ + EmergenceContentEditor diff --git a/sencha-workspace/packages/emergence-cms-summaries/Readme.md b/sencha-workspace/packages/emergence-cms-summaries/Readme.md deleted file mode 100644 index 1412662f8..000000000 --- a/sencha-workspace/packages/emergence-cms-summaries/Readme.md +++ /dev/null @@ -1,2 +0,0 @@ -# emergence-cms-summaries - Read Me - diff --git a/sencha-workspace/packages/emergence-cms-summaries/build.xml b/sencha-workspace/packages/emergence-cms-summaries/build.xml deleted file mode 100644 index 8831b72ec..000000000 --- a/sencha-workspace/packages/emergence-cms-summaries/build.xml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - - - diff --git a/sencha-workspace/packages/emergence-cms-summaries/overrides/Editor.js b/sencha-workspace/packages/emergence-cms-summaries/overrides/Editor.js deleted file mode 100644 index 7a00ed0e0..000000000 --- a/sencha-workspace/packages/emergence-cms-summaries/overrides/Editor.js +++ /dev/null @@ -1,28 +0,0 @@ -Ext.define('Emergence.overrides.cmssummaries.Editor', { - override: 'Emergence.cms.view.Editor', - requires: [ - 'Emergence.cmssummaries.field.Summary' - ], - - initComponent: function() { - var editorView = this, - summaryField = Ext.create('Emergence.cmssummaries.field.Summary', { - dock: 'top', - hidden: true - }); - - editorView.on({ - syncfromrecord: function(editorView, contentRecord) { - summaryField.setValue(contentRecord.get('Summary')); - summaryField.setHidden(contentRecord.get('Class') != 'Emergence\\CMS\\BlogPost'); - }, - synctorecord: function(editorView, contentRecord) { - contentRecord.set('Summary', summaryField.getValue()); - } - }); - - editorView.callParent(arguments); - - editorView.addDocked(summaryField); - } -}); \ No newline at end of file diff --git a/sencha-workspace/packages/emergence-cms-summaries/package.json b/sencha-workspace/packages/emergence-cms-summaries/package.json deleted file mode 100644 index a6cce3a9b..000000000 --- a/sencha-workspace/packages/emergence-cms-summaries/package.json +++ /dev/null @@ -1,263 +0,0 @@ -{ - /** - * The name of the package. - */ - "name": "emergence-cms-summaries", - - "sencha": { - /** - * Alternate names for this package. - * - * "alternateName": [], - */ - - /** - * The namespace of this package. - * - * As a general rule, all classes that belong to this package should be under this namespace - * if multiple namespaces are part of this package, set this to "". - */ - "namespace": "Emergence.cmssummaries", - - /** - * The package type. - * - * Sencha Cmd understands the following types of packages: - * - code : An arbitrary package of code for use by applications or other packages. - * - theme : A package to be used as an application’s theme. - * - locale : A package containing localization strings or locale-specific code. - * - template : A package containing one or more templates. - */ - "type": "code", - - /** - * The toolkit used by this theme (only for "theme" package type). - * - * Themes can specify the toolkit they apply to ("classic" or "modern"). - * - * "toolkit": "classic", - */ - "toolkit": "classic", - - /** - * The author of the package. - * - * Required only if you are distributing this package through a Sencha Cmd repository, - * in which case it should match the name you assign to your local package repository. - */ - "creator": "anonymous", - - /** - * A summarized description of this package. - */ - "summary": "Short summary", - - /** - * A detailed description of this package. - */ - "detailedDescription": "Long description of package", - - /** - * The package version. - * - * Typically, changes to the package should come along with changes to the version. - * This number should be in this format: d+(.d+)* - */ - "version": "1.0.0", - - /** - * The version that users can transparently update from without requiring code changes. - * - * In addition the version property, packages can also indicate the degree to which - * they are backward compatible using the compatVersion property. - */ - "compatVersion": "1.0.0", - - /** - * Spec. version of this package.json file. - * This is set automatically by Sencha Cmd when first generating this file - */ - "format": "1", - - /** - * Additional resources used during theme slicing operations - */ - "slicer": null, - - /** - * Controls the output directory. - */ - "output": "${package.dir}/build", - - /** - * Indicates whether this is a locally developed package or downloaded form a repository. - * Defaults to true on newly generated packages, should not be changed. - */ - "local": true, - - /** - * The theme (package) this package will use (e.g., "ext-theme-neptune", etc.). - * This is only needed if the built package will be used by a non-Cmd application. - * - * "theme": "ext-theme-classic", - */ - - /** - * Sass configuration properties. - */ - "sass" : { - /** - * The namespace to which this package's SASS corresponds. The default value of - * "Emergence.cmssummaries" means that the files in ./sass/src (and ./sass/var) match classes in - * the Emergence.cmssummaries" root namespace. In other words, "Emergence.cmssummaries.panel.Panel" maps to - * ./sass/src/panel/Panel.scss. - * - * To style classes from any namespace, set this to blank. If this is blank, - * then to style "Emergence.cmssummaries.panel.Panel" you would put SASS in - * ./sass/src/Emergence.cmssummaries/panel/Panel.scss. - */ - "namespace": "Emergence.cmssummaries", - - /** - * Comma-separated list of files or folders containing extra Sass. These - * files are automatically included in the Sass compilation. By default this - * is just "etc/all.scss" to allow import directives to control the order - * other files are included. - * - * All "etc" files are included at the top of the Sass compilation in their - * dependency order: - * - * +-------+---------+ - * | | base | - * | theme +---------+ - * | | derived | - * +-------+---------+ - * | packages | (in package dependency order) - * +-----------------+ - * | application | - * +-----------------+ - */ - "etc": [ - "${package.dir}/sass/etc/all.scss" - ], - - /** - * Comma-separated list of folders containing Sass variable definitions - * files. These file can also define Sass mixins for use by components. - * - * All "var" files are included after "etc" files in the Sass compilation in - * dependency order: - * - * +-------+---------+ - * | | base | - * | theme +---------+ - * | | derived | - * +-------+---------+ - * | packages | (in package dependency order) - * +-----------------+ - * | application | - * +-----------------+ - * - * The "sass/var/all.scss" file is always included at the start of the var - * block before any files associated with JavaScript classes. - */ - "var": [ - "${package.dir}/sass/var" - ], - - /** - * Comma-separated list of folders containing Sass rule files. - * - * All "src" files are included after "var" files in the Sass compilation in - * dependency order (the same order as "etc"): - * - * +-------+---------+ - * | | base | - * | theme +---------+ - * | | derived | - * +-------+---------+ - * | packages | (in package dependency order) - * +-----------------+ - * | application | - * +-----------------+ - */ - "src": [ - "${package.dir}/sass/src" - ] - }, - - /** - * This is the comma-separated list of folders where classes reside. These - * classes must be explicitly required to be included in the build. - */ - "classpath": [ - "${package.dir}/src" - ], - - /** - * Comma-separated string with the paths of directories or files to search. Any classes - * declared in these locations will be automatically required and included in the build. - * If any file defines an Ext JS override (using Ext.define with an "override" property), - * that override will in fact only be included in the build if the target class specified - * in the "override" property is also included. - */ - "overrides": [ - "${package.dir}/overrides" - ], - - "example": { - /** - * One or more folders that contain example applications for this package. - */ - "path": [ - "${package.dir}/examples" - ] - - /** - * You can list apps specifically. - * - * "apps": [ - * "demo1", - * "demo2" - * ] - * - * By default, all subfolders in the path are considered example applications. - */ - }, - - /** - * The framework this package will use (i.e., "ext" or "touch"). - * This is only needed if the built package will be used by a non-Cmd application. - * - * "framework": "ext", - */ - "framework": "ext", - - /** - * Packages can require other packages in the same way that applications can require - * packages. - * - * Can be specified as an array of package names or configuration objects. - * - * "requires": [ - * "foo", - * "bar@1.1-2.0", - * { - * "name": "baz" - * "version": "1.5" - * } - * ] - * - * Can also be specified as an object: - * - * "requires": { - * "foo": "2.2", - * "bar": { - * "minVersion": "1.1", - * "version": "2.0" - * } - * } - */ - "requires": [] - } -} diff --git a/sencha-workspace/packages/emergence-cms-summaries/src/field/Summary.js b/sencha-workspace/packages/emergence-cms-summaries/src/field/Summary.js deleted file mode 100644 index 2ab0aa991..000000000 --- a/sencha-workspace/packages/emergence-cms-summaries/src/field/Summary.js +++ /dev/null @@ -1,7 +0,0 @@ -Ext.define('Emergence.cmssummaries.field.Summary', { - extend: 'Ext.form.field.TextArea', - xtype: 'emergence-cmssummaries-field', - - emptyText: 'Post summary', - grow: true -}); \ No newline at end of file diff --git a/sencha-workspace/packages/emergence-cms/src/view/DualViewController.js b/sencha-workspace/packages/emergence-cms/src/view/DualViewController.js index a8df41937..773222a57 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/DualViewController.js +++ b/sencha-workspace/packages/emergence-cms/src/view/DualViewController.js @@ -15,10 +15,10 @@ Ext.define('Emergence.cms.view.DualViewController', { 'emergence-cms-editor field[reference=tagsField]': { change: 'onTagsChange' }, - 'emergence-cms-editor button[reference=publishedTimeBtn] menucheckitem': { + 'emergence-cms-editor menucheckitem#publishOnSaveCheck': { checkchange: 'onPublishTimeChange' }, - 'emergence-cms-editor button[reference=publishedTimeBtn] field': { + 'emergence-cms-editor #publishTimeCt field': { change: 'onPublishTimeChange' }, 'emergence-cms-editor dashboard-column': { @@ -92,9 +92,9 @@ Ext.define('Emergence.cms.view.DualViewController', { onPublishTimeChange: Ext.Function.createBuffered(function() { var editorView = this.lookupReference('editor'), previewCmp = this.lookupReference('preview'), - date = editorView.lookupReference('publishedTimeBtn').down('menucheckitem').checked ? new Date() : editorView.getSelectedDateTime(); + date = editorView.down('menucheckitem#publishOnSaveCheck').checked ? new Date() : editorView.getSelectedDateTime(); - previewCmp.timeEl.set({ datetime: Ext.Date.format(date, 'c') }).update(Ext.Date.format(date, 'l, F n, Y \\a\\t g:i a')); + previewCmp.timeEl.set({ datetime: Ext.Date.format(date, 'c') }).update(Ext.Date.format(date, 'l, F j, Y \\a\\t g:i a')); previewCmp.timeWrapper.show(); previewCmp.infoWrapper.show(); }, 50), diff --git a/sencha-workspace/packages/emergence-cms/src/view/Editor.js b/sencha-workspace/packages/emergence-cms/src/view/Editor.js index 9374e0f4f..26229ccd5 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/Editor.js +++ b/sencha-workspace/packages/emergence-cms/src/view/Editor.js @@ -25,7 +25,8 @@ Ext.define('Emergence.cms.view.Editor', { config: { contentRecord: null, - composers: ['html', 'markdown', 'multimedia', 'embed'] + composers: ['html', 'markdown', 'multimedia', 'embed'], + includeSummary: false, }, columnWidths: [1], @@ -39,23 +40,6 @@ Ext.define('Emergence.cms.view.Editor', { header: { xtype: 'toolbar', padding: '4 7', - items: [ - '->', - { - cls: 'save-btn', - text: 'Save', - glyph: 0xf0ee+'@FontAwesome', // fa-cloud-upload - action: 'save' - } - ] - }, - - dockedItems: [{ - dock: 'top', - - xtype: 'toolbar', - border: '1 0 0', - padding: '8 0 4 8', items: [ { reference: 'titleField', @@ -66,9 +50,22 @@ Ext.define('Emergence.cms.view.Editor', { selectOnFocus: true, emptyText: 'Title', hideLabel: true + }, + { + xtype: 'tbspacer', + width: 7, + }, + { + cls: 'save-btn', + text: 'Save', + glyph: 0xf0ee + '@FontAwesome', // fa-cloud-upload + scale: 'large', + action: 'save' } ] - }, { + }, + + dockedItems: [{ dock: 'top', xtype: 'toolbar', @@ -121,7 +118,24 @@ Ext.define('Emergence.cms.view.Editor', { border: false, layout: { overflowHandler: 'menu' - } + }, + }, { + reference: 'summaryFieldCt', + dock: 'top', + hidden: !this.includeSummary, + + xtype: 'toolbar', + border: false, + padding: '0 0 0 8', + items: [ + { + reference: 'summaryField', + flex: 1, + xtype: 'textarea', + emptyText: 'Summarize your post here. This summary may appear in blog feeds, with a link to the full contents.', + grow: true, + }, + ], }, { reference: 'inserterCt', @@ -145,9 +159,9 @@ Ext.define('Emergence.cms.view.Editor', { }], getSelectedDateTime: function() { - var publishedTimeBtn = this.lookupReference('publishedTimeBtn'), - date = publishedTimeBtn.down('datefield').getValue() || new Date(), - time = publishedTimeBtn.down('timefield').getValue() || new Date(); + var publishedTimeCt = this.down('#publishTimeCt'), + date = publishedTimeCt.down('datefield').getValue() || new Date(), + time = publishedTimeCt.down('timefield').getValue() || new Date(); date.setHours(time.getHours()); date.setMinutes(time.getMinutes()); @@ -191,7 +205,57 @@ Ext.define('Emergence.cms.view.Editor', { } return composers; - } + }, + + updateIncludeSummary: function (includeSummary, includeSummaryOld) { + var me = this, + fieldCt = me.lookup('summaryFieldCt'), + field = me.lookup('summaryField'), + toggleBtn = me.lookup('summaryToggleBtn'), + _removeSummary = function () { + fieldCt.setVisible(false); // hide field + field.setValue(); // clear it + }; + + if (field) { + if (includeSummary) { + fieldCt.setVisible(true); + field.focus(); + } else { + // before removing summary, confirm deleting the field contents + if (field.getValue().trim().length > 0) { + Ext.Msg.show({ + title: 'Delete post summary', + message: 'Removing the summary will delete any text you have written there.', + icon: Ext.Msg.WARNING, + buttons: [ + Ext.Msg.YES, + Ext.Msg.NO, + ], + buttonText: { + // yes and no reversed so that "Keep it" will be the default + no: 'Delete and remove', + yes: 'Keep it', + }, + fn: function (btn) { + if (btn === 'no') { + _removeSummary(); + } else if (btn === 'yes') { + // if we want to keep the summary, then toggle it back on + if (toggleBtn.toggle) { + toggleBtn.toggle(true); + } else if (toggleBtn.setChecked) { + toggleBtn.setChecked(true); // if it's in an overflow menu + } + } + } + }); + } else { + _removeSummary(); + } + } + } + }, // onComposerDrop: function(dropEvent) { // var composer = dropEvent.panel; // @@ -203,4 +267,4 @@ Ext.define('Emergence.cms.view.Editor', { // } // }); // }, -}); \ No newline at end of file +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/EditorController.js b/sencha-workspace/packages/emergence-cms/src/view/EditorController.js index 55b77e768..735dbf8c9 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/EditorController.js +++ b/sencha-workspace/packages/emergence-cms/src/view/EditorController.js @@ -19,10 +19,13 @@ Ext.define('Emergence.cms.view.EditorController', { 'button[reference=statusBtn] menucheckitem, button[reference=visibilityBtn] menucheckitem': { checkchange: 'onEnumMenuCheckChange' }, - 'button[reference=publishedTimeBtn] menucheckitem': { + 'button[reference=summaryToggleBtn]': { + toggle: 'onSummaryToggle', + }, + 'menucheckitem#publishOnSaveCheck': { checkchange: 'onPublishImmediatelyCheckChange' }, - 'button[reference=publishedTimeBtn] field': { + '#publishTimeCt field': { change: 'onPublishTimeFieldChange' } }, @@ -67,37 +70,54 @@ Ext.define('Emergence.cms.view.EditorController', { var me = this, editorView = me.getView(), contentRecord = editorView.getContentRecord(), + composersColumn = editorView.items.getAt(0), + composersIndex, + composersToRemove = [], + composersToRemoveIndex, wasPhantom = contentRecord.phantom; editorView.setLoading('Saving…'); - me.syncToRecord(); - contentRecord.save({ - callback: function(record, operation, success) { - var contentItemsData = contentRecord.get('items'); - - if (success && wasPhantom) { - editorView.setLoading('Opening new post…'); - location.href = contentRecord.getProxy().getConnection().buildUrl(contentRecord.toUrl() + '/edit'); - } else { - editorView.setLoading(false); + if (composersColumn && composersColumn.items && composersColumn.items.length > 0) { + // remove empty markdown composers + // (other composer types are allowed to remain empty) + for (composersIndex = 0; composersIndex < composersColumn.items.length; composersIndex++) { + var composer = composersColumn.items.getAt(composersIndex); + if (composer.$className === 'Emergence.cms.view.composer.Markdown' && composer.isEmpty()) { + composersToRemove.push(composer.id); + } + } - // write server-returned content item data to each composer - editorView.items.getAt(0).items.each(function(composer, composerIndex) { - composer.setContentItem(contentItemsData[composerIndex]); - }); + for (composersToRemoveIndex = 0; composersToRemoveIndex < composersToRemove.length; composersToRemoveIndex++) { + composersColumn.remove(composersToRemove[composersToRemoveIndex]); + } + } - if (!success) { - Ext.Msg.show({ - title: 'Failed to save blog post', - message: operation.getError() || 'Please backup your work to another application and report this to your technical support contact', - buttons: Ext.Msg.OK, - icon: Ext.Msg.ERROR - }); + // if no composers, warn the user + if (!composersColumn || !composersColumn.items || composersColumn.items.length < 1) { + Ext.Msg.show({ + title: 'Empty blog post', + message: 'Your post appears to be empty. Are you sure you want to save it?', + icon: Ext.Msg.QUESTION, + buttons: [ + Ext.Msg.YES, + Ext.Msg.NO, + ], + buttonText: { + yes: 'Save empty post', + no: 'Don’t save', + }, + fn: function (btn) { + if (btn === 'yes') { + me.savePost(); + } else { + editorView.setLoading(false); } } - } - }); + }); + } else { + me.savePost(); + } }, onEnumMenuCheckChange: function(menuItem, checked) { @@ -111,11 +131,15 @@ Ext.define('Emergence.cms.view.EditorController', { parentButton.setGlyph(menuItem.glyph); }, + onSummaryToggle: function (toggleBtn, pressed) { + this.getView().setIncludeSummary(pressed); + }, + onPublishImmediatelyCheckChange: function(menuItem, checked) { - var publishedTimeBtn = this.lookupReference('publishedTimeBtn'); + var publishedTimeCt = this.getView().down('#publishTimeCt'); - publishedTimeBtn.down('datefield').setDisabled(checked); - publishedTimeBtn.down('timefield').setDisabled(checked); + publishedTimeCt.down('datefield').setDisabled(checked); + publishedTimeCt.down('timefield').setDisabled(checked); this.syncPublishedTimeBtnText(); }, @@ -127,8 +151,8 @@ Ext.define('Emergence.cms.view.EditorController', { // protected methods syncPublishedTimeBtnText: function() { - var publishedTimeBtn = this.lookupReference('publishedTimeBtn'), - immediateChecked = publishedTimeBtn.down('menucheckitem').checked, + var editorView = this.getView(), + immediateChecked = editorView.down('#publishOnSaveCheck').checked, date, text; if (immediateChecked) { @@ -138,7 +162,7 @@ Ext.define('Emergence.cms.view.EditorController', { text = /* (date > new Date() ? 'Publish ' : 'Published ') + */ Ext.Date.format(date, 'n/j/Y g:i a'); } - publishedTimeBtn.setText(text); + editorView.down('#publishTimeBtn').setText(text); }, syncFromRecord: function() { @@ -153,14 +177,18 @@ Ext.define('Emergence.cms.view.EditorController', { composersLength = composers.length, composersIndex, composer, composerItemClass, composersColumn = editorView.items.getAt(0), // openBtn = me.lookupReference('openBtn'), - publishedTimeBtn = me.lookupReference('publishedTimeBtn'), + publishedTimeCt = editorView.down('#publishTimeCt'), + summary = contentRecord.get('Summary'), + summaryHasLength = summary ? summary.length > 0 : false, + summaryField = me.lookupReference('summaryField'), + summaryToggle = me.lookupReference('summaryToggleBtn'), tagsField = me.lookupReference('tagsField'), tagsStore = tagsField.getStore(), tagsData = Ext.Array.map(contentRecord.get('tags') || [], function(tag) { return parseInt(tag.ID, 10); }); - Ext.batchLayouts(function() { + Ext.batchLayouts(function () { // sync title me.lookupReference('titleField').setValue(contentRecord.get('Title')); @@ -168,19 +196,24 @@ Ext.define('Emergence.cms.view.EditorController', { if (tagsStore.isLoaded()) { tagsField.setValue(tagsData); } else { - tagsStore.on('load', function() { + tagsStore.on('load', function () { tagsField.setValue(tagsData); }, me, { single: true }); } // sync status/visibility fields - me.lookupReference('statusBtn').down('[value="'+contentRecord.get('Status')+'"]').setChecked(true); - me.lookupReference('visibilityBtn').down('[value="'+contentRecord.get('Visibility')+'"]').setChecked(true); + me.lookupReference('statusBtn').down('[value="' + contentRecord.get('Status') + '"]').setChecked(true); + me.lookupReference('visibilityBtn').down('[value="' + contentRecord.get('Visibility') + '"]').setChecked(true); + + // sync post summary + summaryField.setValue(summary); + summaryToggle.toggle(summaryHasLength); + me.getView().setIncludeSummary(summaryHasLength); // sync publish time fields - publishedTimeBtn.down('menucheckitem').setChecked(isPhantom); - publishedTimeBtn.down('datefield').setValue(isPhantom ? new Date() : publishedTime); - publishedTimeBtn.down('timefield').setValue(isPhantom ? new Date() : publishedTime); + publishedTimeCt.down('timefield').setValue(isPhantom ? new Date() : Ext.Date.clone(publishedTime)); + publishedTimeCt.down('datefield').setValue(isPhantom ? new Date() : Ext.Date.clone(publishedTime)); + editorView.down('#publishOnSaveCheck').setChecked(isPhantom); // remove any existing composers from the column if its been initialized already if (composersColumn) { @@ -215,6 +248,11 @@ Ext.define('Emergence.cms.view.EditorController', { })); } + // add a default composer if no records + if (contentItemsLength === 0) { + editorView.addView(Ext.create('Emergence.cms.view.composer.Markdown')); + } + me.fireViewEvent('syncfromrecord', editorView, contentRecord); }); }, @@ -223,9 +261,12 @@ Ext.define('Emergence.cms.view.EditorController', { var me = this, editorView = me.getView(), composersColumn = editorView.items.getAt(0), - contentRecord = editorView.getContentRecord(), + summaryField = me.lookupReference('summaryField'), itemsData = [], - order = 1; + order = 1, contentRecord; + + + contentRecord = editorView.getContentRecord(); // update title contentRecord.set('Title', me.lookupReference('titleField').getValue()); @@ -235,13 +276,16 @@ Ext.define('Emergence.cms.view.EditorController', { contentRecord.set('Visibility', me.lookupReference('visibilityBtn').down('[checked]').value); // update published-on timestamp - contentRecord.set('Published', me.lookupReference('publishedTimeBtn').down('menucheckitem').checked ? new Date() : editorView.getSelectedDateTime()); + contentRecord.set('Published', editorView.down('menucheckitem#publishOnSaveCheck').checked ? new Date() : editorView.getSelectedDateTime()); // update tags list contentRecord.set('tags', Ext.Array.map(me.lookupReference('tagsField').getValueRecords(), function(tag) { return tag.get('ID') || tag.get('Title'); })); + // update summary + contentRecord.set('Summary', summaryField.getValue()); + // update items list if (composersColumn) { composersColumn.items.each(function(composer) { @@ -255,5 +299,44 @@ Ext.define('Emergence.cms.view.EditorController', { contentRecord.set('items', itemsData); me.fireViewEvent('synctorecord', editorView, contentRecord); - } -}); \ No newline at end of file + }, + + savePost() { + var me = this, + editorView = me.getView(), + contentRecord = editorView.getContentRecord(), + composersColumn = editorView.items.getAt(0), + wasPhantom = contentRecord.phantom; + + me.syncToRecord(); + + contentRecord.save({ + callback: function (record, operation, success) { + var contentItemsData = contentRecord.get('items'); + + if (success && wasPhantom) { + editorView.setLoading('Opening new post…'); + location.href = contentRecord.getProxy().getConnection().buildUrl(contentRecord.toUrl() + '/edit'); + } else { + editorView.setLoading(false); + + if (composersColumn && composersColumn.items) { + // write server-returned content item data to each composer + composersColumn.items.each(function (composer, composerIndex) { + composer.setContentItem(contentItemsData[composerIndex]); + }); + } + + if (!success) { + Ext.Msg.show({ + title: 'Failed to save blog post', + message: operation.getError() || 'Please backup your work to another application and report this to your technical support contact', + buttons: Ext.Msg.OK, + icon: Ext.Msg.ERROR + }); + } + } + } + }); + }, +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/Toolbar.js b/sencha-workspace/packages/emergence-cms/src/view/Toolbar.js index 5628214be..b6220ec33 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/Toolbar.js +++ b/sencha-workspace/packages/emergence-cms/src/view/Toolbar.js @@ -58,7 +58,7 @@ Ext.define('Emergence.cms.view.Toolbar', { group: 'visibility', text: 'Login required', value: 'Private', - glyph: 0xf0c0+'@FontAwesome', // fa-group + glyph: 0xf023+'@FontAwesome', // fa-lock tooltip: 'Only users logged into the site can find or view this content' }, { @@ -72,10 +72,17 @@ Ext.define('Emergence.cms.view.Toolbar', { ] } }, - '->', { - reference: 'publishedTimeBtn', + reference: 'summaryToggleBtn', + xtype: 'button', + text: 'Summary', + glyph: 0xf10d + '@FontAwesome', // fa-quote-left + enableToggle: true, + }, + '->', + { + itemId: 'publishTimeBtn', xtype: 'button', text: 'Publication time', glyph: 0xf017+'@FontAwesome', // fa-clock-o @@ -85,11 +92,13 @@ Ext.define('Emergence.cms.view.Toolbar', { items: [ '', { + itemId: 'publishOnSaveCheck', xtype: 'menucheckitem', text: 'Publish on save' }, '-', { + itemId: 'publishTimeCt', xtype: 'fieldcontainer', layout: 'anchor', defaults: { anchor: '100%' }, @@ -105,4 +114,4 @@ Ext.define('Emergence.cms.view.Toolbar', { } } ] -}); \ No newline at end of file +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Abstract.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Abstract.js index 8b7c44f98..9e05111bc 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Abstract.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Abstract.js @@ -51,6 +51,10 @@ Ext.define('Emergence.cms.view.composer.Abstract', { return data; }, + isEmpty: function () { + return Ext.isEmpty(this.getItemData().Data); + }, + firePreviewChange: function(html) { var me = this; @@ -100,4 +104,4 @@ Ext.define('Emergence.cms.view.composer.Abstract', { // me.fireEvent('dragstart', me); // }); // } -}); \ No newline at end of file +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Embed.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Embed.js index 4da804e24..44939e735 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Embed.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Embed.js @@ -42,5 +42,13 @@ Ext.define('Emergence.cms.view.composer.Embed', { return Ext.applyIf({ Data: this.textarea.getValue() }, this.callParent()); - } -}); \ No newline at end of file + }, + + isEmpty: function () { + if (this.textarea) { + return Ext.isEmpty(this.textarea.getValue().trim()); + } else { + return false; + } + }, +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Html.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Html.js index f440de23c..e4c31aa90 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Html.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Html.js @@ -58,7 +58,16 @@ Ext.define('Emergence.cms.view.composer.Html', { return Ext.applyIf({ Data: this.down('htmleditor').getValue() }, this.callParent()); - } + }, + + isEmpty: function () { + var editor = this.down('htmleditor'); + if (editor) { + return Ext.isEmpty(editor.getValue().trim()); + } else { + return false; + } + }, // repairEditor: function() { // var me = this, @@ -78,4 +87,4 @@ Ext.define('Emergence.cms.view.composer.Html', { // backupEditor: function() { // this.backupValue = this.down('htmleditor').getValue(); // }, -}); \ No newline at end of file +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Markdown.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Markdown.js index b5b81c53d..e5b20d2b2 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Markdown.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Markdown.js @@ -28,7 +28,8 @@ Ext.define('Emergence.cms.view.composer.Markdown', { }], items: { - xtype: 'textarea' + xtype: 'textarea', + emptyText: 'Type your post here, using Markdown for formatting.', // grow: true // temporarily disabled due to ExtJS bug that causes the page to scroll to top on grow }, @@ -64,5 +65,13 @@ Ext.define('Emergence.cms.view.composer.Markdown', { return Ext.applyIf({ Data: this.textarea.getValue() }, this.callParent()); - } -}); \ No newline at end of file + }, + + isEmpty: function () { + if (this.textarea) { + return Ext.isEmpty(this.textarea.getValue().trim()); + } else { + return false; + } + }, +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Multimedia.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Multimedia.js index 8c820b1d3..fc5c9cc6f 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Multimedia.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Multimedia.js @@ -87,6 +87,10 @@ Ext.define('Emergence.cms.view.composer.Multimedia', { }, me.callParent()); }, + isEmpty: function () { + return Ext.isEmpty(this.getMedia()) && Ext.isEmpty(this.captionField.getValue().trim()); + }, + // config handlers updateMedia: function(media) { @@ -136,4 +140,4 @@ Ext.define('Emergence.cms.view.composer.Multimedia', { } }); } -}); \ No newline at end of file +}); diff --git a/sencha-workspace/packages/emergence-cms/src/view/composer/Unknown.js b/sencha-workspace/packages/emergence-cms/src/view/composer/Unknown.js index b6ee55d3e..951d80d90 100644 --- a/sencha-workspace/packages/emergence-cms/src/view/composer/Unknown.js +++ b/sencha-workspace/packages/emergence-cms/src/view/composer/Unknown.js @@ -17,5 +17,9 @@ Ext.define('Emergence.cms.view.composer.Unknown', { me.update(me.contentItem); me.callParent(); + }, + + isEmpty: function() { + return false; // we cannot know for sure } -}); \ No newline at end of file +}); diff --git a/site-root/img/logo.png b/site-root/img/logo.png new file mode 100644 index 000000000..0256fbcfa Binary files /dev/null and b/site-root/img/logo.png differ diff --git a/site-root/sass/skeleton/_normalize.scss b/site-root/sass/skeleton/_normalize.scss index 28c4cd6f7..8d24b816a 100644 --- a/site-root/sass/skeleton/_normalize.scss +++ b/site-root/sass/skeleton/_normalize.scss @@ -74,7 +74,16 @@ body { font-size: 75%; color: #222; background: #fff; - font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; + font-family: -apple-system, + BlinkMacSystemFont, + "Segoe UI", + Roboto, + Helvetica, + Arial, + sans-serif, + "Apple Color Emoji", + "Segoe UI Emoji", + "Segoe UI Symbol"; } @@ -100,9 +109,9 @@ h4 img, h5 img, h6 img { -------------------------------------------------------------- */ p { margin: 0 0 1.5em; } -/* - These can be used to pull an image at the start of a paragraph, so - that the text flows around it (usage:

Text

) +/* + These can be used to pull an image at the start of a paragraph, so + that the text flows around it (usage:

Text

) */ .left { float: left !important; } p .left { margin: 1.5em 1.5em 1.5em 0; padding: 0; } @@ -145,22 +154,22 @@ dd { margin-left: 1.5em;} /* Tables -------------------------------------------------------------- */ -/* - Because of the need for padding on TH and TD, the vertical rhythm - on table cells has to be 27px, instead of the standard 18px or 36px - of other elements. - */ +/* + Because of the need for padding on TH and TD, the vertical rhythm + on table cells has to be 27px, instead of the standard 18px or 36px + of other elements. + */ table { margin-bottom: 1.4em; width:100%; } th { font-weight: bold; } thead th { background: #c3d9ff; } th,td,caption { padding: 4px 10px 4px 5px; } /* - You can zebra-stripe your tables in outdated browsers by adding - the class "even" to every other table row. + You can zebra-stripe your tables in outdated browsers by adding + the class "even" to every other table row. */ -tbody tr:nth-child(even) td, -tbody tr.even td { - background: #e5ecf9; +tbody tr:nth-child(even) td, +tbody tr.even td { + background: #e5ecf9; } tfoot { font-style: italic; } caption { background: #eee; } @@ -352,4 +361,4 @@ a:hover { color: #036; } @page { margin: 0.5cm; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3{ page-break-after: avoid; } -} \ No newline at end of file +}