diff --git a/.editorconfig b/.editorconfig index a541e47e767bca..2f3fbe64be9f7d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -19,3 +19,10 @@ indent_size = 2 [*.md] trim_trailing_whitespace = false + +[*.{gradle,java,kt}] +indent_style = space + +[packages/react-native-*/**.xml] +indent_style = space + diff --git a/.eslintignore b/.eslintignore index 08e37e82948a34..2577b07cec12e8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,6 +4,7 @@ build-module node_modules packages/block-serialization-spec-parser/parser.js packages/e2e-tests/plugins +packages/react-native-editor/bundle playground/dist vendor wordpress diff --git a/.github/workflows/rnmobile-android-runner.yml b/.github/workflows/rnmobile-android-runner.yml new file mode 100644 index 00000000000000..622bde9edfec64 --- /dev/null +++ b/.github/workflows/rnmobile-android-runner.yml @@ -0,0 +1,42 @@ +name: React Native E2E Tests (Android) +on: push + +jobs: + test: + runs-on: macos-latest + strategy: + matrix: + native-test-name: [ + gutenberg-editor-gallery + ] + + steps: + - name: checkout + uses: actions/checkout@v2 + + - name: Restore npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + - run: npm ci + + - name: Restore Gradle cache + uses: actions/cache@v2 + with: + path: ~/.gradle/caches + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }} + restore-keys: ${{ runner.os }}-gradle + + - uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 28 + profile: pixel_xl + script: npm run native test:e2e:android:local ${{ matrix.native-test-name }} + + - uses: actions/upload-artifact@v2 + if: always() + with: + name: android-screen-recordings + path: packages/react-native-editor/android-screen-recordings diff --git a/.github/workflows/rnmobile-ios-runner.yml b/.github/workflows/rnmobile-ios-runner.yml new file mode 100644 index 00000000000000..111ea0090bc639 --- /dev/null +++ b/.github/workflows/rnmobile-ios-runner.yml @@ -0,0 +1,67 @@ +name: React Native E2E Tests (iOS) +on: push + +jobs: + test: + runs-on: macos-latest + strategy: + matrix: + native-test-name: [ + gutenberg-editor-gallery + ] + + steps: + - uses: actions/checkout@v2 + + - name: Restore npm cache + uses: actions/cache@v2 + with: + path: ~/.npm + key: ${{ runner.os }}-npm-${{ hashFiles('package-lock.json') }} + + - run: npm ci + + - name: Prepare build cache key + run: find package-lock.json packages/react-native-editor/ios packages/react-native-aztec/ios packages/react-native-bridge/ios -type f -print0 | sort -z | xargs -0 shasum | tee ios-checksums.txt + + - name: Restore build cache + uses: actions/cache@v2 + with: + path: packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app + key: ${{ runner.os }}-ios-build-${{ hashFiles('ios-checksums.txt') }} + + - name: Restore pods cache + uses: actions/cache@v2 + with: + path: | + packages/react-native-editor/ios/Pods + ~/Library/Caches/CocoaPods + ~/.cocoapods/repos/trunk + packages/react-native-editor/ios/vendor + key: ${{ runner.os }}-pods-${{ hashFiles('packages/react-native-editor/ios/Gemfile.lock') }}-${{ hashFiles('packages/react-native-editor/ios/Podfile.lock') }}-${{ hashFiles('package-lock.json') }} + restore-keys: | + ${{ runner.os }}-pods-${{ hashFiles('packages/react-native-editor/ios/Gemfile.lock') }}-${{ hashFiles('packages/react-native-editor/ios/Podfile.lock') }}-${{ hashFiles('package-lock.json') }} + ${{ runner.os }}-pods-${{ hashFiles('packages/react-native-editor/ios/Gemfile.lock') }}-${{ hashFiles('packages/react-native-editor/ios/Podfile.lock') }}- + ${{ runner.os }}-pods-${{ hashFiles('packages/react-native-editor/ios/Gemfile.lock') }}- + ${{ runner.os }}-pods- + + - name: Bundle iOS + run: npm run native test:e2e:bundle:ios + + - name: Switch Xcode Version + run: sudo xcode-select --switch /Applications/Xcode_11.4.1.app + + - name: Build (if needed) + run: test -e packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app/GutenbergDemo || SKIP_BUNDLING=true npm run native test:e2e:build-app:ios + + - name: Run iOS Device Tests + run: TEST_RN_PLATFORM=ios npm run native device-tests:local ${{ matrix.native-test-name }} + + - name: Prepare build cache + run: rm packages/react-native-editor/ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app/main.jsbundle + + - uses: actions/upload-artifact@v2 + if: always() + with: + name: ios-screen-recordings + path: packages/react-native-editor/ios-screen-recordings diff --git a/docs/manifest.json b/docs/manifest.json index 13b8969f97186f..4d9e0ebdd9e716 100644 --- a/docs/manifest.json +++ b/docs/manifest.json @@ -1601,6 +1601,24 @@ "markdown_source": "../packages/project-management-automation/README.md", "parent": "packages" }, + { + "title": "@wordpress/react-native-aztec", + "slug": "packages-react-native-aztec", + "markdown_source": "../packages/react-native-aztec/README.md", + "parent": "packages" + }, + { + "title": "@wordpress/react-native-bridge", + "slug": "packages-react-native-bridge", + "markdown_source": "../packages/react-native-bridge/README.md", + "parent": "packages" + }, + { + "title": "@wordpress/react-native-editor", + "slug": "packages-react-native-editor", + "markdown_source": "../packages/react-native-editor/README.md", + "parent": "packages" + }, { "title": "@wordpress/redux-routine", "slug": "packages-redux-routine", diff --git a/package-lock.json b/package-lock.json index 4b2c9f31120268..72e168e57c4b4f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,7 +126,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz", "integrity": "sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==", - "dev": true, "requires": { "@babel/types": "^7.8.3" } @@ -135,7 +134,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz", "integrity": "sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw==", - "dev": true, "requires": { "@babel/helper-explode-assignable-expression": "^7.8.3", "@babel/types": "^7.8.3" @@ -145,7 +143,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.9.0.tgz", "integrity": "sha512-weiIo4gaoGgnhff54GQ3P5wsUQmnSwpkvU0r6ZHq6TzoSzKy4JxHEgnxNytaKbov2a9z/CVNyzliuCOUPEX3Jw==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/types": "^7.9.0" @@ -155,7 +152,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.9.0.tgz", "integrity": "sha512-3xJEiyuYU4Q/Ar9BsHisgdxZsRlsShMe90URZ0e6przL26CCs8NJbDoxH94kKT17PcxlMhsCAwZd90evCo26VQ==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-module-imports": "^7.8.3", @@ -191,7 +187,6 @@ "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz", "integrity": "sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.8.3", "@babel/helper-member-expression-to-functions": "^7.8.3", @@ -205,7 +200,6 @@ "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz", "integrity": "sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-regex": "^7.8.3", @@ -216,7 +210,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz", "integrity": "sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.8.3", "@babel/types": "^7.8.3", @@ -227,7 +220,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", "integrity": "sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw==", - "dev": true, "requires": { "@babel/traverse": "^7.8.3", "@babel/types": "^7.8.3" @@ -307,7 +299,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.8.3.tgz", "integrity": "sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ==", - "dev": true, "requires": { "lodash": "^4.17.13" } @@ -316,7 +307,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz", "integrity": "sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-wrap-function": "^7.8.3", @@ -362,7 +352,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz", "integrity": "sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.8.3", "@babel/template": "^7.8.3", @@ -411,7 +400,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.8.3.tgz", "integrity": "sha512-mx0WXDDiIl5DwzMtzWGRSPugXi9BxROS05GQrhLNbEamhBiicgn994ibwkyiBH+6png7bm/yA7AUsvHyCXi4Vw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -431,7 +419,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -451,7 +438,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.8.3.tgz", "integrity": "sha512-PYtv2S2OdCdp7GSPDg5ndGZFm9DmWFvuLoS5nBxZCgOBggluLnhTScspJxng96alHQzPyrrHxvC9/w4bFuspeA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-export-default-from": "^7.8.3" @@ -471,7 +457,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" @@ -491,7 +476,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz", "integrity": "sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.0" @@ -501,7 +485,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" @@ -511,7 +494,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz", "integrity": "sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.0" @@ -531,7 +513,6 @@ "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -540,7 +521,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -549,7 +529,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -558,7 +537,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -567,7 +545,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.8.3.tgz", "integrity": "sha512-a1qnnsr73KLNIQcQlcQ4ZHxqqfBKM6iNQZW2OMTyxNbA2WC7SHWHtGVpFzWtQAuS2pspkWVzdEBXXx8Ik0Za4w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -576,7 +553,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz", "integrity": "sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -585,7 +561,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -594,7 +569,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -603,7 +577,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -612,7 +585,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -621,7 +593,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -630,7 +601,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -639,7 +609,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -648,7 +617,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } @@ -666,7 +634,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz", "integrity": "sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -675,7 +642,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz", "integrity": "sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -684,7 +650,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz", "integrity": "sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", @@ -695,7 +660,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz", "integrity": "sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -704,7 +668,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz", "integrity": "sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "lodash": "^4.17.13" @@ -714,7 +677,6 @@ "version": "7.9.2", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz", "integrity": "sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-define-map": "^7.8.3", @@ -729,8 +691,7 @@ "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" } } }, @@ -738,7 +699,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz", "integrity": "sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -747,7 +707,6 @@ "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -775,7 +734,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz", "integrity": "sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ==", - "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -785,7 +743,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.9.0.tgz", "integrity": "sha512-7Qfg0lKQhEHs93FChxVLAvhBshOPQDtJUTVHr/ZwQNRccCm4O9D79r9tVSoV8iNwjP1YgfD+e/fgHcPkN1qEQg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-flow": "^7.8.3" @@ -795,7 +752,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz", "integrity": "sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -804,7 +760,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz", "integrity": "sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ==", - "dev": true, "requires": { "@babel/helper-function-name": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -814,7 +769,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz", "integrity": "sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -823,7 +777,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz", "integrity": "sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -843,7 +796,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz", "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==", - "dev": true, "requires": { "@babel/helper-module-transforms": "^7.9.0", "@babel/helper-plugin-utils": "^7.8.3", @@ -895,7 +847,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.8.3.tgz", "integrity": "sha512-i3LuN8tPDqUCRFu3dkzF2r1Nx0jp4scxtm7JxtIqI9he9Vk20YD+/zshdzR9JLsoBMlJlNR82a62vQExNEVx/Q==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -904,7 +855,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz", "integrity": "sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-replace-supers": "^7.8.3" @@ -914,7 +864,6 @@ "version": "7.9.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz", "integrity": "sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg==", - "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -924,7 +873,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz", "integrity": "sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -942,7 +890,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz", "integrity": "sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -951,7 +898,6 @@ "version": "7.9.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.9.4.tgz", "integrity": "sha512-Mjqf3pZBNLt854CK0C/kRuXAnE6H/bo7xYojP+WGtX8glDGSibcwnsWwhwoSuRg0+EBnxPC1ouVnuetUIlPSAw==", - "dev": true, "requires": { "@babel/helper-builder-react-jsx": "^7.9.0", "@babel/helper-builder-react-jsx-experimental": "^7.9.0", @@ -984,7 +930,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.9.0.tgz", "integrity": "sha512-K6m3LlSnTSfRkM6FcRk8saNEeaeyG5k7AVkBU2bZK3+1zdkSED3qNdsWrUgQBeTVD2Tp3VMmerxVO2yM5iITmw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.8.3" @@ -994,7 +939,6 @@ "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz", "integrity": "sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA==", - "dev": true, "requires": { "regenerator-transform": "^0.14.2" } @@ -1012,7 +956,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz", "integrity": "sha512-pUu9VSf3kI1OqbWINQ7MaugnitRss1z533436waNXp+0N3ur3zfut37sXiQMxkuCF4VUjwZucen/quskCh7NHw==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", @@ -1023,8 +966,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -1032,7 +974,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz", "integrity": "sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -1041,7 +982,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz", "integrity": "sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } @@ -1050,7 +990,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz", "integrity": "sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/helper-regex": "^7.8.3" @@ -1060,7 +999,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz", "integrity": "sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ==", - "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -1079,7 +1017,6 @@ "version": "7.9.4", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz", "integrity": "sha512-yeWeUkKx2auDbSxRe8MusAG+n4m9BFY/v+lPjmQDgOFX5qnySkUY5oXzkp6FwPdsYqnKay6lorXYdC0n3bZO7w==", - "dev": true, "requires": { "@babel/helper-create-class-features-plugin": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", @@ -1090,7 +1027,6 @@ "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz", "integrity": "sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw==", - "dev": true, "requires": { "@babel/helper-create-regexp-features-plugin": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3" @@ -1227,7 +1163,6 @@ "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.9.0.tgz", "integrity": "sha512-Tv8Zyi2J2VRR8g7pC5gTeIN8Ihultbmk0ocyNz8H2nEZbmhp1N6q0A1UGsQbDvGP/sNinQKUHf3SqXwqjtFv4Q==", - "dev": true, "requires": { "find-cache-dir": "^2.0.0", "lodash": "^4.17.13", @@ -1240,7 +1175,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", @@ -1251,7 +1185,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -1260,7 +1193,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -1270,7 +1202,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" @@ -1280,7 +1211,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -1289,7 +1219,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -1297,20 +1226,17 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, "requires": { "find-up": "^3.0.0" } @@ -1318,8 +1244,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "source-map": { "version": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1425,8 +1350,7 @@ "@bcoe/v8-coverage": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, "@cnakazawa/watch": { "version": "1.0.3", @@ -2071,20 +1995,17 @@ "@hapi/address": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.0.0.tgz", - "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==", - "dev": true + "integrity": "sha512-mV6T0IYqb0xL1UALPFplXYQmR0twnXG0M6jUswpquqT2sD12BOiCiLy3EvMp/Fy7s3DZElC4/aPjEjo2jeZpvw==" }, "@hapi/hoek": { "version": "6.2.4", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-6.2.4.tgz", - "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==", - "dev": true + "integrity": "sha512-HOJ20Kc93DkDVvjwHyHawPwPkX44sIrbXazAUDiUXaY2R9JwQGo2PhFfnQtdrsIe4igjG2fPgMra7NYw7qhy0A==" }, "@hapi/joi": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.0.tgz", "integrity": "sha512-n6kaRQO8S+kepUTbXL9O/UOL788Odqs38/VOfoCrATDtTvyfiO3fgjlSRaNkHabpTLgM7qru9ifqXlXbXk8SeQ==", - "dev": true, "requires": { "@hapi/address": "2.x.x", "@hapi/hoek": "6.x.x", @@ -2095,14 +2016,12 @@ "@hapi/marker": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@hapi/marker/-/marker-1.0.0.tgz", - "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA==", - "dev": true + "integrity": "sha512-JOfdekTXnJexfE8PyhZFyHvHjt81rBFSAbTIRAhF2vv/2Y1JzoKsGqxH/GpZJoF7aEfYok8JVcAHmSz1gkBieA==" }, "@hapi/topo": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.2.tgz", "integrity": "sha512-r+aumOqJ5QbD6aLPJWqVjMAPsx5pZKz+F5yPqXZ/WWG9JTtHbQqlzrJoknJ0iJxLj9vlXtmpSdjlkszseeG8OA==", - "dev": true, "requires": { "@hapi/hoek": "8.x.x" }, @@ -2110,8 +2029,7 @@ "@hapi/hoek": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.0.2.tgz", - "integrity": "sha512-O6o6mrV4P65vVccxymuruucb+GhP2zl9NLCG8OdoFRS8BEGw3vwpPp20wpAtpbQQxz1CEUtmxJGgWhjq1XA3qw==", - "dev": true + "integrity": "sha512-O6o6mrV4P65vVccxymuruucb+GhP2zl9NLCG8OdoFRS8BEGw3vwpPp20wpAtpbQQxz1CEUtmxJGgWhjq1XA3qw==" } } }, @@ -2196,7 +2114,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", - "dev": true, "requires": { "@jest/source-map": "^24.9.0", "chalk": "^2.0.1", @@ -2207,7 +2124,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -2217,39 +2133,38 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" } } }, "@jest/core": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.3.0.tgz", - "integrity": "sha512-+D5a/tFf6pA/Gqft2DLBp/yeSRgXhlJ+Wpst0X/ZkfTRP54qDR3C61VfHwaex+GzZBiTcE9vQeoZ2v5T10+Mqw==", + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", "dev": true, "requires": { - "@jest/console": "^25.3.0", - "@jest/reporters": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-changed-files": "^25.3.0", - "jest-config": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-message-util": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-resolve-dependencies": "^25.3.0", - "jest-runner": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", - "jest-watcher": "^25.3.0", + "jest-resolve": "^25.5.1", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "jest-watcher": "^25.5.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "realpath-native": "^2.0.0", @@ -2259,94 +2174,97 @@ }, "dependencies": { "@jest/console": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.4.0.tgz", - "integrity": "sha512-CfE0erx4hdJ6t7RzAcE1wLG6ZzsHSmybvIBQDoCkDM1QaSeWL9wJMzID/2BbHHa7ll9SsbbK43HjbERbBaFX2A==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-message-util": "^25.4.0", - "jest-util": "^25.4.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" } }, "@jest/test-result": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.4.0.tgz", - "integrity": "sha512-8BAKPaMCHlL941eyfqhWbmp3MebtzywlxzV+qtngQ3FH+RBqnoSAhNEPj4MG7d2NVUrMOVfrwuzGpVIK+QnMAA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/console": "^25.4.0", - "@jest/types": "^25.4.0", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/transform": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.4.0.tgz", - "integrity": "sha512-t1w2S6V1sk++1HHsxboWxPEuSpN8pxEvNrZN+Ud/knkROWtf8LeUmz73A4ezE8476a5AM00IZr9a8FO9x1+j3g==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.4.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", "jest-regex-util": "^25.2.6", - "jest-util": "^25.4.0", + "jest-util": "^25.5.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "realpath-native": "^2.0.0", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, "ansi-escapes": { @@ -2356,6 +2274,14 @@ "dev": true, "requires": { "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } } }, "ansi-regex": { @@ -2406,6 +2332,12 @@ "fill-range": "^7.0.1" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -2440,6 +2372,16 @@ "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, "fsevents": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", @@ -2448,9 +2390,9 @@ "optional": true }, "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.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "has-flag": { @@ -2465,67 +2407,57 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, "jest-haste-map": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.4.0.tgz", - "integrity": "sha512-5EoCe1gXfGC7jmXbKzqxESrgRcaO3SzWXGCnvp9BcT0CFMyrB1Q6LIsjl9RmvmJGQgW297TCfrdgiy574Rl9HQ==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, "requires": { - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.4.0", - "jest-worker": "^25.4.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", "which": "^2.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "jest-message-util": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.4.0.tgz", - "integrity": "sha512-LYY9hRcVGgMeMwmdfh9tTjeux1OjZHMusq/E5f3tJN+dAoVVkJtq5ZUEPIcB7bpxDUt2zjUsrwg0EGgPQ+OhXQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "jest-regex-util": { @@ -2534,48 +2466,84 @@ "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==", - "dev": true + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.4.0.tgz", - "integrity": "sha512-WSZD59sBtAUjLv1hMeKbNZXmMcrLRWcYqpO8Dz8b4CeCTZpfNQw2q9uwrYAD+BbJoLJlu4ezVPwtAmM/9/SlZA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" } }, "jest-worker": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.4.0.tgz", - "integrity": "sha512-ghAs/1FtfYpMmYQ0AHqxV62XPvKdUDIBBApMZfly+E9JEmYh2K45G0R5dWxx986RN12pRCxsViwQVtGl+N4whw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2592,18 +2560,175 @@ "picomatch": "^2.0.5" } }, + "node-notifier": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "dev": true, + "optional": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", + "shellwords": "^0.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "optional": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", "dev": true }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2644,11 +2769,39 @@ } }, "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, + "v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "dependencies": { + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -2673,34 +2826,42 @@ } }, "@jest/environment": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.3.0.tgz", - "integrity": "sha512-vgooqwJTHLLak4fE+TaCGeYP7Tz1Y3CKOsNxR1sE0V3nx3KRUHn3NUnt+wbcfd5yQWKZQKAfW6wqbuwQLrXo3g==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", "requires": { - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0" + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" }, "dependencies": { "@jest/fake-timers": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.3.0.tgz", - "integrity": "sha512-NHAj7WbsyR3qBJPpBwSwqaq2WluIvUQsyzpJTN7XDVk7VnlC/y1BAnaYZL3vbPIP8Nhm0Ae5DJe0KExr/SdMJQ==", - "dev": true, - "requires": { - "@jest/types": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", "lolex": "^5.0.0" } }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -2710,7 +2871,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -2719,7 +2879,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2729,7 +2888,6 @@ "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.4" } @@ -2737,62 +2895,62 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.3.0.tgz", - "integrity": "sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "requires": { - "@jest/types": "^25.3.0" + "@jest/types": "^25.5.0" } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } @@ -2801,7 +2959,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -2810,14 +2967,12 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -2826,7 +2981,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -2837,7 +2991,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", - "dev": true, "requires": { "@jest/types": "^24.9.0", "jest-message-util": "^24.9.0", @@ -2848,7 +3001,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -2859,13 +3011,250 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } } } }, + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + }, + "dependencies": { + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "requires": { + "@jest/types": "^25.5.0" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + } + } + }, "@jest/reporters": { "version": "25.3.0", "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.3.0.tgz", @@ -3249,7 +3638,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", - "dev": true, "requires": { "callsites": "^3.0.0", "graceful-fs": "^4.1.15", @@ -3259,14 +3647,12 @@ "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==", - "dev": true + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -3274,7 +3660,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", - "dev": true, "requires": { "@jest/console": "^24.9.0", "@jest/types": "^24.9.0", @@ -3285,7 +3670,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -3296,7 +3680,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -3304,57 +3687,55 @@ } }, "@jest/test-sequencer": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.3.0.tgz", - "integrity": "sha512-Xvns3xbji7JCvVcDGvqJ/pf4IpmohPODumoPEZJ0/VgC5gI4XaNVIBET2Dq5Czu6Gk3xFcmhtthh/MBOTljdNg==", - "dev": true, + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", "requires": { - "@jest/test-result": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-runner": "^25.3.0", - "jest-runtime": "^25.3.0" + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, - "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", - "dev": true, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -3364,7 +3745,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -3374,7 +3754,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -3383,7 +3762,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3393,7 +3771,6 @@ "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.4" } @@ -3401,86 +3778,96 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "optional": true }, "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==", - "dev": true + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-haste-map": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.3.0.tgz", - "integrity": "sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A==", - "dev": true, + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", "which": "^2.0.2" } }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==", - "dev": true + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, "jest-worker": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz", - "integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" @@ -3489,14 +3876,12 @@ "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -3505,26 +3890,17 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -3533,7 +3909,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -3542,7 +3917,6 @@ "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" } @@ -3639,6 +4013,7 @@ "version": "25.3.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.3.0.tgz", "integrity": "sha512-UkaDNewdqXAmCDbN2GlUM6amDKS78eCqiw/UmF5nE0mmLTd6moJkiZJML/X52Ke3LH7Swhw883IRXq8o9nWjVw==", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -3650,6 +4025,7 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -3659,6 +4035,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3668,6 +4045,7 @@ "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.4" } @@ -3675,17 +4053,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6457,7 +6838,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-3.0.0.tgz", "integrity": "sha512-m3X+iWLsK/H7/b7PpbNO33eQayR/+M26la4ZbYe1KRke5Umg4PIWsvg21O8Tw4uJcY8LA5hsP+rBi/syBkBf0g==", - "dev": true, "requires": { "serve-static": "^1.13.1" } @@ -6466,7 +6846,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-3.0.3.tgz", "integrity": "sha512-rNO9DmRiVhB6aP2DVUjEJv7ecriTARDZND88ny3xNVUkrD1Y+zwF6aZu3eoT52VXOxLCSLiJzz19OiyGmfqxYg==", - "dev": true, "requires": { "@react-native-community/cli-tools": "^3.0.0", "chalk": "^2.4.2", @@ -6481,7 +6860,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6492,7 +6870,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -6505,7 +6882,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -6520,7 +6896,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -6529,7 +6904,6 @@ "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" @@ -6538,14 +6912,12 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" } } }, @@ -6553,7 +6925,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.0.0.tgz", "integrity": "sha512-QoNVlDj8eMXRZk9uktPFsctHurQpv9jKmiu6mQii4NEtT2npE7g1hbWpRNojutBsfgmCdQGDHd9uB54eeCnYgg==", - "dev": true, "requires": { "@react-native-community/cli-tools": "^3.0.0", "chalk": "^2.4.2", @@ -6565,7 +6936,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6578,7 +6948,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz", "integrity": "sha512-8IhQKZdf3E4CR8T7HhkPGgorot/cLkRDgneJFDSWk/wCYZAuUh4NEAdumQV7N0jLSMWX7xxiWUPi94lOBxVY9g==", - "dev": true, "requires": { "chalk": "^2.4.2", "lodash": "^4.17.5", @@ -6590,7 +6959,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6600,16 +6968,18 @@ "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "dev": true + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" } } }, "@react-native-community/cli-types": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-3.0.0.tgz", - "integrity": "sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg==", - "dev": true + "integrity": "sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg==" + }, + "@react-native-community/slider": { + "version": "git+https://github.com/wordpress-mobile/react-native-slider.git#5ad284d92b8d886e366445bf215be741ed53ddc6", + "from": "git+https://github.com/wordpress-mobile/react-native-slider.git#5ad284d92b8d886e366445bf215be741ed53ddc6" }, "@samverschueren/stream-to-observable": { "version": "0.3.0", @@ -6627,10 +6997,9 @@ "dev": true }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", - "dev": true, + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.2.tgz", + "integrity": "sha512-+DUO6pnp3udV/v2VfUWgaY5BIE1IfT7lLfeDzPVeMT1XKkaAp9LgSI9x5RtrFQoZ9Oi0PgXQQHPaoKu7dCjVxw==", "requires": { "type-detect": "4.0.8" } @@ -9521,7 +9890,6 @@ "version": "7.1.7", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", - "dev": true, "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0", @@ -9531,10 +9899,9 @@ } }, "@types/babel__generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", - "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", - "dev": true, + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "requires": { "@babel/types": "^7.0.0" } @@ -9543,17 +9910,15 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "dev": true, "requires": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "@types/babel__traverse": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", - "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", - "dev": true, + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", + "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", "requires": { "@babel/types": "^7.3.0" } @@ -9609,8 +9974,7 @@ "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==" }, "@types/glob": { "version": "7.1.1", @@ -9623,6 +9987,14 @@ "@types/node": "*" } }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "requires": { + "@types/node": "*" + } + }, "@types/history": { "version": "4.7.4", "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.4.tgz", @@ -9711,14 +10083,12 @@ "@types/node": { "version": "12.7.11", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.11.tgz", - "integrity": "sha512-Otxmr2rrZLKRYIybtdG/sgeO+tHY20GxeDjcGmUnmmlCWyEnv2a2x1ZXBo3BTec4OiTXMQCiazB8NMBf0iRlFw==", - "dev": true + "integrity": "sha512-Otxmr2rrZLKRYIybtdG/sgeO+tHY20GxeDjcGmUnmmlCWyEnv2a2x1ZXBo3BTec4OiTXMQCiazB8NMBf0iRlFw==" }, "@types/normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" }, "@types/npm-package-arg": { "version": "6.1.0", @@ -9734,14 +10104,12 @@ "@types/prettier": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.0.tgz", - "integrity": "sha512-gDE8JJEygpay7IjA/u3JiIURvwZW08f0cZSZLAzFoX/ZmeqvS0Sqv+97aKuHpNsalAMMhwPe+iAS6fQbfmbt7A==", - "dev": true + "integrity": "sha512-gDE8JJEygpay7IjA/u3JiIURvwZW08f0cZSZLAzFoX/ZmeqvS0Sqv+97aKuHpNsalAMMhwPe+iAS6fQbfmbt7A==" }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", - "dev": true + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" }, "@types/q": { "version": "1.5.2", @@ -9769,7 +10137,6 @@ "version": "16.9.18", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.18.tgz", "integrity": "sha512-MvjiKX/kUE8o49ipppg49RDZ97p4XfW1WWksp/UlTUSJpisyhzd62pZAMXxAscFLoxfYOflkGANAnGkSeHTFQg==", - "dev": true, "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" @@ -9793,6 +10160,15 @@ "@types/react": "*" } }, + "@types/react-native": { + "version": "0.57.65", + "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.57.65.tgz", + "integrity": "sha512-7P5ulTb+/cnwbABWaAjzKmSYkRWeK7UCTfUwHhDpnwxdiL2X/KbdN1sPgo0B2E4zxfYE3MEoHv7FhB8Acfvf8A==", + "requires": { + "@types/prop-types": "*", + "@types/react": "*" + } + }, "@types/react-syntax-highlighter": { "version": "11.0.2", "resolved": "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.2.tgz", @@ -11083,6 +11459,320 @@ "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.2", "enzyme-to-json": "^3.4.4" + }, + "dependencies": { + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "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.4" + } + }, + "color-name": { + "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 + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "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 + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "which": { + "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" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } } }, "@wordpress/jest-puppeteer-axe": { @@ -11236,6 +11926,78 @@ "@babel/runtime": "^7.9.2" } }, + "@wordpress/react-native-aztec": { + "version": "file:packages/react-native-aztec", + "dependencies": { + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "requires": { + "fbjs": "^0.8.16", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + } + } + }, + "@wordpress/react-native-bridge": { + "version": "file:packages/react-native-bridge", + "requires": { + "@wordpress/react-native-aztec": "file:packages/react-native-aztec" + } + }, + "@wordpress/react-native-editor": { + "version": "file:packages/react-native-editor", + "requires": { + "@babel/runtime": "^7.9.2", + "@react-native-community/slider": "git+https://github.com/wordpress-mobile/react-native-slider.git#5ad284d92b8d886e366445bf215be741ed53ddc6", + "@wordpress/api-fetch": "file:packages/api-fetch", + "@wordpress/block-editor": "file:packages/block-editor", + "@wordpress/block-library": "file:packages/block-library", + "@wordpress/blocks": "file:packages/blocks", + "@wordpress/components": "file:packages/components", + "@wordpress/data": "file:packages/data", + "@wordpress/edit-post": "file:packages/edit-post", + "@wordpress/element": "file:packages/element", + "@wordpress/hooks": "file:packages/hooks", + "@wordpress/i18n": "file:packages/i18n", + "@wordpress/react-native-aztec": "file:packages/react-native-aztec", + "@wordpress/react-native-bridge": "file:packages/react-native-bridge", + "fast-average-color": "^4.3.0", + "jed": "^1.1.1", + "jsc-android": "^241213.1.0", + "jsdom-jscore-rn": "git+https://github.com/iamcco/jsdom-jscore-rn.git#a562f3d57c27c13e5bfc8cf82d496e69a3ba2800", + "metro-react-native-babel-preset": "0.57.0", + "metro-react-native-babel-transformer": "0.56.0", + "node-fetch": "^2.3.0", + "react-native": "0.61.5", + "react-native-dark-mode": "git+https://github.com/wordpress-mobile/react-native-dark-mode.git#f09bf1480e7b34536413ab3300f29e4375edb2c6", + "react-native-get-random-values": "git+https://github.com/wordpress-mobile/react-native-get-random-values.git#f03f2c16414aff4ea76064dcd00a9e3c6efc838d", + "react-native-hr": "git+https://github.com/Riglerr/react-native-hr.git#2d01a5cf77212d100e8b99e0310cce5234f977b3", + "react-native-hsv-color-picker": "git+https://github.com/wordpress-mobile/react-native-hsv-color-picker.git", + "react-native-keyboard-aware-scroll-view": "git+https://github.com/wordpress-mobile/react-native-keyboard-aware-scroll-view.git#gb-v0.8.8", + "react-native-linear-gradient": "git+https://github.com/wordpress-mobile/react-native-linear-gradient.git#52bf43077171cff8714ce3e0155f3ebb7f55bc37", + "react-native-modal": "^6.5.0", + "react-native-safe-area": "^0.5.0", + "react-native-sass-transformer": "^1.1.1", + "react-native-svg": "git+https://github.com/wordpress-mobile/react-native-svg.git#a628e92990a2404e30a0086f168bd2b5b7b4ce96", + "react-native-url-polyfill": "^1.1.2", + "react-native-video": "git+https://github.com/wordpress-mobile/react-native-video.git#1b964b107863351ed744fc104d7952bbec3e2d4f" + }, + "dependencies": { + "jsc-android": { + "version": "241213.1.0", + "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-241213.1.0.tgz", + "integrity": "sha512-AH8NYyMNLNhcUEF97QbMxPNLNW+oiSBlvm1rsMNzgJ1d5TQzdh/AOJGsxeeESp3m9YIWGLCgUvGTVoVLs0p68A==" + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + } + } + }, "@wordpress/redux-routine": { "version": "file:packages/redux-routine", "requires": { @@ -11308,6 +12070,503 @@ "webpack-bundle-analyzer": "^3.6.1", "webpack-cli": "^3.3.11", "webpack-livereload-plugin": "^2.3.0" + }, + "dependencies": { + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/core": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.5.4.tgz", + "integrity": "sha512-3uSo7laYxF00Dg/DMgbn4xMJKmDdWvZnf89n8Xj/5/AeQ2dOQmn6b6Hkj/MleyzZWXpwv+WSdYWl4cLsy2JsoA==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/reporters": "^25.5.1", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^25.5.0", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-resolve-dependencies": "^25.5.4", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-watcher": "^25.5.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "realpath-native": "^2.0.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0" + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + } + }, + "@jest/reporters": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.5.1.tgz", + "integrity": "sha512-3jbd8pPDTuhYJ7vqiHXbSwTJQNavczPs+f1kRprRDxETeE3u6srJ+f0NPuwvOmk+lmunZzPkYWIFZDLHQPkviw==", + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^25.5.1", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^3.1.0", + "terminal-link": "^2.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "requires": { + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + } + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "dev": true, + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "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==" + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } } }, "@wordpress/server-side-render": { @@ -11403,20 +12662,17 @@ "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", - "dev": true + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" }, "abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "dev": true, "requires": { "event-target-shim": "^5.0.0" } @@ -11424,14 +12680,12 @@ "absolute-path": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", - "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=", - "dev": true + "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=" }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", - "dev": true, "requires": { "mime-types": "~2.1.18", "negotiator": "0.6.1" @@ -11440,14 +12694,12 @@ "acorn": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==" }, "acorn-globals": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "dev": true, "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" @@ -11456,8 +12708,7 @@ "acorn-walk": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" } } }, @@ -11681,7 +12932,6 @@ "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -11776,7 +13026,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", - "dev": true, "requires": { "ansi-wrap": "^0.1.0" } @@ -11785,7 +13034,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", - "dev": true, "requires": { "ansi-wrap": "0.1.0" } @@ -11793,14 +13041,12 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", - "dev": true + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" }, "ansi-fragments": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/ansi-fragments/-/ansi-fragments-0.2.1.tgz", "integrity": "sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w==", - "dev": true, "requires": { "colorette": "^1.0.7", "slice-ansi": "^2.0.0", @@ -11810,14 +13056,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -11828,7 +13072,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -11839,7 +13082,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", - "dev": true, "requires": { "ansi-wrap": "0.1.0" } @@ -11854,7 +13096,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", - "dev": true, "requires": { "ansi-wrap": "0.1.0" } @@ -11862,8 +13103,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "3.2.1", @@ -11893,8 +13133,7 @@ "ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", - "dev": true + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" }, "any-observable": { "version": "0.3.0", @@ -11923,139 +13162,6824 @@ "integrity": "sha1-OBh+wt6nV3//Az/8sSFyaS/24Rg=", "dev": true }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - } - } - }, - "aria-query": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", - "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", - "dev": true, - "requires": { - "ast-types-flow": "0.0.7", - "commander": "^2.11.0" + "app-root-path": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz", + "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==" + }, + "appium": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/appium/-/appium-1.17.1.tgz", + "integrity": "sha512-QdM7b0AAF/q79V8rauVZw24dGpU6tkLLHbbMG+yfNlsrsa8/xivOrbc3DM5Fmn8x4JjgUthHenIse7KRWCQy3w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.6.0", + "appium-android-driver": "^4.20.0", + "appium-base-driver": "^5.0.0", + "appium-espresso-driver": "^1.0.0", + "appium-fake-driver": "^0.x", + "appium-flutter-driver": "^0", + "appium-ios-driver": "4.x", + "appium-mac-driver": "1.x", + "appium-support": "2.x", + "appium-tizen-driver": "^1.1.1-beta.4", + "appium-uiautomator2-driver": "^1.37.1", + "appium-windows-driver": "1.x", + "appium-xcuitest-driver": "^3.22.0", + "appium-youiengine-driver": "^1.2.0", + "argparse": "^1.0.10", + "async-lock": "^1.0.0", + "asyncbox": "2.x", + "bluebird": "3.x", + "continuation-local-storage": "3.x", + "dateformat": "^3.0.3", + "find-root": "^1.1.0", + "fsevents": "2.x", + "lodash": "^4.17.11", + "longjohn": "^0.2.12", + "npmlog": "4.x", + "request": "^2.81.0", + "request-promise": "4.x", + "semver": "^7.0.0", + "source-map-support": "0.x", + "teen_process": "1.x", + "winston": "3.x", + "word-wrap": "^1.2.3" }, "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-differ": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", - "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", - "dev": true - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-filter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", - "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", - "dev": true - }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" - } - }, - "array-iterate": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", - "integrity": "sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ==", - "dev": true - }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, - "array-slice": { + "101": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/101/-/101-1.6.3.tgz", + "integrity": "sha512-4dmQ45yY0Dx24Qxp+zAsNLlMF6tteCyfVzgbulvSyC7tCyd3V8sW76sS0tHq8NpcbXfWTKasfyfzU1Kd86oKzw==", + "dev": true, + "requires": { + "clone": "^1.0.2", + "deep-eql": "^0.1.3", + "keypather": "^1.10.2" + } + }, + "@babel/polyfill": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.8.7.tgz", + "integrity": "sha512-LeSfP9bNZH2UOZgcGcZ0PIHUt1ZuHub1L3CVmEyqLxCeDLm4C5Gi8jRH8ZX2PNpDhQCo0z6y/+DIs2JlliXW8w==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.4" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + } + } + }, + "@babel/runtime": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", + "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@jimp/bmp": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.9.5.tgz", + "integrity": "sha512-2cYdgXaNykuPe9sjm11Jihp5VomyWTWziIuDDB7xnxQtEz2HUR0bjXm2MJJOfU0TL52H+LS2JIKtAxcLPzp28w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "bmp-js": "^0.1.0", + "core-js": "^3.4.1" + } + }, + "@jimp/core": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.9.5.tgz", + "integrity": "sha512-P1mlB9UOeI3IAQ4lGTmRBGw+F/mHWXd3tSyBskjL4E3YJ1eNK7WRrErUj/vUOvSBIryotu7nGo8vv8Q8JZ7/8w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "core-js": "^3.4.1", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + }, + "dependencies": { + "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" + } + } + } + }, + "@jimp/custom": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.9.5.tgz", + "integrity": "sha512-FaR7M0oxqbd7ujBL5ryyllS+mEuMKbKaDsdb8Cpu9SAo80DBiasUrYFFD/45/aRa95aM5o8t4C4Pna2bx8t3Tg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/core": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/gif": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.9.5.tgz", + "integrity": "sha512-QxjLl15nIz/QTeNgLFUJIOMLIceMO2B/xLUWF1/WqaP7Su6SGasRS6JY8OZ9QnqJLMWkodoEJmL6DxwtoOtqdg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.9.5.tgz", + "integrity": "sha512-cBpXqmeegsLzf/mYk1WpYov2RH1W944re5P61/ag6AMWEMQ51BoBdgBy5JABZIELg2GQxpoG+g/KxUshRzeIAg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1", + "jpeg-js": "^0.3.4" + } + }, + "@jimp/plugin-blit": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.9.5.tgz", + "integrity": "sha512-VmV99HeCPOyliY/uEGOaKO9EcqDxSBzKDGC7emNCLFzlbK4uty4/cYMKGKTBiZR9AS1rEd63LxrDtbHKR8CsqQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-blur": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.9.5.tgz", + "integrity": "sha512-FnAEhMW9ZK8D6qCLDeMAloi4h7TCch9ZWFdonj49gwllpvLksBpnL9PTft4dFXCwZgOAq2apYwW7cwTAIfAw4A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-color": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.9.5.tgz", + "integrity": "sha512-2aFE0tRdhAKCCgh+tFLsLPOSgrk3ttl2TtTP5FAXeKmzlLj7FZ/JKj0waaGWZKdJ+uDxsVpX3EhuK3CfukIyrg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.9.5.tgz", + "integrity": "sha512-zhaCJnUqd8hhD8IXxbRALU6ZzCWWbQDulc8Tn8Hxnub0si7dlq/DxBQT7og6kCxswBj2zPBtRAHONEwLdt7Nfw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-cover": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.9.5.tgz", + "integrity": "sha512-rG7vtx7vV9mHCFR4YP9GzGEsaop0IkMidP3UFPULbDcBdEEkehEG7a0h2X4w/Nt07J3k8wVoXYTjrb/CXpWkaw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-crop": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.9.5.tgz", + "integrity": "sha512-yoScC43YhYlswTKyL4fmawGwF73HyuIRpp1R3mXa6qbMA9mjX9QiqNdAIMB3UMHeBcIgkOD/Zy1f90/skBMpxg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-displace": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.9.5.tgz", + "integrity": "sha512-nwfB72qNP8kNyBnlaY0vgJys7RUjvI61Qp3AMMbKKaRSsthCx7aeKU9Cyv+AHMfcVkkt3NdTmh7ScE+hkNFUhA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-dither": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.9.5.tgz", + "integrity": "sha512-Pp1ehm5Hon6LcttRG+d+x1UN1ww00P4cyBnMVRR3NMhIfgc0IjQgojik9ZXax3nVj7XkqXJJh8f5uxC1cvYUnA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-flip": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.9.5.tgz", + "integrity": "sha512-rKbg8c9ePst3w2t1kxQt2H05/rUR5/pjjafhZ97s01pxH/SOJudy5d76nJGzRBYoaRnxpvDzpN+2+iA08wDY5Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.9.5.tgz", + "integrity": "sha512-8HloHpVPgSsoWekslJ5uUPK2ddoLrGXQAVOyo3BT2pVgwbL317+r96NxPGKTxrY20fqex9SQrjx3kHeSWbysEA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-invert": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.9.5.tgz", + "integrity": "sha512-tqfMqQqsU4ulaif0Kk/BydqmG5UbjT67dmMjwnDL7rke+ypJ8tzq7j9QeZ9SDFB+PxUQcy/kPEw/R2Ys7HHi8A==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-mask": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.9.5.tgz", + "integrity": "sha512-lIOrKb/VT1laDIA1H1nPOdtOB4TVhMRlxanXoEP8uKdE6a2goqZHXbKLn9itkm0MxtsTlT9KIXwzGxjCV38B3w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-normalize": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.9.5.tgz", + "integrity": "sha512-gayxgPLDp2gynu2IacvdCtqw0bdcC2feUqYOBjTtCpAwIz1KP2Qd6qKjV1dAVGiLO9ESW5maMa0vIBiBkYOovg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-print": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.9.5.tgz", + "integrity": "sha512-/BUSyCfvVhuFdf+rBdH1wbuY8r9J0qhn4Icy7HqO58By7I+V7q7jayoeiLk+zEBsAXpCUbWiZG3KWNtZhLWeQg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.9.5.tgz", + "integrity": "sha512-vIMleLPbEv0qTE1Mnc7mg5HSFc4l4FxlbDniVUvpi8ZMFa8IkigcTeAgXUKacevNL7uZ66MrnpQ49J3tNE28dQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-rotate": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.9.5.tgz", + "integrity": "sha512-BHlhwUruHNQkOpsfzTE2uuSfmkj5eiIDRSAC8whupUGGXNgS67tZJB6u0qDRIeSP/gWV5tGGwXQNMn3AahwR1Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugin-scale": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.9.5.tgz", + "integrity": "sha512-PDU8F77EPFTcLBVDcJtGUvPXA2acG4KqJMZauHwZLZxuiDEvt9qsDQm4aTKcN/ku8oWZjfGBSOamhx/QNUqV5Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1" + } + }, + "@jimp/plugins": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.9.5.tgz", + "integrity": "sha512-3hvuXeRLj36ifpwE7I7g5Da9bKl/0y62t90ZN0hdQwhLBjRRF4u1e1JZpyu6EK98Bp+W/c8fJ2iuOsHadJOusg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/plugin-blit": "^0.9.5", + "@jimp/plugin-blur": "^0.9.5", + "@jimp/plugin-color": "^0.9.5", + "@jimp/plugin-contain": "^0.9.5", + "@jimp/plugin-cover": "^0.9.5", + "@jimp/plugin-crop": "^0.9.5", + "@jimp/plugin-displace": "^0.9.5", + "@jimp/plugin-dither": "^0.9.5", + "@jimp/plugin-flip": "^0.9.5", + "@jimp/plugin-gaussian": "^0.9.5", + "@jimp/plugin-invert": "^0.9.5", + "@jimp/plugin-mask": "^0.9.5", + "@jimp/plugin-normalize": "^0.9.5", + "@jimp/plugin-print": "^0.9.5", + "@jimp/plugin-resize": "^0.9.5", + "@jimp/plugin-rotate": "^0.9.5", + "@jimp/plugin-scale": "^0.9.5", + "core-js": "^3.4.1", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.9.5.tgz", + "integrity": "sha512-0GPq/XixXcuWIA3gpMCUUj6rhxT78Hu9oDC9reaHUCcC/5cRTd5Eh7wLafZL8EfOZWV3mh2FZtWiY1xaNHHlBQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/utils": "^0.9.5", + "core-js": "^3.4.1", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.9.5.tgz", + "integrity": "sha512-EcRtiHsAQ9aygRRMWhGTVfitfHwllgt93GE1L8d/iwSlu3e3IIV38MDINdluQUQMU5jcFBcX6eyVVvsgCleGiQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "core-js": "^3.4.1", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.9.5.tgz", + "integrity": "sha512-62inaxx8zy24WMP+bsg6ZmgsL49oyoGUIGcjDKzvyAY/O6opD+UMNlArhl0xvCCdzriQxbljtSv/8uyHxz4Xbw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/bmp": "^0.9.5", + "@jimp/gif": "^0.9.5", + "@jimp/jpeg": "^0.9.5", + "@jimp/png": "^0.9.5", + "@jimp/tiff": "^0.9.5", + "core-js": "^3.4.1", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.9.5.tgz", + "integrity": "sha512-W9vse4/1AYmOjtIVACoBMdc/2te1zcPURhMYNEyiezCU7hWMdj/Z1mwiWFq3AYCgOG8GPVx0ZQzrgqUfUxfTHQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "core-js": "^3.4.1" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/node": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.0.tgz", + "integrity": "sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ==", + "dev": true, + "optional": true + }, + "@wdio/config": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-5.18.4.tgz", + "integrity": "sha512-HQugjG+BABDYG/1dPR6KA+IQilsg1MSQ/NVIg8R6I8ER9MA2JNIoaxvXZ+CnDfgY/QpyIHEeqJhfgw8GElaPdw==", + "dev": true, + "requires": { + "@wdio/logger": "5.16.10", + "deepmerge": "^4.0.0", + "glob": "^7.1.2" + } + }, + "@wdio/logger": { + "version": "5.16.10", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-5.16.10.tgz", + "integrity": "sha512-hRKhxgd9uB48Dtj2xe2ckxU4KwI/RO8IwguySuaI2SLFj6EDbdonwzpVkq111/fjBuq7R1NauAaNcm3AMEbIFA==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "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" + } + } + } + }, + "@wdio/protocols": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-5.19.0.tgz", + "integrity": "sha512-6DTSZKJd/UwtiTuQ2GgfQV/LTnjVmAn6uNzUz2j5cdFxCI63vaRQ4AnaPFjjT3VuN+rJXnmRF8FKoT02jBCQrg==", + "dev": true + }, + "@wdio/repl": { + "version": "5.18.6", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-5.18.6.tgz", + "integrity": "sha512-z9UPBk/Uee0l9g0ijnOatU3WP7TcpIyNtRj9AGsJVbYZFwqMWBqPkO4nblldyNQIuqdgXAPsDo8lPGDno12/oA==", + "dev": true, + "requires": { + "@wdio/utils": "5.18.6" + } + }, + "@wdio/utils": { + "version": "5.18.6", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-5.18.6.tgz", + "integrity": "sha512-OVdK7P9Gne9tR6dl1GEKucwX4mtS47F26g4lH8r0HURvMegZLGtcchI1cqF6hjK7EpP737b+C3q4ooZSBdH9XQ==", + "dev": true, + "requires": { + "@wdio/logger": "5.16.10", + "deepmerge": "^4.0.0" + } + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "adbkit-apkreader": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/adbkit-apkreader/-/adbkit-apkreader-3.2.0.tgz", + "integrity": "sha512-QwsxPYCqWSmCAiW/A4gq0eytb4jtZc7WNbECIhLCRfGEB38oXzIV/YkTpkOTQFKSg3S4Svb6y///qOUH7UrWWw==", + "dev": true, + "requires": { + "bluebird": "^3.4.7", + "debug": "~4.1.1", + "yauzl": "^2.7.0" + } + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "any-base": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/any-base/-/any-base-1.1.0.tgz", + "integrity": "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==", + "dev": true + }, + "appium-adb": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/appium-adb/-/appium-adb-7.26.0.tgz", + "integrity": "sha512-EWVj2kaPmbnGTrr9sX+XqMmYKKdFlo94M106fEfLbb41PxJTn/e6bwJ6qwXjGMpJhlpgbjUwFGhnUkaut6lD+w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "adbkit-apkreader": "^3.1.2", + "appium-support": "^2.37.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.4.7", + "lodash": "^4.0.0", + "lru-cache": "^5.0.0", + "semver": "^7.0.0", + "shell-quote": "^1.6.1", + "source-map-support": "^0.5.5", + "teen_process": "^1.11.0", + "utf7": "^1.0.2" + } + }, + "appium-android-driver": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/appium-android-driver/-/appium-android-driver-4.26.1.tgz", + "integrity": "sha512-vczjhG0DOToBDV/++0iMdx4wXvTD/CaICH4F9IbTPa0APOTSGsL+k113vmD2Alsquvq/F/Kj5MFIq2DlpPjhgw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-adb": "^7.22.0", + "appium-base-driver": "^5.1.0", + "appium-chromedriver": "^4.13.0", + "appium-support": "^2.37.0", + "asyncbox": "^2.0.4", + "bluebird": "^3.4.7", + "io.appium.settings": "^3.1.0", + "jimp": "^0.9.3", + "lodash": "^4.17.4", + "moment": "^2.24.0", + "moment-timezone": "^0.5.26", + "portfinder": "^1.0.6", + "portscanner": "2.2.0", + "semver": "^7.0.0", + "shared-preferences-builder": "^0.0.4", + "shell-quote": "^1.6.1", + "source-map-support": "^0.5.5", + "teen_process": "^1.9.0", + "ws": "^7.0.0", + "yargs": "^15.0.1" + } + }, + "appium-base-driver": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/appium-base-driver/-/appium-base-driver-5.3.1.tgz", + "integrity": "sha512-IQpmGI3+CzBzbW34x1eGRIkOuMYqJ1uHvJwmThFJBLoaYZNDPRlO37g0np2TjESwOBYpD1DSEWLxzkKQusU1rA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.39.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.3", + "body-parser": "^1.18.2", + "colors": "^1.1.2", + "es6-error": "^4.1.1", + "express": "^4.16.2", + "http-status-codes": "^1.3.0", + "lodash": "^4.0.0", + "lru-cache": "^5.0.0", + "method-override": "^3.0.0", + "morgan": "^1.9.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "sanitize-filename": "^1.6.1", + "serve-favicon": "^2.4.5", + "source-map-support": "^0.5.5", + "uuid-js": "^0.7.5", + "validate.js": "^0.13.0", + "webdriverio": "^5.10.9", + "ws": "^7.0.0" + } + }, + "appium-chromedriver": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/appium-chromedriver/-/appium-chromedriver-4.21.0.tgz", + "integrity": "sha512-93LmpeC7sCqjHzMhk+1JR8VM9rNwLJ/mNWjjG26ngqfSY/xNn5fzq9ff+TUKXYVlyPqE64ODi+5UifKUZ9QZ7Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.39.0", + "asyncbox": "^2.0.2", + "bluebird": "^3.5.1", + "compare-versions": "^3.4.0", + "fancy-log": "^1.3.2", + "lodash": "^4.17.4", + "request": "^2.57.0", + "request-promise": "^4.2.2", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.15.0", + "xmldom": "^0.2.0", + "xpath": "^0.0.27" + }, + "dependencies": { + "xmldom": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.2.1.tgz", + "integrity": "sha512-kXXiYvmblIgEemGeB75y97FyaZavx6SQhGppLw5TKWAD2Wd0KAly0g23eVLh17YcpxZpnFym1Qk/eaRjy1APPg==", + "dev": true + } + } + }, + "appium-espresso-driver": { + "version": "1.23.2", + "resolved": "https://registry.npmjs.org/appium-espresso-driver/-/appium-espresso-driver-1.23.2.tgz", + "integrity": "sha512-NY5AXM1Mo5iFOih8iXinLkuT00w3P+k0qWtkBphVc1z1u0x9dBW6CMdH9a1W25g3u/4yJZIAAdY7A4dyrCIpyw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.3", + "appium-adb": "^7.19.1", + "appium-android-driver": "^4.25.3", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.20.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.0", + "lodash": "^4.17.11", + "portscanner": "^2.1.1", + "request": "^2.88.0", + "request-promise": "^4.2.1", + "source-map-support": "^0.5.8", + "validate.js": "^0.13.0", + "yargs": "^15.0.1" + } + }, + "appium-fake-driver": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/appium-fake-driver/-/appium-fake-driver-0.9.0.tgz", + "integrity": "sha512-MwCqt1vz+bRidl9NRNcToJZostKEJQAzBizh9QyZ+5n3/N+OTBYCp5AD/pJw/MjF4Wl1u1Jhu2jFxsu+XaQpqA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.11.1", + "asyncbox": "^2.3.2", + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "source-map-support": "^0.5.5", + "xmldom": "^0.1.19", + "xpath": "0.0.27", + "yargs": "^15.0.1" + } + }, + "appium-flutter-driver": { + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/appium-flutter-driver/-/appium-flutter-driver-0.0.23.tgz", + "integrity": "sha512-yRZwfioaMpE2s9Av8pgv6hQkArsQ36KkrEgHaOk5uRRuTXbHSg0OB51Bm8xKdXvWYmA4DI6Oz4xWSTNjfdrJhw==", + "dev": true, + "requires": { + "appium-base-driver": "^5.0.0", + "appium-uiautomator2-driver": "^1.35.1", + "appium-xcuitest-driver": "^3.0.0", + "rpc-websockets": "^4.5.1" + } + }, + "appium-idb": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/appium-idb/-/appium-idb-0.4.1.tgz", + "integrity": "sha512-gMuZC/ndo4lGL2t/9sL+yyCGQVUV0rdpxgjvnuEdADA3GYCUFV/rUj2czJUhajUOhADGUP1Pibn0h3qtZuaBbQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.41.0", + "asyncbox": "^2.5.2", + "bluebird": "^3.1.1", + "lodash": "^4.0.0", + "shell-quote": "^1.6.1", + "source-map-support": "^0.5.5", + "teen_process": "^1.11.0" + }, + "dependencies": { + "appium-support": { + "version": "2.43.0", + "resolved": "https://registry.npmjs.org/appium-support/-/appium-support-2.43.0.tgz", + "integrity": "sha512-HELlIM6J0CI/ALHKbr8Z8TNjrnyw1QVdzLKCUX/l4Gw/MmaS4QvHNpuy3Bdd0MCxX/aw76q2F58HmCiwzHtAkg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "archiver": "^3.1.1", + "base64-stream": "^1.0.0", + "bluebird": "^3.5.1", + "bplist-creator": "^0", + "bplist-parser": "^0.2", + "extract-zip": "^1.6.0", + "glob": "^7.1.2", + "jimp": "^0.9.0", + "jsftp": "^2.1.2", + "klaw": "^3.0.0", + "lodash": "^4.2.1", + "md5-file": "^4.0.0", + "mjpeg-server": "^0.3.0", + "mkdirp": "^1.0.0", + "moment": "^2.24.0", + "mv": "^2.1.1", + "ncp": "^2.0.0", + "npmlog": "^4.1.2", + "plist": "^3.0.1", + "pluralize": "^8.0.0", + "pngjs": "^3.0.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "rimraf": "^3.0.0", + "sanitize-filename": "^1.6.1", + "semver": "^7.0.0", + "shell-quote": "^1.7.2", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1", + "uuid": "^7.0.2", + "which": "^2.0.0", + "yauzl": "^2.7.0" + } + }, + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "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" + } + } + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true + }, + "zip-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + } + } + } + }, + "appium-ios-device": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/appium-ios-device/-/appium-ios-device-1.5.0.tgz", + "integrity": "sha512-s05omp42+ObeyTI6SQ2HcommWiX3Y5Bfpvn1D1ftyl01u/qr9QLyDzBn47myYB80MeDcwaR/iRADDLlXkpR4Dg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.35.0", + "bluebird": "^3.1.1", + "lodash": "^4.17.15", + "semver": "^7.0.0", + "source-map-support": "^0.5.5" + } + }, + "appium-ios-driver": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/appium-ios-driver/-/appium-ios-driver-4.6.0.tgz", + "integrity": "sha512-pEE8ZJYcmB3CLs+EqlAsFOJCsJ6v6K1m//UXIU8r29w2PHs9d4LmFXvOESUBK7CIrlJmwCcr6eAZhtsr0H1fuw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-ios-simulator": "^3.9.0", + "appium-remote-debugger": "^4.1.0", + "appium-support": "^2.25.0", + "appium-xcode": "^3.1.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.1", + "colors": "^1.1.2", + "js2xmlparser2": "^0.2.0", + "lodash": "^4.13.1", + "moment": "^2.24.0", + "moment-timezone": "^0.5.26", + "node-idevice": "^0.1.6", + "node-simctl": "^5.0.0", + "pem": "^1.8.3", + "portfinder": "^1.0.13", + "request": "^2.79.0", + "request-promise": "^4.1.1", + "safari-launcher": "^2.0.5", + "source-map-support": "^0.5.5", + "teen_process": "^1.6.0", + "through": "^2.3.8", + "uuid-js": "^0.7.5", + "xmldom": "^0.2.0", + "xpath": "^0.0.24", + "yargs": "^15.0.1" + }, + "dependencies": { + "appium-remote-debugger": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-4.5.0.tgz", + "integrity": "sha512-8UhFOQJvSCHSuWloGe+FOeIObIp6wzc5oaXV8vVRANn8rqZlQl2j4dgelQcA1DoE54Lphy00Bo99M7qDsKkF7w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^4.0.0", + "appium-support": "^2.28.0", + "asyncbox": "^2.5.2", + "bluebird": "^3.4.7", + "bufferpack": "0.0.6", + "es6-error": "^4.1.1", + "lodash": "^4.17.11", + "request": "^2.79.0", + "request-promise": "^4.1.1", + "source-map-support": "^0.5.5", + "ws": "^7.0.0" + }, + "dependencies": { + "appium-base-driver": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/appium-base-driver/-/appium-base-driver-4.5.1.tgz", + "integrity": "sha512-g7sI5mzmGdZhIFg3+A5f9ewtihYKS0b33wZWbN6R/PYYTEmXbNhFPGfVqzoAzFANuLjlTlvEEsqGcUtjrMO2Bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.33.1", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.3", + "body-parser": "^1.18.2", + "colors": "^1.1.2", + "es6-error": "^4.1.1", + "express": "^4.16.2", + "http-status-codes": "^1.3.0", + "lodash": "^4.0.0", + "lru-cache": "^5.0.0", + "method-override": "^3.0.0", + "morgan": "^1.9.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "sanitize-filename": "^1.6.1", + "serve-favicon": "^2.4.5", + "source-map-support": "^0.5.5", + "uuid-js": "^0.7.5", + "validate.js": "^0.13.0", + "webdriverio": "^5.10.9", + "ws": "^7.0.0" + } + } + } + }, + "node-simctl": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-5.3.0.tgz", + "integrity": "sha512-5EJPsorg+ZLxeLk6Cc5Q3hI4WcWkWSWkqQnJEJf3DrM9UekGvpgOUE8uZtr8dTtY/GZCsI30Ksusqm+zGq3NsA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.37.0", + "appium-xcode": "^3.8.0", + "asyncbox": "^2.3.1", + "lodash": "^4.2.1", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1" + } + }, + "xmldom": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.2.1.tgz", + "integrity": "sha512-kXXiYvmblIgEemGeB75y97FyaZavx6SQhGppLw5TKWAD2Wd0KAly0g23eVLh17YcpxZpnFym1Qk/eaRjy1APPg==", + "dev": true + }, + "xpath": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.24.tgz", + "integrity": "sha1-Gt4WLhzFI8jTn8fQavwW6iFvKfs=", + "dev": true + } + } + }, + "appium-ios-simulator": { + "version": "3.20.0", + "resolved": "https://registry.npmjs.org/appium-ios-simulator/-/appium-ios-simulator-3.20.0.tgz", + "integrity": "sha512-RbnQrlCeRNhkftXkt97pQARfVNeCxp6v2v6RaZV1ZU5D2HrY5lEaw7I65wqUxn75w6hywiz23+y//6+OaLnfog==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.39.0", + "appium-xcode": "^3.1.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.1", + "fkill": "^7.0.0", + "lodash": "^4.2.1", + "node-simctl": "^6.1.0", + "openssl-wrapper": "^0.3.4", + "semver": "^7.0.0", + "shell-quote": "^1.6.1", + "source-map-support": "^0.5.3", + "teen_process": "^1.3.0" + } + }, + "appium-mac-driver": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/appium-mac-driver/-/appium-mac-driver-1.10.0.tgz", + "integrity": "sha512-+isEfxtE7FQJr418udxfHBp9OU/S/tEjG8BbMgGjcHi8TE/4B78KzQZxgewGPRKraNLFo/58by8PqgWsS6sLtA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.36.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "source-map-support": "^0.5.5", + "teen_process": "^1.15.0", + "yargs": "^15.0.1" + } + }, + "appium-remote-debugger": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/appium-remote-debugger/-/appium-remote-debugger-8.9.0.tgz", + "integrity": "sha512-GSq6luI9Us6urS7K8c90R13/MU1T95GGKNBV4t+IPw7cvDcm5fpsnqKX77xrf+7z/n4claUk/8m6yce9sSskqQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-ios-device": "^1.2.1", + "appium-support": "^2.41.0", + "async-lock": "^1.2.2", + "asyncbox": "^2.6.0", + "bluebird": "^3.4.7", + "lodash": "^4.17.11", + "source-map-support": "^0.5.5" + }, + "dependencies": { + "appium-support": { + "version": "2.43.0", + "resolved": "https://registry.npmjs.org/appium-support/-/appium-support-2.43.0.tgz", + "integrity": "sha512-HELlIM6J0CI/ALHKbr8Z8TNjrnyw1QVdzLKCUX/l4Gw/MmaS4QvHNpuy3Bdd0MCxX/aw76q2F58HmCiwzHtAkg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "archiver": "^3.1.1", + "base64-stream": "^1.0.0", + "bluebird": "^3.5.1", + "bplist-creator": "^0", + "bplist-parser": "^0.2", + "extract-zip": "^1.6.0", + "glob": "^7.1.2", + "jimp": "^0.9.0", + "jsftp": "^2.1.2", + "klaw": "^3.0.0", + "lodash": "^4.2.1", + "md5-file": "^4.0.0", + "mjpeg-server": "^0.3.0", + "mkdirp": "^1.0.0", + "moment": "^2.24.0", + "mv": "^2.1.1", + "ncp": "^2.0.0", + "npmlog": "^4.1.2", + "plist": "^3.0.1", + "pluralize": "^8.0.0", + "pngjs": "^3.0.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "rimraf": "^3.0.0", + "sanitize-filename": "^1.6.1", + "semver": "^7.0.0", + "shell-quote": "^1.7.2", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1", + "uuid": "^7.0.2", + "which": "^2.0.0", + "yauzl": "^2.7.0" + } + }, + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "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" + } + } + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true + }, + "zip-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + } + } + } + }, + "appium-sdb": { + "version": "1.0.1-beta", + "resolved": "https://registry.npmjs.org/appium-sdb/-/appium-sdb-1.0.1-beta.tgz", + "integrity": "sha512-vTQv52JjlKLc/D/iJuJeFeZW0DYxSo9whF2DXu5UC3+Y1qUIHX91h2UBmNzs5NSbvIJ63lGWi7vMVnu6IhMdsQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.4.0", + "asyncbox": "^2.3.1", + "lodash": "^4.17.11", + "source-map-support": "^0.5.9", + "teen_process": "^1.3.1" + } + }, + "appium-support": { + "version": "2.39.1", + "resolved": "https://registry.npmjs.org/appium-support/-/appium-support-2.39.1.tgz", + "integrity": "sha512-FKDvP4pkt9N2KRzf5V+w8nNquoEIdNreOzM1OuSj4TxtG7S6Ix2LbXqjXjN4/nZKC5VEz1Vh+IQrSZ2uQv6MZg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "archiver": "^1.3.0", + "bluebird": "^3.5.1", + "bplist-creator": "^0", + "bplist-parser": "^0.2", + "extract-zip": "^1.6.0", + "glob": "^7.1.2", + "jimp": "^0.9.0", + "jsftp": "^2.1.2", + "klaw": "^3.0.0", + "lodash": "^4.2.1", + "md5-file": "^4.0.0", + "mjpeg-server": "^0.3.0", + "mkdirp": "^1.0.0", + "moment": "^2.24.0", + "mv": "^2.1.1", + "ncp": "^2.0.0", + "npmlog": "^4.1.2", + "plist": "^3.0.1", + "pluralize": "^8.0.0", + "pngjs": "^3.0.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "rimraf": "^3.0.0", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1", + "which": "^2.0.0", + "yauzl": "^2.7.0" + } + }, + "appium-tizen-driver": { + "version": "1.1.1-beta.4", + "resolved": "https://registry.npmjs.org/appium-tizen-driver/-/appium-tizen-driver-1.1.1-beta.4.tgz", + "integrity": "sha512-lDOxwEAXUaoYwVMznFwYkHodceDahBNj2ImIGVDwSefEmEfR+1pZKvp1+SIeLRJfelsqVjnX8HQj8zRIP6lhKg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^3.0.0", + "appium-sdb": "^1.0.1-beta", + "appium-support": "^2.8.0", + "asyncbox": "^2.0.4", + "bluebird": "^3.4.7", + "fancy-log": "^1.3.2", + "jimp": "^0.5.3", + "lodash": "^4.17.9", + "source-map-support": "^0.5.9", + "teen_process": "^1.9.0", + "yargs": "^12.0.2" + }, + "dependencies": { + "@jimp/bmp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/bmp/-/bmp-0.5.4.tgz", + "integrity": "sha512-P/ezH1FuoM3FwS0Dm2ZGkph4x5/rPBzFLEZor7KQkmGUnYEIEG4o0BUcAWFmJOp2HgzbT6O2SfrpJNBOcVACzQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "bmp-js": "^0.1.0", + "core-js": "^2.5.7" + } + }, + "@jimp/core": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/core/-/core-0.5.4.tgz", + "integrity": "sha512-n3uvHy2ndUKItmbhnRO8xmU8J6KR+v6CQxO9sbeUDpSc3VXc1PkqrA8ZsCVFCjnDFcGBXL+MJeCTyQzq5W9Crw==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "any-base": "^1.1.0", + "buffer": "^5.2.0", + "core-js": "^2.5.7", + "exif-parser": "^0.1.12", + "file-type": "^9.0.0", + "load-bmfont": "^1.3.1", + "mkdirp": "0.5.1", + "phin": "^2.9.1", + "pixelmatch": "^4.0.2", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/custom": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.5.4.tgz", + "integrity": "sha512-tLfyJoyouDl2J3RPFGfDzTtE+4S8ljqJUmLzy/cmx1n7+xS5TpLPdPskp7UaeAfNTqdF4CNAm94KYoxTZdj2mg==", + "dev": true, + "requires": { + "@jimp/core": "^0.5.4", + "core-js": "^2.5.7" + } + }, + "@jimp/gif": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/gif/-/gif-0.5.0.tgz", + "integrity": "sha512-HVB4c7b8r/yCpjhCjVNPRFLuujTav5UPmcQcFJjU6aIxmne6e29rAjRJEv3UMamHDGSu/96PzOsPZBO5U+ZGww==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7", + "omggif": "^1.0.9" + } + }, + "@jimp/jpeg": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/jpeg/-/jpeg-0.5.4.tgz", + "integrity": "sha512-YaPWm+YSGCThNE/jLMckM3Qs6uaMxd/VsHOnEaqu5tGA4GFbfVaWHjKqkNGAFuiNV+HdgKlNcCOF3of+elvzqQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7", + "jpeg-js": "^0.3.4" + } + }, + "@jimp/plugin-blit": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blit/-/plugin-blit-0.5.4.tgz", + "integrity": "sha512-WqDYOugv76hF1wnKy7+xPGf9PUbcm9vPW28/jHWn1hjbb2GnusJ2fVEFad76J/1SPfhrQ2Uebf2QCWJuLmOqZg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-blur": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-blur/-/plugin-blur-0.5.0.tgz", + "integrity": "sha512-5k0PXCA1RTJdITL7yMAyZ5tGQjKLHqFvwdXj/PCoBo5PuMyr0x6qfxmQEySixGk/ZHdDxMi80vYxHdKHjNNgjg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-color": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@jimp/plugin-color/-/plugin-color-0.5.5.tgz", + "integrity": "sha512-hWeOqNCmLguGYLhSvBrpfCvlijsMEVaLZAOod62s1rzWnujozyKOzm2eZe+W3To6mHbp5RGJNVrIwHBWMab4ug==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7", + "tinycolor2": "^1.4.1" + } + }, + "@jimp/plugin-contain": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-contain/-/plugin-contain-0.5.4.tgz", + "integrity": "sha512-8YJh4FI3S69unri0nJsWeqVLeVGA77N2R0Ws16iSuCCD/5UnWd9FeWRrSbKuidBG6TdMBaG2KUqSYZeHeH9GOQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-cover": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-cover/-/plugin-cover-0.5.4.tgz", + "integrity": "sha512-2Rur7b44WiDDgizUI2M2uYWc1RmfhU5KjKS1xXruobjQ0tXkf5xlrPXSushq0hB6Ne0Ss6wv0+/6eQ8WeGHU2w==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-crop": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-crop/-/plugin-crop-0.5.4.tgz", + "integrity": "sha512-6t0rqn4VazquGk48tO6hFBrQ+nkvC+A1RnR6UM/m8ZtG2/yjpwF0MXcpgJI1Fb+a4Ug7BY1fu2GPcZOhnAVK/g==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-displace": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-displace/-/plugin-displace-0.5.0.tgz", + "integrity": "sha512-Bec7SQvnmKia4hOXEDjeNVx7vo/1bWqjuV6NO8xbNQcAO3gaCl91c9FjMDhsfAVb0Ou6imhbIuFPrLxorXsecQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-dither": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-dither/-/plugin-dither-0.5.0.tgz", + "integrity": "sha512-We2WJQsD/Lm8oqBFp/vUv9/5r2avyenL+wNNu/s2b1HqA5O4sPGrjHy9K6vIov0NroQGCQ3bNznLkTmjiHKBcg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-flip": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-flip/-/plugin-flip-0.5.0.tgz", + "integrity": "sha512-D/ehBQxLMNR7oNd80KXo4tnSET5zEm5mR70khYOTtTlfti/DlLp3qOdjPOzfLyAdqO7Ly4qCaXrIsnia+pfPrA==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-gaussian": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-gaussian/-/plugin-gaussian-0.5.0.tgz", + "integrity": "sha512-Ln4kgxblv0/YzLBDb/J8DYPLhDzKH87Y8yHh5UKv3H+LPKnLaEG3L4iKTE9ivvdocnjmrtTFMYcWv2ERSPeHcg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-invert": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-invert/-/plugin-invert-0.5.0.tgz", + "integrity": "sha512-/vyKeIi3T7puf+8ruWovTjzDC585EnTwJ+lGOOUYiNPsdn4JDFe1B3xd+Ayv9aCQbXDIlPElZaM9vd/+wqDiIQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-mask": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-mask/-/plugin-mask-0.5.4.tgz", + "integrity": "sha512-mUJ04pCrUWaJGXPjgoVbzhIQB8cVobj2ZEFlGO3BEAjyylYMrdJlNlsER8dd7UuJ2L/a4ocWtFDdsnuicnBghQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-normalize": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-normalize/-/plugin-normalize-0.5.4.tgz", + "integrity": "sha512-Q5W0oEz9wxsjuhvHAJynI/OqXZcmqEAuRONQId7Aw5ulCXSOg9C4y2a67EO7aZAt55T+zMVxI9UpVUpzVvO6hw==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-print": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-print/-/plugin-print-0.5.4.tgz", + "integrity": "sha512-DOZr5TY9WyMWFBD37oz7KpTEBVioFIHQF/gH5b3O5jjFyj4JPMkw7k3kVBve9lIrzIYrvLqe0wH59vyAwpeEFg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7", + "load-bmfont": "^1.4.0" + } + }, + "@jimp/plugin-resize": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-resize/-/plugin-resize-0.5.4.tgz", + "integrity": "sha512-lXNprNAT0QY1D1vG/1x6urUTlWuZe2dfL29P81ApW2Yfcio471+oqo45moX5FLS0q24xU600g7cHGf2/TzqSfA==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-rotate": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/plugin-rotate/-/plugin-rotate-0.5.4.tgz", + "integrity": "sha512-SIdUpMc8clObMchy8TnjgHgcXEQM992z5KavgiuOnCuBlsmSHtE3MrXTOyMW0Dn3gqapV9Y5vygrLm/BVtCCsg==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugin-scale": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/plugin-scale/-/plugin-scale-0.5.0.tgz", + "integrity": "sha512-5InIOr3cNtrS5aQ/uaosNf28qLLc0InpNGKFmGFTv8oqZqLch6PtDTjDBZ1GGWsPdA/ljy4Qyy7mJO1QBmgQeQ==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7" + } + }, + "@jimp/plugins": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@jimp/plugins/-/plugins-0.5.5.tgz", + "integrity": "sha512-9oF6LbSM/K7YkFCcxaPaD8NUkL/ZY8vT8NIGfQ/NpX+tKQtcsLHcRavHpUC+M1xXShv/QGx9OdBV/jgiu82QYg==", + "dev": true, + "requires": { + "@jimp/plugin-blit": "^0.5.4", + "@jimp/plugin-blur": "^0.5.0", + "@jimp/plugin-color": "^0.5.5", + "@jimp/plugin-contain": "^0.5.4", + "@jimp/plugin-cover": "^0.5.4", + "@jimp/plugin-crop": "^0.5.4", + "@jimp/plugin-displace": "^0.5.0", + "@jimp/plugin-dither": "^0.5.0", + "@jimp/plugin-flip": "^0.5.0", + "@jimp/plugin-gaussian": "^0.5.0", + "@jimp/plugin-invert": "^0.5.0", + "@jimp/plugin-mask": "^0.5.4", + "@jimp/plugin-normalize": "^0.5.4", + "@jimp/plugin-print": "^0.5.4", + "@jimp/plugin-resize": "^0.5.4", + "@jimp/plugin-rotate": "^0.5.4", + "@jimp/plugin-scale": "^0.5.0", + "core-js": "^2.5.7", + "timm": "^1.6.1" + } + }, + "@jimp/png": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/png/-/png-0.5.4.tgz", + "integrity": "sha512-J2NU7368zihF1HUZdmpXsL/Hhyf+I3ubmK+6Uz3Uoyvtk1VS7dO3L0io6fJQutfWmPZ4bvu6Ry022oHjbi6QCA==", + "dev": true, + "requires": { + "@jimp/utils": "^0.5.0", + "core-js": "^2.5.7", + "pngjs": "^3.3.3" + } + }, + "@jimp/tiff": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/tiff/-/tiff-0.5.4.tgz", + "integrity": "sha512-hr7Zq3eWjAZ+itSwuAObIWMRNv7oHVM3xuEDC2ouP7HfE7woBtyhCyfA7u12KlgtM57gKWeogXqTlewRGVzx6g==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "utif": "^2.0.1" + } + }, + "@jimp/types": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@jimp/types/-/types-0.5.4.tgz", + "integrity": "sha512-nbZXM6TsdpnYHIBd8ZuoxGpvmxc2SqiggY30/bhOP/VJQoDBzm2v/20Ywz5M0snpIK2SdYG52eZPNjfjqUP39w==", + "dev": true, + "requires": { + "@jimp/bmp": "^0.5.4", + "@jimp/gif": "^0.5.0", + "@jimp/jpeg": "^0.5.4", + "@jimp/png": "^0.5.4", + "@jimp/tiff": "^0.5.4", + "core-js": "^2.5.7", + "timm": "^1.6.1" + } + }, + "@jimp/utils": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@jimp/utils/-/utils-0.5.0.tgz", + "integrity": "sha512-7H9RFVU+Li2XmEko0GGyzy7m7JjSc7qa+m8l3fUzYg2GtwASApjKF/LSG2AUQCUmDKFLdfIEVjxvKvZUJFEmpw==", + "dev": true, + "requires": { + "core-js": "^2.5.7" + } + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "appium-base-driver": { + "version": "3.21.2", + "resolved": "https://registry.npmjs.org/appium-base-driver/-/appium-base-driver-3.21.2.tgz", + "integrity": "sha512-cA7adQK63OiZzCvuHfQ4jKcT3tFogo8dfbgbgS4xpcmIEXgUZd/6MHicQG4NdfzbJpojQXNSeeCkRvlpksQrOQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.24.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.3", + "body-parser": "^1.18.2", + "colors": "^1.1.2", + "es6-error": "^4.1.1", + "express": "^4.16.2", + "http-status-codes": "^1.3.0", + "lodash": "^4.0.0", + "lru-cache": "^5.0.0", + "method-override": "^3.0.0", + "morgan": "^1.9.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "sanitize-filename": "^1.6.1", + "serve-favicon": "^2.4.5", + "source-map-support": "^0.5.5", + "uuid-js": "^0.7.5", + "validate.js": "^0.13.0", + "webdriverio": "^5.10.9", + "ws": "^7.0.0" + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "jimp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.5.6.tgz", + "integrity": "sha512-H0nHTu6KgAgQzDxa38ew2dXbnRzKm1w5uEyhMIxqwCQVjwgarOjjkV/avbNLxfxRHAFaNp4rGIc/qm8P+uhX9A==", + "dev": true, + "requires": { + "@babel/polyfill": "^7.0.0", + "@jimp/custom": "^0.5.4", + "@jimp/plugins": "^0.5.5", + "@jimp/types": "^0.5.4", + "core-js": "^2.5.7" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "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" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "appium-uiautomator2-driver": { + "version": "1.44.2", + "resolved": "https://registry.npmjs.org/appium-uiautomator2-driver/-/appium-uiautomator2-driver-1.44.2.tgz", + "integrity": "sha512-xnfuQjXLjZP8XzUfTpnFk6nd6Qo5ixCLWK9wD10lPcmsYiqdHT8gSySaS5RglqYyCKC5mfQPwqKUMzSpCHKbig==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-adb": "^7.20.0", + "appium-android-driver": "^4.25.0", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.37.0", + "appium-uiautomator2-server": "^4.4.0", + "async-lock": "^1.2.2", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "portscanner": "2.2.0", + "request": "^2.81.0", + "request-promise": "^4.1.1", + "source-map-support": "^0.5.5", + "teen_process": "^1.3.1", + "yargs": "^14.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.2.tgz", + "integrity": "sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.0" + } + }, + "yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "appium-uiautomator2-server": { + "version": "4.5.5", + "resolved": "https://registry.npmjs.org/appium-uiautomator2-server/-/appium-uiautomator2-server-4.5.5.tgz", + "integrity": "sha512-VtgdvOoC7jElOV5b+j0A3pB8c8D3Kll7b0EW2UR0+3Qs3gi0Xkzgouj/rtYv51elGeo/4NgmQ0hrQGqsEwIcfw==", + "dev": true + }, + "appium-webdriveragent": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-2.14.2.tgz", + "integrity": "sha512-C5/0Gh7rRPuvzYIqa2eVZX5RNP8wUzc4JdUhADS034rRCQQuShJghf3ZRSepottDGmPR3vMSau5sh0umtLWcaA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.2", + "appium-ios-simulator": "^3.14.0", + "appium-support": "^2.37.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.5.3", + "bluebird": "^3.5.5", + "lodash": "^4.17.11", + "node-simctl": "^6.0.2", + "request": "^2.79.0", + "request-promise": "^4.1.1", + "source-map-support": "^0.5.12", + "stream-equal": "^1.1.1", + "teen_process": "^1.14.1" + } + }, + "appium-windows-driver": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/appium-windows-driver/-/appium-windows-driver-1.8.0.tgz", + "integrity": "sha512-z1orUQK60Pi4he+5CJ9gj3WTUYXenyk39NEsLxiuqp9uxb3DikgZ399chRmYkqg/dIQuIUKRhZmFz+VtV2Gj1g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.0.0", + "appium-support": "^2.5.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.1", + "lodash": "^4.6.1", + "request-promise": "^4.2.2", + "source-map-support": "^0.5.5", + "teen_process": "^1.7.0", + "yargs": "^15.0.1" + } + }, + "appium-xcode": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/appium-xcode/-/appium-xcode-3.10.0.tgz", + "integrity": "sha512-6Db49w2UjcdMn96nUMS/EGKE/6r/sgIPcw8mr9+e4Oeb5rvROAm/VeIWmwnov3uk2JG3SGkLTQRB9tROKKRDgw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.4.0", + "asyncbox": "^2.3.0", + "lodash": "^4.17.4", + "plist": "^3.0.1", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.3.0" + } + }, + "appium-xcuitest-driver": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/appium-xcuitest-driver/-/appium-xcuitest-driver-3.22.0.tgz", + "integrity": "sha512-hhjRz8EwUBBu1V0k9CwRN5CmQwreckEjnx7DFDjX3XQd/jfCBdNp5yKxqhjYveivvhiazPLTi3uoDy/aSs7Kpw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-base-driver": "^5.1.0", + "appium-idb": "^0", + "appium-ios-device": "^1.5.0", + "appium-ios-driver": "^4.6.0", + "appium-ios-simulator": "^3.20.0", + "appium-remote-debugger": "^8.8.1", + "appium-support": "^2.41.0", + "appium-webdriveragent": "^2.14.1", + "appium-xcode": "^3.8.0", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.1.1", + "js2xmlparser2": "^0.2.0", + "lodash": "^4.17.10", + "moment": "^2.24.0", + "moment-timezone": "0.5.28", + "node-simctl": "^6.1.0", + "portscanner": "2.2.0", + "request": "^2.79.0", + "request-promise": "^4.1.1", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.14.0", + "ws": "^7.0.0", + "xmldom": "^0.3.0", + "yargs": "^15.0.1" + }, + "dependencies": { + "appium-support": { + "version": "2.43.0", + "resolved": "https://registry.npmjs.org/appium-support/-/appium-support-2.43.0.tgz", + "integrity": "sha512-HELlIM6J0CI/ALHKbr8Z8TNjrnyw1QVdzLKCUX/l4Gw/MmaS4QvHNpuy3Bdd0MCxX/aw76q2F58HmCiwzHtAkg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "archiver": "^3.1.1", + "base64-stream": "^1.0.0", + "bluebird": "^3.5.1", + "bplist-creator": "^0", + "bplist-parser": "^0.2", + "extract-zip": "^1.6.0", + "glob": "^7.1.2", + "jimp": "^0.9.0", + "jsftp": "^2.1.2", + "klaw": "^3.0.0", + "lodash": "^4.2.1", + "md5-file": "^4.0.0", + "mjpeg-server": "^0.3.0", + "mkdirp": "^1.0.0", + "moment": "^2.24.0", + "mv": "^2.1.1", + "ncp": "^2.0.0", + "npmlog": "^4.1.2", + "plist": "^3.0.1", + "pluralize": "^8.0.0", + "pngjs": "^3.0.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "rimraf": "^3.0.0", + "sanitize-filename": "^1.6.1", + "semver": "^7.0.0", + "shell-quote": "^1.7.2", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1", + "uuid": "^7.0.2", + "which": "^2.0.0", + "yauzl": "^2.7.0" + } + }, + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "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" + } + } + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true + }, + "xmldom": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.3.0.tgz", + "integrity": "sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g==", + "dev": true + }, + "zip-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + } + } + } + }, + "appium-youiengine-driver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/appium-youiengine-driver/-/appium-youiengine-driver-1.2.3.tgz", + "integrity": "sha512-N0isiXzcGn1RCHjQPDDewrXHgBurweaGRD0pGIAU9aIt94YsXBs3V8VYtRasx1iYjD/wem8YCLpX8ZOT87MkGg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-android-driver": "^4.0.0", + "appium-base-driver": "^4.x", + "appium-ios-driver": "^4.3.0", + "appium-ios-simulator": "3.x", + "appium-mac-driver": "1.x", + "appium-support": "2.x", + "appium-xcuitest-driver": "^3.0.0", + "asyncbox": "2.x", + "bluebird": "3.x", + "lodash": "^4.17.11", + "node-simctl": "^5.0.2", + "selenium-webdriver": "3.x", + "shelljs": "0.8.x", + "source-map-support": "^0.5.12", + "teen_process": "^1.15.0" + }, + "dependencies": { + "appium-base-driver": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/appium-base-driver/-/appium-base-driver-4.5.1.tgz", + "integrity": "sha512-g7sI5mzmGdZhIFg3+A5f9ewtihYKS0b33wZWbN6R/PYYTEmXbNhFPGfVqzoAzFANuLjlTlvEEsqGcUtjrMO2Bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.33.1", + "async-lock": "^1.0.0", + "asyncbox": "^2.3.1", + "bluebird": "^3.5.3", + "body-parser": "^1.18.2", + "colors": "^1.1.2", + "es6-error": "^4.1.1", + "express": "^4.16.2", + "http-status-codes": "^1.3.0", + "lodash": "^4.0.0", + "lru-cache": "^5.0.0", + "method-override": "^3.0.0", + "morgan": "^1.9.0", + "request": "^2.83.0", + "request-promise": "^4.2.2", + "sanitize-filename": "^1.6.1", + "serve-favicon": "^2.4.5", + "source-map-support": "^0.5.5", + "uuid-js": "^0.7.5", + "validate.js": "^0.13.0", + "webdriverio": "^5.10.9", + "ws": "^7.0.0" + } + }, + "node-simctl": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-5.3.0.tgz", + "integrity": "sha512-5EJPsorg+ZLxeLk6Cc5Q3hI4WcWkWSWkqQnJEJf3DrM9UekGvpgOUE8uZtr8dTtY/GZCsI30Ksusqm+zGq3NsA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.37.0", + "appium-xcode": "^3.8.0", + "asyncbox": "^2.3.1", + "lodash": "^4.2.1", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "archiver": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz", + "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "async": "^2.0.0", + "buffer-crc32": "^0.2.1", + "glob": "^7.0.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0", + "tar-stream": "^1.5.0", + "walkdir": "^0.0.11", + "zip-stream": "^1.1.0" + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "dev": true, + "requires": { + "glob": "^7.0.0", + "graceful-fs": "^4.1.0", + "lazystream": "^1.0.0", + "lodash": "^4.8.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-args": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/assert-args/-/assert-args-1.2.1.tgz", + "integrity": "sha1-QEEDoUUqMv53iYgR5U5ZCoqTc70=", + "dev": true, + "requires": { + "101": "^1.2.0", + "compound-subject": "0.0.1", + "debug": "^2.2.0", + "get-prototype-of": "0.0.0", + "is-capitalized": "^1.0.0", + "is-class": "0.0.4" + }, + "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 + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "dev": true, + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "async-lock": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.2.2.tgz", + "integrity": "sha512-uczz62z2fMWOFbyo6rG4NlV2SdxugJT6sZA2QcfB1XaSjEiOh8CuOb/TttyMnYQCda6nkWecJe465tGQDPJiKw==", + "dev": true + }, + "asyncbox": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/asyncbox/-/asyncbox-2.6.0.tgz", + "integrity": "sha512-x9RDH0Dk4qZIGHQc9KbnDrUnaEbtWJW2DbuSElOFOQ2ppGsT1eFEDsiconZPpRGMW6+Uv724FYaBc8SUvyWVzA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.1", + "es6-mapify": "^1.1.0", + "lodash": "^4.17.4", + "source-map-support": "^0.5.5" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "dev": true + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "base64-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-1.0.0.tgz", + "integrity": "sha512-BQQZftaO48FcE1Kof9CmXMFaAdqkcNorgc8CxesZv9nMbbTF1EFyQe89UOuh//QMmdtfUDXyO8rgUalemL5ODA==", + "dev": true + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true + }, + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bmp-js": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz", + "integrity": "sha1-4Fpj95amwf8l9Hcex62twUjAcjM=", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "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 + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "bplist-creator": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", + "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", + "dev": true, + "requires": { + "stream-buffers": "~2.2.0" + } + }, + "bplist-parser": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", + "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", + "dev": true, + "requires": { + "big-integer": "^1.6.44" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "buffer": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.5.0.tgz", + "integrity": "sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-equal": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz", + "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "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 + }, + "bufferpack": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/bufferpack/-/bufferpack-0.0.6.tgz", + "integrity": "sha1-+z2HOKDh5OA7z/mfmnX57Bip1z4=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "circular-json": { + "version": "0.5.9", + "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", + "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==", + "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 + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.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 + }, + "is-fullwidth-code-point": { + "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 + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "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": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/color/-/color-3.0.0.tgz", + "integrity": "sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + } + } + }, + "color-convert": { + "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.4" + } + }, + "color-name": { + "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 + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colornames": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/colornames/-/colornames-1.1.1.tgz", + "integrity": "sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y=", + "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 + }, + "colorspace": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.2.tgz", + "integrity": "sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ==", + "dev": true, + "requires": { + "color": "3.0.x", + "text-hex": "1.0.x" + } + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "compound-subject": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/compound-subject/-/compound-subject-0.0.1.tgz", + "integrity": "sha1-JxVUaYoVrmCLHfyv0wt7oeqJLEs=", + "dev": true + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.1", + "crc32-stream": "^2.0.0", + "normalize-path": "^2.0.0", + "readable-stream": "^2.0.0" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "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" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "dev": true, + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "core-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.4.tgz", + "integrity": "sha512-4paDGScNgZP2IXXilaffL9X7968RuvwlkK3xWtZRVqgd8SYNiVKRJvkFd1aqqEuPfN7E68ZHEp9hDj6lHj4Hyw==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^2.0.0" + } + }, + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "css-value": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz", + "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "diagnostics": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.1.tgz", + "integrity": "sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ==", + "dev": true, + "requires": { + "colorspace": "1.1.x", + "enabled": "1.0.x", + "kuler": "1.0.x" + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=", + "dev": true + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "dev": true, + "requires": { + "shimmer": "^1.2.0" + } + }, + "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 + }, + "enabled": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", + "integrity": "sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M=", + "dev": true, + "requires": { + "env-variable": "0.0.x" + } + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "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" + } + }, + "env-variable": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz", + "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg==", + "dev": true + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "es6-mapify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es6-mapify/-/es6-mapify-1.2.0.tgz", + "integrity": "sha512-b4QYXTO1HD0MMFs+JtYrQEaynlyuEInBF3anGQK11rQ45akiIBs+3YUyTBq9FLzM7rD5P2xAglEOXz9gcdmdIw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0" + } + }, + "es6-promisify": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.0.2.tgz", + "integrity": "sha512-eO6vFm0JvqGzjWIQA6QVKjxpmELfhWbDUWHm1rPfIbn55mhKPiAa5xpLmQWJrNa629ZIeQ8ZvMAi13kvrjK6Mg==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", + "dev": true + }, + "execa": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.0.tgz", + "integrity": "sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA==", + "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" + } + }, + "exif-parser": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz", + "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=", + "dev": true + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "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 + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "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=", + "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" + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "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" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "dev": true, + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-safe-stringify": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", + "dev": true + }, + "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" + } + }, + "fecha": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", + "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==", + "dev": true + }, + "file-type": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-9.0.0.tgz", + "integrity": "sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==", + "dev": true + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "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 + } + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", + "dev": true + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fkill": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/fkill/-/fkill-7.0.0.tgz", + "integrity": "sha512-i61SqvPdfCxl1/VQulh9SXrC+4dudCtINzTHbKaEx3Jr0kD9SvxKDeXzej7Saurnj3al/jMJwQnsUc62VrBMHQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0", + "arrify": "^2.0.1", + "execa": "^4.0.0", + "pid-from-port": "^1.1.3", + "process-exists": "^4.0.0", + "ps-list": "^7.0.0", + "taskkill": "^3.0.0" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "ftp-response-parser": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ftp-response-parser/-/ftp-response-parser-1.0.1.tgz", + "integrity": "sha1-O50z+O3V+45HALj3eMRi5bFYH4k=", + "dev": true, + "requires": { + "readable-stream": "^1.0.31" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-prototype-of": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/get-prototype-of/-/get-prototype-of-0.0.0.tgz", + "integrity": "sha1-mHcr0QcW0W3rSzIlFsRp78oorEQ=", + "dev": true + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", + "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", + "dev": true, + "requires": { + "min-document": "^2.19.0", + "process": "~0.5.1" + } + }, + "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==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "http-status-codes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-1.4.0.tgz", + "integrity": "sha512-JrT3ua+WgH8zBD3HEJYbeEgnuQaAnUeRRko/YojPAJjGmIfGD3KPU/asLdsLwKjfxOmQe5nXMQ0pt/7MyapVbQ==", + "dev": true + }, + "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 + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "indent-string": { + "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", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "io.appium.settings": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/io.appium.settings/-/io.appium.settings-3.1.0.tgz", + "integrity": "sha512-s3OqMAD1CMTvYLLTijH/u36DLR6neqPxL7q9cD7qzEYycj8E7UzmvYg2amLf//xPSeCNjGpPbuVlk+ug29jSnQ==", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-capitalized": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-capitalized/-/is-capitalized-1.0.0.tgz", + "integrity": "sha1-TIRktNkdPk7rRIid0s2PGwrEwTY=", + "dev": true + }, + "is-class": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/is-class/-/is-class-0.0.4.tgz", + "integrity": "sha1-4FdFFwW7NOOePjNZjJOpg3KWtzY=", + "dev": true + }, + "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" + } + }, + "is-function": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", + "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", + "dev": true + }, + "is-number-like": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/is-number-like/-/is-number-like-1.0.8.tgz", + "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", + "dev": true, + "requires": { + "lodash.isfinite": "^3.3.2" + } + }, + "is-stream": { + "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": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jimp": { + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.9.5.tgz", + "integrity": "sha512-gjrzz+lT4In7shmP4LV1o/dfL0btnh4W9F5jPCXA6Qw4uEAF8+8GDwAR69hbUQCZH7R5KoCtq81tpfzydoJtSQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.7.2", + "@jimp/custom": "^0.9.5", + "@jimp/plugins": "^0.9.5", + "@jimp/types": "^0.9.5", + "core-js": "^3.4.1", + "regenerator-runtime": "^0.13.3" + } + }, + "jpeg-js": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.7.tgz", + "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==", + "dev": true + }, + "js2xmlparser2": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/js2xmlparser2/-/js2xmlparser2-0.2.0.tgz", + "integrity": "sha1-p8ogibg9AjMdYxiS3WdDhkElAz8=", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsftp": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/jsftp/-/jsftp-2.1.3.tgz", + "integrity": "sha512-r79EVB8jaNAZbq8hvanL8e8JGu2ZNr2bXdHC4ZdQhRImpSPpnWwm5DYVzQ5QxJmtGtKhNNuvqGgbNaFl604fEQ==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "ftp-response-parser": "^1.0.1", + "once": "^1.4.0", + "parse-listing": "^1.1.3", + "stream-combiner": "^0.2.2", + "unorm": "^1.4.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jszip": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.2.tgz", + "integrity": "sha512-NmKajvAFQpbg3taXQXr/ccS2wcucR1AZ+NtyWp2Nq7HHVsXhcJFR8p0Baf32C2yVvBylFWVeKf+WI2AnvlPhpA==", + "dev": true, + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, + "keypather": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/keypather/-/keypather-1.10.2.tgz", + "integrity": "sha1-4ESWMtSz5RbyHMAUznxWRP3c5hQ=", + "dev": true, + "requires": { + "101": "^1.0.0" + } + }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "kuler": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", + "integrity": "sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ==", + "dev": true, + "requires": { + "colornames": "^1.1.1" + } + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "load-bmfont": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", + "integrity": "sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g==", + "dev": true, + "requires": { + "buffer-equal": "0.0.1", + "mime": "^1.3.4", + "parse-bmfont-ascii": "^1.0.3", + "parse-bmfont-binary": "^1.0.5", + "parse-bmfont-xml": "^1.1.4", + "phin": "^2.9.1", + "xhr": "^2.0.1", + "xtend": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.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.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", + "dev": true + }, + "lodash.isfinite": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", + "integrity": "sha1-+4m2WpqAKBgz8LdHizpRBPiY67M=", + "dev": true + }, + "lodash.isobject": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", + "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=", + "dev": true + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", + "dev": true + }, + "lodash.zip": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz", + "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=", + "dev": true + }, + "logform": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.1.2.tgz", + "integrity": "sha512-+lZh4OpERDBLqjiwDLpAWNQu6KMjnlXH2ByZwCuSqVPJletw0kTWJf5CgSNAUKn1KUkv3m2cUz/LK8zyEy7wzQ==", + "dev": true, + "requires": { + "colors": "^1.2.1", + "fast-safe-stringify": "^2.0.4", + "fecha": "^2.3.3", + "ms": "^2.1.1", + "triple-beam": "^1.3.0" + } + }, + "loglevel": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.7.tgz", + "integrity": "sha512-cY2eLFrQSAfVPhCgH1s7JI73tMbg9YC3v3+ZHVW67sBS7UxWzNEk/ZBbSfLykBWHp33dqqtOv82gjhKEi81T/A==", + "dev": true + }, + "loglevel-plugin-prefix": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", + "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", + "dev": true + }, + "longjohn": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/longjohn/-/longjohn-0.2.12.tgz", + "integrity": "sha1-fKdEawg2VcN351EiE9x1TVKmSn4=", + "dev": true, + "requires": { + "source-map-support": "0.3.2 - 1.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "md5-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/md5-file/-/md5-file-4.0.0.tgz", + "integrity": "sha512-UC0qFwyAjn4YdPpKaDNw6gNxRf7Mcx7jC1UGCY4boCzgvU2Aoc1mOGzTtrjjLKhM5ivsnhoKpQVxKPp+1j1qwg==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "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 + }, + "method-override": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/method-override/-/method-override-3.0.0.tgz", + "integrity": "sha512-IJ2NNN/mSl9w3kzWB92rcdHpz+HjkxhDJWNDBqSlas+zQdP8wBiJzITPg08M/k2uVvMow7Sk41atndNtt/PHSA==", + "dev": true, + "requires": { + "debug": "3.1.0", + "methods": "~1.1.2", + "parseurl": "~1.3.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "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 + } + } + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "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==", + "dev": true, + "requires": { + "mime-db": "1.43.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 + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "dev": true, + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mjpeg-server": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mjpeg-server/-/mjpeg-server-0.3.0.tgz", + "integrity": "sha1-rx3hP3VkJwi6bsFw36xAi9xdlzc=", + "dev": true + }, + "mkdirp": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz", + "integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==", + "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==", + "dev": true + }, + "moment-timezone": { + "version": "0.5.28", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.28.tgz", + "integrity": "sha512-TDJkZvAyKIVWg5EtVqRzU97w0Rb0YVbfpqyjgu6GwXCAohVRqwZjf4fOzDE6p1Ch98Sro/8hQQi65WDXW5STPw==", + "dev": true, + "requires": { + "moment": ">= 2.9.0" + } + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "dev": true, + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.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 + } + } + }, + "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 + }, + "mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", + "dev": true, + "requires": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "dependencies": { + "glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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" + } + }, + "rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", + "dev": true, + "requires": { + "glob": "^6.0.1" + } + } + } + }, + "ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-idevice": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/node-idevice/-/node-idevice-0.1.6.tgz", + "integrity": "sha1-lBGqdotEv7fNJezlyKHItLbx+kQ=", + "dev": true + }, + "node-simctl": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-simctl/-/node-simctl-6.1.0.tgz", + "integrity": "sha512-Ec+KDabRtxP4ul3wkmyVJa0/cWbznl4JGKdpbXAaM/DM8VPSoUVwJPyZoeYKvkKeke9Ee2meDlVRIL/gidz2TA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "appium-support": "^2.37.0", + "appium-xcode": "^3.8.0", + "asyncbox": "^2.3.1", + "lodash": "^4.2.1", + "semver": "^7.0.0", + "source-map-support": "^0.5.5", + "teen_process": "^1.5.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "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": "^3.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.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", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "omggif": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/omggif/-/omggif-1.0.10.tgz", + "integrity": "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "one-time": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", + "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=", + "dev": true + }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "openssl-wrapper": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/openssl-wrapper/-/openssl-wrapper-0.3.4.tgz", + "integrity": "sha1-wB7Jjk3NK13+C2k/MYJyAOO4Gwc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.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" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "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=", + "dev": true, + "requires": { + "shebang-regex": "^1.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=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parse-bmfont-ascii": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz", + "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=", + "dev": true + }, + "parse-bmfont-binary": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz", + "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=", + "dev": true + }, + "parse-bmfont-xml": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz", + "integrity": "sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==", + "dev": true, + "requires": { + "xml-parse-from-string": "^1.0.0", + "xml2js": "^0.4.5" + } + }, + "parse-headers": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", + "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==", + "dev": true + }, + "parse-listing": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/parse-listing/-/parse-listing-1.1.3.tgz", + "integrity": "sha1-qlRvV/3BKc+/mUXNS3V7FLBhgt0=", + "dev": true + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "pem": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/pem/-/pem-1.14.4.tgz", + "integrity": "sha512-v8lH3NpirgiEmbOqhx0vwQTxwi0ExsiWBGYh0jYNq7K6mQuO4gI6UEFlr6fLAdv9TPXRt6GqiwE37puQdIDS8g==", + "dev": true, + "requires": { + "es6-promisify": "^6.0.0", + "md5": "^2.2.1", + "os-tmpdir": "^1.0.1", + "which": "^2.0.2" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "phin": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz", + "integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==", + "dev": true + }, + "pid-from-port": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pid-from-port/-/pid-from-port-1.1.3.tgz", + "integrity": "sha512-OlE82n3yMOE5dY9RMOwxhoWefeMlxwk5IVxoj0sSzSFIlmvhN4obzTvO3s/d/b5JhcgXikjaspsy/HuUDTqbBg==", + "dev": true, + "requires": { + "execa": "^0.9.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", + "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "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" + } + }, + "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 + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "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=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "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=", + "dev": true, + "requires": { + "shebang-regex": "^1.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=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "pixelmatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz", + "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=", + "dev": true, + "requires": { + "pngjs": "^3.0.0" + } + }, + "plist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "dev": true, + "requires": { + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", + "xmldom": "0.1.x" + }, + "dependencies": { + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + } + } + }, + "pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true + }, + "pngjs": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.4.0.tgz", + "integrity": "sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==", + "dev": true + }, + "portfinder": { + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.25.tgz", + "integrity": "sha512-6ElJnHBbxVA1XSLgBp7G1FiCkQdlqGzuF7DswL5tcea+E8UpuvPU7beVAjjRwCioTS9ZluNbu+ZyRvgTsmqEBg==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "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" + } + } + } + }, + "portscanner": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.2.0.tgz", + "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", + "dev": true, + "requires": { + "async": "^2.6.0", + "is-number-like": "^1.0.3" + } + }, + "process": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", + "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=", + "dev": true + }, + "process-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/process-exists/-/process-exists-4.0.0.tgz", + "integrity": "sha512-BnlcYPiZjSW+fye12g9B7UeCzMAOdMkxuTz3zcytJ2BHwYZf2RoKvuuwUcJLeXlGj58x9YQrvhT21PmKhUc4UQ==", + "dev": true, + "requires": { + "ps-list": "^6.3.0" + }, + "dependencies": { + "ps-list": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-6.3.0.tgz", + "integrity": "sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA==", + "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==", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "ps-list": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-7.0.0.tgz", + "integrity": "sha512-ZDhdxqb+kE895BAvqIdGnWwfvB43h7KHMIcJC0hw7xLbbiJoprS+bqZxuGZ0jWdDxZEvB3jpnfgJyOn3lmsH+Q==", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "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", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "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" + } + }, + "rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "requires": { + "resolve": "^1.1.6" + } + }, + "regenerator-runtime": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz", + "integrity": "sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "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" + } + }, + "request-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.5.tgz", + "integrity": "sha512-ZgnepCykFdmpq86fKGwqntyTiUrHycALuGggpyCZwMvGaZWgxW6yagT0FHkgo5LzYvOaCNvxYwWYIjevSH1EDg==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resq": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resq/-/resq-1.7.1.tgz", + "integrity": "sha512-09u9Q5SAuJfAW5UoVAmvRtLvCOMaKP+djiixTXsZvPaojGKhuvc0Nfvp84U1rIfopJWEOXi5ywpCFwCk7mj8Xw==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1" + }, + "dependencies": { + "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=", + "dev": true + } + } + }, + "rgb2hex": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.10.tgz", + "integrity": "sha512-vKz+kzolWbL3rke/xeTE2+6vHmZnNxGyDnaVW4OckntAIcc7DcZzWkQSfxMDwqHS8vhgySnIFyBUH7lIk6PxvQ==", + "dev": true + }, + "rimraf": { + "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" + } + }, + "rpc-websockets": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/rpc-websockets/-/rpc-websockets-4.6.1.tgz", + "integrity": "sha512-xyQC6+95hOFQJBuMRIYi2E3/ddKEMMKuql5Sd49r4578CcthP0N9nHHFkVtvrsAgz4OQH6j7zsLurLNY0nOU6g==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "assert-args": "^1.2.1", + "babel-runtime": "^6.26.0", + "circular-json": "^0.5.9", + "eventemitter3": "^3.1.2", + "uuid": "^3.3.2", + "ws": "^5.2.2" + }, + "dependencies": { + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "safari-launcher": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/safari-launcher/-/safari-launcher-2.0.5.tgz", + "integrity": "sha1-pO/6nqUS0dVB5HuAOdhScBXyre0=", + "dev": true + }, + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "selenium-webdriver": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz", + "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==", + "dev": true, + "requires": { + "jszip": "^3.1.3", + "rimraf": "^2.5.4", + "tmp": "0.0.30", + "xml2js": "^0.4.17" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "semver": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "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" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-error": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz", + "integrity": "sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA==", + "dev": true, + "requires": { + "type-fest": "^0.8.0" + } + }, + "serve-favicon": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz", + "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=", + "dev": true, + "requires": { + "etag": "~1.8.1", + "fresh": "0.5.2", + "ms": "2.1.1", + "parseurl": "~1.3.2", + "safe-buffer": "5.1.1" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "shared-preferences-builder": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/shared-preferences-builder/-/shared-preferences-builder-0.0.4.tgz", + "integrity": "sha512-6yy1O1zVAY8HWVjsaJzFzkmvmktlSvqnjsYZpWJ0dUrFS5Rfn1a8P7h+7zyl9MTqUfSXeaE7De6Yymx3OszxlQ==", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "xmlbuilder": "^9.0.1" + }, + "dependencies": { + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", + "dev": true + } + } + }, + "shebang-command": { + "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": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "shelljs": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", + "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", + "dev": true, + "requires": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", + "dev": true + }, + "stream-combiner": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz", + "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "stream-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-equal/-/stream-equal-1.1.1.tgz", + "integrity": "sha512-SaZxkvxujYBR6NTumhRTg/yztw2p30fzZ/jvSgQtlZFEGI7tdSNDaPbvT47QF92hx6Tar8hAhpr7ErpTNvtuCQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "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==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "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=", + "dev": true + }, + "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": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "taskkill": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/taskkill/-/taskkill-3.1.0.tgz", + "integrity": "sha512-5KcOFzPvd1nGFVrmB7H4+QAWVjYOf//+QTbOj0GpXbqtqbKGWVczG+rq6VhXAtdtlKLTs16NAmHRyF5vbggQ2w==", + "dev": true, + "requires": { + "arrify": "^2.0.1", + "execa": "^3.3.0" + }, + "dependencies": { + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "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", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + } + } + }, + "teen_process": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-1.15.0.tgz", + "integrity": "sha512-E8DdTeffAselFMtcE56jNiof7jt+X+KJPpCn4xvbLFy0YVAT24Y9O5jSIzOFfAKIAirKkK0M9YfmQfmxmUdgGA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.0.0", + "bluebird": "^3.5.1", + "lodash": "^4.17.4", + "shell-quote": "^1.4.3", + "source-map-support": "^0.5.3" + } + }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "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 + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true + }, + "timm": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/timm/-/timm-1.6.2.tgz", + "integrity": "sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw==", + "dev": true + }, + "tinycolor2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz", + "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=", + "dev": true + }, + "tmp": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", + "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "dev": true + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tough-cookie": { + "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.28", + "punycode": "^2.1.1" + } + }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==", + "dev": true + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=", + "dev": true, + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "unorm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "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==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "utf7": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/utf7/-/utf7-1.0.2.tgz", + "integrity": "sha1-lV9JCq5lO6IguUVqCod2wZk2CZE=", + "dev": true, + "requires": { + "semver": "~5.3.0" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=", + "dev": true + }, + "utif": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/utif/-/utif-2.0.1.tgz", + "integrity": "sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==", + "dev": true, + "requires": { + "pako": "^1.0.5" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "uuid-js": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/uuid-js/-/uuid-js-0.7.5.tgz", + "integrity": "sha1-bIhtAqU9LUDc8l2RoXC0p7JblNA=", + "dev": true + }, + "validate.js": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/validate.js/-/validate.js-0.13.1.tgz", + "integrity": "sha512-PnFM3xiZ+kYmLyTiMgTYmU7ZHkjBZz2/+F0DaALc/uUtVzdCt1wAosvYJ5hFQi/hz8O4zb52FQhHZRC+uVkJ+g==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "walkdir": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", + "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=", + "dev": true + }, + "webdriver": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-5.19.0.tgz", + "integrity": "sha512-lPHhLqySiwEQr61R+/UD4KjImCxPEQTgipU5nIFUJFJxo97dIBolTHpXVcGazsrQc3nSPjiHY9CrKjuxl2MjCQ==", + "dev": true, + "requires": { + "@wdio/config": "5.18.4", + "@wdio/logger": "5.16.10", + "@wdio/protocols": "5.19.0", + "@wdio/utils": "5.18.6", + "lodash.merge": "^4.6.1", + "request": "^2.83.0" + } + }, + "webdriverio": { + "version": "5.19.0", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-5.19.0.tgz", + "integrity": "sha512-0HFKkE9RqfTGlJbZ2XyxpHDH+Seya5x9wHs8USL5PSrxxnEljcrVc6qya85o6zFlcTgGzC5WM6UDycXkfa1cLg==", + "dev": true, + "requires": { + "@wdio/config": "5.18.4", + "@wdio/logger": "5.16.10", + "@wdio/repl": "5.18.6", + "@wdio/utils": "5.18.6", + "archiver": "^3.0.0", + "css-value": "^0.0.1", + "grapheme-splitter": "^1.0.2", + "lodash.clonedeep": "^4.5.0", + "lodash.isobject": "^3.0.2", + "lodash.isplainobject": "^4.0.6", + "lodash.zip": "^4.2.0", + "resq": "^1.6.0", + "rgb2hex": "^0.1.0", + "serialize-error": "^5.0.0", + "webdriver": "5.19.0" + }, + "dependencies": { + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "bl": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.1.tgz", + "integrity": "sha512-FL/TdvchukRCuWVxT0YMO/7+L5TNeNrVFvRU2IY63aUyv9mpt8splf2NEr6qXtPo5fya5a66YohQKvGNmLrWNA==", + "dev": true, + "requires": { + "readable-stream": "^3.4.0" + } + }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "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" + } + } + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + }, + "zip-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + } + } + } + }, + "which": { + "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" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "winston": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.2.1.tgz", + "integrity": "sha512-zU6vgnS9dAWCEKg/QYigd6cgMVVNwyTzKs81XZtTFuRwJOcDdBg7AU0mXVyNbs7O5RH2zdv+BdNZUlx7mXPuOw==", + "dev": true, + "requires": { + "async": "^2.6.1", + "diagnostics": "^1.1.1", + "is-stream": "^1.1.0", + "logform": "^2.1.1", + "one-time": "0.0.4", + "readable-stream": "^3.1.1", + "stack-trace": "0.0.x", + "triple-beam": "^1.3.0", + "winston-transport": "^4.3.0" + }, + "dependencies": { + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.3.0.tgz", + "integrity": "sha512-B2wPuwUi3vhzn/51Uukcao4dIduEiPOcOt9HJ3QeaXgkJ5Z7UwpBzxS4ZGNHtrxrUvTwemsQiSys0ihOf8Mp1A==", + "dev": true, + "requires": { + "readable-stream": "^2.3.6", + "triple-beam": "^1.2.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "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" + }, + "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 + }, + "is-fullwidth-code-point": { + "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 + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==", + "dev": true + }, + "xhr": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", + "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", + "dev": true, + "requires": { + "global": "~4.3.0", + "is-function": "^1.0.1", + "parse-headers": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "xml-parse-from-string": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz", + "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=", + "dev": true + }, + "xml2js": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz", + "integrity": "sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==", + "dev": true, + "requires": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + } + }, + "xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "dev": true + }, + "xmldom": { + "version": "0.1.31", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", + "dev": true + }, + "xpath": { + "version": "0.0.27", + "resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz", + "integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "15.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz", + "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.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 + }, + "is-fullwidth-code-point": { + "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 + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } + } + } + }, + "yargs-parser": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.0.tgz", + "integrity": "sha512-o/Jr6JBOv6Yx3pL+5naWSoIA2jJ+ZkMYQG/ie9qFbukBe4uzmBatlXFOiu/tNKRWEtyf+n5w7jc/O16ufqOTdQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "dev": true, + "requires": { + "archiver-utils": "^1.3.0", + "compress-commons": "^1.2.0", + "lodash": "^4.8.0", + "readable-stream": "^2.0.0" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "archiver": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-3.1.1.tgz", + "integrity": "sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "async": "^2.6.3", + "buffer-crc32": "^0.2.1", + "glob": "^7.1.4", + "readable-stream": "^3.4.0", + "tar-stream": "^2.1.0", + "zip-stream": "^2.1.2" + }, + "dependencies": { + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "bl": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.0.2.tgz", + "integrity": "sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "tar-stream": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", + "integrity": "sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q==", + "dev": true, + "requires": { + "bl": "^4.0.1", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "dev": true, + "requires": { + "glob": "^7.1.4", + "graceful-fs": "^4.2.0", + "lazystream": "^1.0.0", + "lodash.defaults": "^4.2.0", + "lodash.difference": "^4.5.0", + "lodash.flatten": "^4.4.0", + "lodash.isplainobject": "^4.0.6", + "lodash.union": "^4.6.0", + "normalize-path": "^3.0.0", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + } + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-differ": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-2.1.0.tgz", + "integrity": "sha512-KbUpJgx909ZscOc/7CLATBFam7P1Z1QRQInvgT0UztM9Q72aGKCunKASAl7WNW0tnPmPyEMeMhdsfWhfmW037w==", + "dev": true + }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + }, + "array-filter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-1.0.0.tgz", + "integrity": "sha1-uveeYubvTCpMC4MSMtr/7CUfnYM=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-iterate": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.2.tgz", + "integrity": "sha512-1hWSHTIlG/8wtYD+PPX5AOBtKWngpDFjrsrHgZpe+JdgNGz0udYu6ZIkAa/xuenIUEqFv7DvE2Yr60jxweJSrQ==", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-slice": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=" }, "array-union": { "version": "1.0.2", @@ -12390,8 +20314,7 @@ "art": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/art/-/art-0.10.3.tgz", - "integrity": "sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==", - "dev": true + "integrity": "sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==" }, "asap": { "version": "2.0.6", @@ -12401,8 +20324,7 @@ "asn1": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" }, "asn1.js": { "version": "4.10.1", @@ -12445,8 +20367,7 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" }, "assign-symbols": { "version": "1.0.0", @@ -12468,14 +20389,12 @@ "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "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" } @@ -12495,14 +20414,12 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" }, "atob": { "version": "2.1.1", @@ -12594,14 +20511,12 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", - "dev": true + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, "axe-core": { "version": "3.5.3", @@ -12781,27 +20696,41 @@ }, "dependencies": { "@jest/transform": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.3.0.tgz", - "integrity": "sha512-W01p8kTDvvEX6kd0tJc7Y5VdYyFaKwNWy1HQz6Jqlhu48z/8Gxp+yFCDVj+H8Rc7ezl3Mg0hDaGuFVkmHOqirg==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", "jest-regex-util": "^25.2.6", - "jest-util": "^25.3.0", + "jest-util": "^25.5.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "realpath-native": "^2.0.0", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "ansi-styles": { @@ -12881,16 +20810,16 @@ } }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, "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.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "has-flag": { @@ -12906,23 +20835,38 @@ "dev": true }, "jest-haste-map": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.3.0.tgz", - "integrity": "sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", "which": "^2.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "jest-regex-util": { @@ -12932,27 +20876,45 @@ "dev": true }, "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==", - "dev": true + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "jest-worker": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz", - "integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "requires": { "merge-stream": "^2.0.0", @@ -13245,7 +21207,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", - "dev": true, "requires": { "object.assign": "^4.1.0" } @@ -13493,11 +21454,13 @@ } }, "babel-plugin-jest-hoist": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.2.6.tgz", - "integrity": "sha512-qE2xjMathybYxjiGFJg0mLFrz0qNp83aNZycWDY/SuHiZNq+vQfRQtuINqyXyue1ELd8Rd+1OhFSLjms8msMbw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", "dev": true, "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", "@types/babel__traverse": "^7.0.6" } }, @@ -13720,8 +21683,7 @@ "babel-plugin-syntax-trailing-function-commas": { "version": "7.0.0-beta.0", "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", - "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==", - "dev": true + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" }, "babel-plugin-transform-inline-consecutive-adds": { "version": "0.4.3", @@ -13799,7 +21761,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", - "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -13817,7 +21778,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz", "integrity": "sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw==", - "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-object-rest-spread": "^7.0.0", @@ -13849,12 +21809,12 @@ } }, "babel-preset-jest": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.3.0.tgz", - "integrity": "sha512-tjdvLKNMwDI9r+QWz9sZUQGTq1dpoxjUqFUpEasAc7MOtHg9XuLT2fx0udFG+k1nvMV0WvHHVAN7VmCZ+1Zxbw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^25.2.6", + "babel-plugin-jest-hoist": "^25.5.0", "babel-preset-current-node-syntax": "^0.1.2" } }, @@ -14009,7 +21969,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, "requires": { "safe-buffer": "5.1.2" } @@ -14024,7 +21983,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, "optional": true, "requires": { "tweetnacl": "^0.14.3" @@ -14069,8 +22027,7 @@ "big-integer": { "version": "1.6.48", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", - "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", - "dev": true + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==" }, "big.js": { "version": "3.2.0", @@ -14228,8 +22185,7 @@ "boolbase": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, "boxen": { "version": "4.2.0", @@ -14353,7 +22309,6 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", - "dev": true, "requires": { "stream-buffers": "~2.2.0" } @@ -14362,7 +22317,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz", "integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==", - "dev": true, "requires": { "big-integer": "^1.6.44" } @@ -14417,14 +22371,12 @@ "browser-process-hrtime": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", - "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", - "dev": true + "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=" }, "browser-resolve": { "version": "1.11.3", "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, "requires": { "resolve": "1.1.7" }, @@ -14432,8 +22384,7 @@ "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" } } }, @@ -14586,8 +22537,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, "buffer-fill": { "version": "1.0.0", @@ -14598,8 +22548,7 @@ "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" }, "buffer-xor": { "version": "1.0.3", @@ -14610,8 +22559,7 @@ "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, "builtin-status-codes": { "version": "3.0.0", @@ -14781,7 +22729,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", - "dev": true, "requires": { "callsites": "^2.0.0" }, @@ -14789,8 +22736,7 @@ "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", - "dev": true + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" } } }, @@ -14798,7 +22744,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", - "dev": true, "requires": { "caller-callsite": "^2.0.0" } @@ -14827,8 +22772,7 @@ "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" }, "camelcase-css": { "version": "2.0.1", @@ -14893,8 +22837,7 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" }, "ccount": { "version": "1.0.3", @@ -15271,7 +23214,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, "requires": { "restore-cursor": "^2.0.0" } @@ -15279,8 +23221,7 @@ "cli-spinners": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.2.0.tgz", - "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==", - "dev": true + "integrity": "sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ==" }, "cli-table3": { "version": "0.5.1", @@ -15352,8 +23293,7 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" }, "clipboard": { "version": "2.0.1", @@ -15369,7 +23309,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", @@ -15379,8 +23318,7 @@ "clone": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, "clone-deep": { "version": "4.0.1", @@ -15430,8 +23368,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, "coa": { "version": "2.0.2", @@ -15460,8 +23397,7 @@ "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 + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "collapse-white-space": { "version": "1.0.4", @@ -15472,8 +23408,7 @@ "collect-v8-coverage": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz", - "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==", - "dev": true + "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==" }, "collection-visit": { "version": "1.0.0", @@ -15500,14 +23435,12 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, "colorette": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz", - "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==", - "dev": true + "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==" }, "colors": { "version": "0.5.1", @@ -15546,7 +23479,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -15560,8 +23492,7 @@ "command-exists": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.8.tgz", - "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==", - "dev": true + "integrity": "sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw==" }, "commander": { "version": "4.1.0", @@ -15578,8 +23509,7 @@ "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "compare-func": { "version": "1.3.2", @@ -15607,11 +23537,30 @@ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" }, + "compress-commons": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-2.1.1.tgz", + "integrity": "sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q==", + "dev": true, + "requires": { + "buffer-crc32": "^0.2.13", + "crc32-stream": "^3.0.1", + "normalize-path": "^3.0.0", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, "compressible": { "version": "2.0.17", "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", - "dev": true, "requires": { "mime-db": ">= 1.40.0 < 2" }, @@ -15619,8 +23568,7 @@ "mime-db": { "version": "1.42.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", - "dev": true + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" } } }, @@ -15628,7 +23576,6 @@ "version": "1.7.4", "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, "requires": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -15642,14 +23589,12 @@ "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, "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" } @@ -15675,7 +23620,6 @@ "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", @@ -15787,7 +23731,6 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", - "dev": true, "requires": { "debug": "2.6.9", "finalhandler": "1.1.2", @@ -15799,7 +23742,6 @@ "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" } @@ -15807,8 +23749,7 @@ "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "statuses": { "version": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -15825,8 +23766,7 @@ "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "consolidated-events": { "version": "2.0.2", @@ -16496,7 +24436,6 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.5.tgz", "integrity": "sha512-94j37OtvxS5w7qr7Ta6dt67tWdnOxigBVN4VnSxNXFez9o18PGQ0D33SchKP17r9LAcWVTYV72G6vDayAUBFIg==", - "dev": true, "requires": { "is-directory": "^0.3.1", "js-yaml": "^3.9.0", @@ -16507,7 +24446,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -16515,6 +24453,50 @@ } } }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "requires": { + "buffer": "^5.1.0" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", + "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } + } + }, + "crc32-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-3.0.1.tgz", + "integrity": "sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w==", + "dev": true, + "requires": { + "crc": "^3.4.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", @@ -16556,7 +24538,6 @@ "version": "15.6.3", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", - "dev": true, "requires": { "fbjs": "^0.8.9", "loose-envify": "^1.3.1", @@ -16587,7 +24568,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -16617,7 +24597,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", - "dev": true, "requires": { "inherits": "^2.0.3", "source-map": "^0.6.1", @@ -16628,8 +24607,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -16848,6 +24826,16 @@ "postcss-value-parser": "^3.3.0" } }, + "css-to-react-native-transform": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/css-to-react-native-transform/-/css-to-react-native-transform-1.9.0.tgz", + "integrity": "sha512-darzotx5xx+Q0bzASkvNBasztLCssNerzf9jpMZx0H4CTY6J/y2Wh50ZtYAJ3FmESEux1bJcGa6T0zfISTuFqw==", + "requires": { + "css": "^2.2.4", + "css-mediaquery": "^0.1.2", + "css-to-react-native": "^2.3.0" + } + }, "css-tree": { "version": "1.0.0-alpha.28", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.28.tgz", @@ -16977,14 +24965,12 @@ "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" }, "cssstyle": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", - "dev": true, "requires": { "cssom": "~0.3.6" } @@ -17038,7 +25024,6 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -17047,7 +25032,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dev": true, "requires": { "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", @@ -17069,8 +25053,7 @@ "dayjs": { "version": "1.8.18", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.18.tgz", - "integrity": "sha512-JBMJZghNK8TtuoPnKNIzW9xavVVigld/zmZNpZSyQbkb2Opp55YIfZUpE4OEqPF/iyUVQTKcn1bC2HtC8B7s3g==", - "dev": true + "integrity": "sha512-JBMJZghNK8TtuoPnKNIzW9xavVVigld/zmZNpZSyQbkb2Opp55YIfZUpE4OEqPF/iyUVQTKcn1bC2HtC8B7s3g==" }, "de-indent": { "version": "1.0.2", @@ -17170,8 +25153,7 @@ "deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, "deep-freeze": { "version": "0.0.1", @@ -17182,8 +25164,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "deep-object-diff": { "version": "1.1.0", @@ -17200,7 +25181,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, "requires": { "clone": "^1.0.2" } @@ -17417,8 +25397,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, "delegate": { "version": "3.2.0", @@ -17428,14 +25407,12 @@ "delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" }, "denodeify": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=" }, "depd": { "version": "1.1.2", @@ -17486,14 +25463,12 @@ "detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" }, "detect-node": { "version": "2.0.4", @@ -17540,8 +25515,7 @@ "diff-sequences": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==" }, "diffie-hellman": { "version": "5.0.3", @@ -17636,7 +25610,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", - "dev": true, "requires": { "domelementtype": "~1.1.1", "entities": "~1.1.1" @@ -17645,8 +25618,7 @@ "domelementtype": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true + "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" } } }, @@ -17671,7 +25643,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "dev": true, "requires": { "webidl-conversions": "^4.0.2" } @@ -17680,7 +25651,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, "requires": { "domelementtype": "1" } @@ -17689,7 +25659,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", - "dev": true, "requires": { "dom-serializer": "0", "domelementtype": "1" @@ -17785,7 +25754,6 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, "optional": true, "requires": { "jsbn": "~0.1.0" @@ -17935,8 +25903,7 @@ "envinfo": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.5.0.tgz", - "integrity": "sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ==", - "dev": true + "integrity": "sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ==" }, "enzyme": { "version": "3.11.0", @@ -18693,7 +26660,6 @@ "version": "1.5.1", "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", - "dev": true, "requires": { "accepts": "~1.3.7", "escape-html": "~1.0.3" @@ -18703,7 +26669,6 @@ "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, "requires": { "mime-types": "~2.1.24", "negotiator": "0.6.2" @@ -18712,14 +26677,12 @@ "mime-db": { "version": "1.42.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", - "dev": true + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" }, "mime-types": { "version": "2.1.25", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "dev": true, "requires": { "mime-db": "1.42.0" } @@ -18727,8 +26690,7 @@ "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" } } }, @@ -18927,7 +26889,6 @@ "version": "1.13.0", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.13.0.tgz", "integrity": "sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw==", - "dev": true, "requires": { "esprima": "^4.0.1", "estraverse": "^4.2.0", @@ -18940,7 +26901,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, "optional": true } } @@ -19989,14 +27949,12 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" }, "etag": { "version": "1.8.1", @@ -20006,14 +27964,17 @@ "event-target-shim": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "dev": true + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" + }, + "eventemitter2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-1.0.5.tgz", + "integrity": "sha1-+YNhBRexc3wLncZDvsqTiTwE3xg=" }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", - "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==", - "dev": true + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, "events": { "version": "3.1.0", @@ -20172,8 +28133,7 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" }, "expand-brackets": { "version": "2.1.4", @@ -20225,24 +28185,38 @@ } }, "expect": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.3.0.tgz", - "integrity": "sha512-buboTXML2h/L0Kh44Ys2Cx49mX20ISc5KDirkxIs3Q9AJv0kazweUAbukegr+nHDOvFRKmxdojjIHCjqAceYfg==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-styles": "^4.0.0", "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", "jest-regex-util": "^25.2.6" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -20252,7 +28226,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -20261,7 +28234,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -20271,7 +28243,6 @@ "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.4" } @@ -20279,92 +28250,112 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } }, "jest-get-type": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } }, "jest-message-util": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.4.0.tgz", - "integrity": "sha512-LYY9hRcVGgMeMwmdfh9tTjeux1OjZHMusq/E5f3tJN+dAoVVkJtq5ZUEPIcB7bpxDUt2zjUsrwg0EGgPQ+OhXQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "jest-regex-util": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -20373,7 +28364,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -20565,8 +28555,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, "extend-shallow": { "version": "3.0.2", @@ -20694,14 +28683,12 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" }, "fancy-log": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", - "dev": true, "requires": { "ansi-gray": "^0.1.1", "color-support": "^1.1.3", @@ -20714,11 +28701,15 @@ "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-4.3.0.tgz", "integrity": "sha512-k8FXd6+JeXoItmdNqB3hMwFgArryjdYBLuzEM8fRY/oztd/051yhSHU6GUrMOfIQU9dDHyFDcIAkGrQKlYtpDA==" }, + "fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==" + }, "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=", - "dev": true + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-diff": { "version": "1.2.0", @@ -20748,8 +28739,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fast-memoize": { "version": "2.5.1", @@ -20815,14 +28805,12 @@ "fbjs-css-vars": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", - "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==", - "dev": true + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, "fbjs-scripts": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz", "integrity": "sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ==", - "dev": true, "requires": { "@babel/core": "^7.0.0", "ansi-colors": "^1.0.1", @@ -20839,14 +28827,12 @@ "core-js": { "version": "2.6.11", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -20869,7 +28855,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } @@ -21033,7 +29018,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", - "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -21048,7 +29032,6 @@ "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" } @@ -21056,14 +29039,12 @@ "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" } } }, @@ -21168,7 +29149,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, "requires": { "locate-path": "^2.0.0" } @@ -21340,8 +29320,7 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "fork-ts-checker-webpack-plugin": { "version": "1.5.0", @@ -21382,7 +29361,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "1.0.6", @@ -21459,7 +29437,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.6.tgz", "integrity": "sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==", - "dev": true, "requires": { "minipass": "^2.2.1" } @@ -21485,7 +29462,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, "optional": true, "requires": { "nan": "^2.12.1", @@ -21496,14 +29472,12 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.3.tgz", "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==", - "dev": true, "optional": true }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "optional": true, "requires": { "fs.realpath": "^1.0.0", @@ -21518,7 +29492,6 @@ "version": "2.9.0", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, "optional": true, "requires": { "safe-buffer": "^5.1.2", @@ -21529,7 +29502,6 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.12.0.tgz", "integrity": "sha512-4KghwV8vH5k+g2ylT+sLTjy5wmUOb9vPhnM8NHvRf9dHmnW/CndrFXy2aRPaPST6dugXSdHXfeaHQm77PIz/1A==", - "dev": true, "optional": true, "requires": { "detect-libc": "^1.0.2", @@ -21548,7 +29520,6 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, "optional": true, "requires": { "glob": "^7.1.3" @@ -21560,7 +29531,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", - "dev": true, "optional": true, "requires": { "abbrev": "1", @@ -21571,14 +29541,12 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, "optional": true }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", - "dev": true, "optional": true, "requires": { "chownr": "^1.1.1", @@ -21594,7 +29562,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, "optional": true } } @@ -21673,7 +29640,6 @@ "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -21688,14 +29654,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "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" } @@ -21704,7 +29668,6 @@ "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", @@ -21715,7 +29678,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -21745,8 +29707,7 @@ "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "get-own-enumerable-property-symbols": { "version": "3.0.0", @@ -21856,10 +29817,23 @@ "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.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "requires": { + "pump": "^3.0.0" + }, + "dependencies": { + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } }, "get-value": { "version": "2.0.6", @@ -21870,7 +29844,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -22125,7 +30098,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -22444,8 +30416,7 @@ "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" }, "gud": { "version": "1.0.0", @@ -22500,14 +30471,12 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" }, "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==", - "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -22557,8 +30526,7 @@ "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" }, "has-value": { "version": "1.0.0", @@ -22723,8 +30691,7 @@ "hermes-engine": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/hermes-engine/-/hermes-engine-0.2.1.tgz", - "integrity": "sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ==", - "dev": true + "integrity": "sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ==" }, "hex-color-regex": { "version": "1.1.0", @@ -22772,8 +30739,7 @@ "hosted-git-info": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", - "dev": true + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, "hpq": { "version": "1.3.0", @@ -22811,7 +30777,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, "requires": { "whatwg-encoding": "^1.0.1" } @@ -22825,8 +30790,7 @@ "html-escaper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", - "dev": true + "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==" }, "html-minifier-terser": { "version": "5.0.2", @@ -22917,6 +30881,20 @@ "readable-stream": "^2.0.2" } }, + "htmlparser2-without-node-native": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/htmlparser2-without-node-native/-/htmlparser2-without-node-native-3.9.2.tgz", + "integrity": "sha1-s+0FDYd9D/NGWWnjOYd7f59mMfY=", + "requires": { + "domelementtype": "^1.3.0", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "eventemitter2": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, "http-cache-semantics": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", @@ -22927,7 +30905,6 @@ "version": "1.6.3", "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -22955,7 +30932,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -23332,7 +31308,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", - "dev": true, "requires": { "minimatch": "^3.0.4" } @@ -23340,8 +31315,7 @@ "image-size": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", - "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==", - "dev": true + "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==" }, "immediate": { "version": "3.0.6", @@ -23504,8 +31478,7 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "init-package-json": { "version": "1.10.3", @@ -23876,7 +31849,6 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, "requires": { "loose-envify": "^1.0.0" } @@ -23884,8 +31856,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "ip": { "version": "1.1.5", @@ -23896,8 +31867,7 @@ "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" }, "ipaddr.js": { "version": "1.9.1", @@ -23992,7 +31962,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, "requires": { "builtin-modules": "^1.0.0" } @@ -24073,8 +32042,14 @@ "is-directory": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true }, "is-expression": { "version": "3.0.0", @@ -24128,8 +32103,7 @@ "is-generator-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" }, "is-glob": { "version": "4.0.0", @@ -24373,8 +32347,7 @@ "is-wsl": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" }, "isarray": { "version": "1.0.0", @@ -24403,8 +32376,7 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, "istanbul-lib-coverage": { "version": "3.0.0", @@ -24436,7 +32408,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, "requires": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^3.0.0", @@ -24446,14 +32417,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -24464,7 +32433,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -24475,7 +32443,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -24483,14 +32450,12 @@ "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 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -24498,7 +32463,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, "requires": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -24520,6 +32484,11 @@ "iterate-iterator": "^1.0.1" } }, + "jed": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/jed/-/jed-1.1.1.tgz", + "integrity": "sha1-elSbvZ/+FYWwzQoZHiAwVb7ldLQ=" + }, "jest": { "version": "25.3.0", "resolved": "https://registry.npmjs.org/jest/-/jest-25.3.0.tgz", @@ -24532,108 +32501,63 @@ }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, - "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" - } - }, "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, - "@jest/transform": { - "version": "https://registry.npmjs.org/@jest/transform/-/transform-25.3.0.tgz", - "integrity": "sha512-W01p8kTDvvEX6kd0tJc7Y5VdYyFaKwNWy1HQz6Jqlhu48z/8Gxp+yFCDVj+H8Rc7ezl3Mg0hDaGuFVkmHOqirg==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.3.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.3.0", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.3.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "ansi-escapes": { - "version": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, "requires": { - "type-fest": "^0.11.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -24648,6 +32572,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -24668,6 +32593,7 @@ "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.4" } @@ -24675,17 +32601,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "cross-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", - "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "emoji-regex": { "version": "8.0.0", @@ -24693,26 +32610,11 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "execa": { - "version": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", - "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", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -24727,47 +32629,23 @@ "path-exists": "^4.0.0" } }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "optional": true - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.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.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "import-local": { "version": "3.0.2", @@ -24788,100 +32666,86 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-stream": { - "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==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "jest-cli": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.3.0.tgz", - "integrity": "sha512-XpNQPlW1tzpP7RGG8dxpkRegYDuLjzSiENu92+CYM87nEbmEPb3b4+yo8xcsHOnj0AG7DUt9b3uG8LuHI3MDzw==", + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.5.4.tgz", + "integrity": "sha512-rG8uJkIiOUpnREh1768/N3n27Cm+xPFkSNFO91tgg+8o2rXeVLStz+vkXkGr4UtzH6t1SNbjwoiswd7p4AhHTw==", "dev": true, "requires": { - "@jest/core": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/core": "^25.5.4", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", "exit": "^0.1.2", + "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-config": "^25.5.4", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", "prompts": "^2.0.1", "realpath-native": "^2.0.0", "yargs": "^15.3.1" } }, "jest-get-type": { - "version": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" - }, - "jest-haste-map": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.3.0.tgz", - "integrity": "sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A==", - "requires": { - "@jest/types": "^25.3.0", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" - } + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true }, "jest-message-util": { - "version": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" - }, - "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==" - }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, - "jest-worker": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz", - "integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==", + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -24891,51 +32755,16 @@ "p-locate": "^4.1.0" } }, - "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==" - }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -24966,16 +32795,6 @@ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, "pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -24986,33 +32805,28 @@ } }, "pretty-format": { - "version": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" } }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true }, "require-main-filename": { "version": "2.0.0", @@ -25020,13 +32834,6 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, "resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -25042,32 +32849,11 @@ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, - "semver": { - "version": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "string-width": { "version": "4.2.0", @@ -25093,35 +32879,20 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, "requires": { "has-flag": "^4.0.0" } }, - "throat": { - "version": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } }, - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", @@ -25133,17 +32904,6 @@ "strip-ansi": "^6.0.0" } }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", @@ -25170,9 +32930,9 @@ } }, "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -25182,21 +32942,61 @@ } }, "jest-changed-files": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.3.0.tgz", - "integrity": "sha512-eqd5hyLbUjIVvLlJ3vQ/MoPxsxfESVXG9gvU19XXjKzxr+dXmZIqCXiY0OiYaibwlHZBJl2Vebkc0ADEMzCXew==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.5.0.tgz", + "integrity": "sha512-EOw9QEqapsDT7mKF162m8HFzRPbmP8qJQny6ldVOdOVBz3ACgPm/1nAn5fPQ/NDaYhX/AHkrGwwkCncpAVSXcw==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "execa": "^3.2.0", "throat": "^5.0.0" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, "cross-spawn": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", - "dev": true, "requires": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -25207,7 +33007,6 @@ "version": "3.4.0", "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", - "dev": true, "requires": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", @@ -25221,38 +33020,30 @@ "strip-final-newline": "^2.0.0" } }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-stream": { "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 + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" }, "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "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 + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "npm-run-path": { "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": "^3.0.0" } @@ -25261,7 +33052,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -25269,30 +33059,17 @@ "p-finally": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "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" - } + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "shebang-command": { "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": "^3.0.0" } @@ -25300,20 +33077,25 @@ "shebang-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, "which": { "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" } @@ -25321,61 +33103,151 @@ } }, "jest-config": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.3.0.tgz", - "integrity": "sha512-CmF1JnNWFmoCSPC4tnU52wnVBpuxHjilA40qH/03IHxIevkjUInSMwaDeE6ACfxMPTLidBGBCO3EbxvzPbo8wA==", - "dev": true, + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.3.0", - "@jest/types": "^25.3.0", - "babel-jest": "^25.3.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", "chalk": "^3.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", - "jest-environment-jsdom": "^25.3.0", - "jest-environment-node": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", "jest-get-type": "^25.2.6", - "jest-jasmine2": "^25.3.0", + "jest-jasmine2": "^25.5.4", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", "micromatch": "^4.0.2", - "pretty-format": "^25.3.0", + "pretty-format": "^25.5.0", "realpath-native": "^2.0.0" }, "dependencies": { + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + } + }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "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 + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "requires": { + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -25385,7 +33257,6 @@ "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.4" } @@ -25393,82 +33264,230 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "deepmerge": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "optional": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-get-type": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } }, "jest-regex-util": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "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==" + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "pretty-format": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -25477,27 +33496,68 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", - "dev": true + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" }, "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -25506,10 +33566,33 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } } } }, @@ -25696,35 +33779,42 @@ "version": "25.3.0", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", - "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.3.0.tgz", - "integrity": "sha512-aBfS4VOf/Qs95yUlX6d6WBv0szvOcTkTTyCIaLuQGj4bSHsT+Wd9dDngVHrCe5uytxpN8VM+NAloI6nbPjXfXw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", "jest-get-type": "^25.2.6", - "jest-util": "^25.3.0", - "pretty-format": "^25.3.0" + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "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 + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -25734,7 +33824,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -25744,7 +33833,6 @@ "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.4" } @@ -25752,40 +33840,41 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "jest-get-type": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, "pretty-format": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -25794,14 +33883,12 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -25834,37 +33921,45 @@ } }, "jest-environment-jsdom": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.3.0.tgz", - "integrity": "sha512-jdE4bQN+k2QEZ9sWOxsqDJvMzbdFSCN/4tw8X0TQaCqyzKz58PyEf41oIr4WO7ERdp7WaJGBSUKF7imR3UW1lg==", - "dev": true, - "requires": { - "@jest/environment": "^25.3.0", - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", "jsdom": "^15.2.1" }, "dependencies": { "@jest/fake-timers": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.3.0.tgz", - "integrity": "sha512-NHAj7WbsyR3qBJPpBwSwqaq2WluIvUQsyzpJTN7XDVk7VnlC/y1BAnaYZL3vbPIP8Nhm0Ae5DJe0KExr/SdMJQ==", - "dev": true, - "requires": { - "@jest/types": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", "lolex": "^5.0.0" } }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -25874,7 +33969,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -25883,7 +33977,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -25893,7 +33986,6 @@ "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.4" } @@ -25901,62 +33993,62 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.3.0.tgz", - "integrity": "sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "requires": { - "@jest/types": "^25.3.0" + "@jest/types": "^25.5.0" } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } @@ -25965,7 +34057,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -25974,14 +34065,12 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -25990,7 +34079,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -25998,37 +34086,45 @@ } }, "jest-environment-node": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.3.0.tgz", - "integrity": "sha512-XO09S29Nx1NU7TiMPHMoDIkxoGBuKSTbE+sHp0gXbeLDXhIdhysUI25kOqFFSD9AuDgvPvxWCXrvNqiFsOH33g==", - "dev": true, - "requires": { - "@jest/environment": "^25.3.0", - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "requires": { + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", "semver": "^6.3.0" }, "dependencies": { "@jest/fake-timers": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.3.0.tgz", - "integrity": "sha512-NHAj7WbsyR3qBJPpBwSwqaq2WluIvUQsyzpJTN7XDVk7VnlC/y1BAnaYZL3vbPIP8Nhm0Ae5DJe0KExr/SdMJQ==", - "dev": true, - "requires": { - "@jest/types": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", "lolex": "^5.0.0" } }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -26038,7 +34134,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -26047,7 +34142,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -26057,7 +34151,6 @@ "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.4" } @@ -26065,62 +34158,62 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.3.0.tgz", - "integrity": "sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "requires": { - "@jest/types": "^25.3.0" + "@jest/types": "^25.5.0" } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } @@ -26129,7 +34222,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -26138,20 +34230,17 @@ "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -26160,7 +34249,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -26234,14 +34322,12 @@ "jest-get-type": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", - "dev": true + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==" }, "jest-haste-map": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", - "dev": true, "requires": { "@jest/types": "^24.9.0", "anymatch": "^2.0.0", @@ -26261,7 +34347,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -26272,7 +34357,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -26280,82 +34364,87 @@ "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==", - "dev": true + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" } } }, "jest-jasmine2": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.3.0.tgz", - "integrity": "sha512-NCYOGE6+HNzYFSui52SefgpsnIzvxjn6KAgqw66BdRp37xpMD/4kujDHLNW5bS5i53os5TcMn6jYrzQRO8VPrQ==", - "dev": true, + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.3.0", - "@jest/source-map": "^25.2.6", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^25.3.0", + "expect": "^25.5.0", "is-generator-fn": "^2.0.0", - "jest-each": "^25.3.0", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "pretty-format": "^25.3.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", "throat": "^5.0.0" }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", + "graceful-fs": "^4.2.4", "source-map": "^0.6.0" } }, "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "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 + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -26365,7 +34454,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -26374,7 +34462,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -26384,7 +34471,6 @@ "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.4" } @@ -26392,67 +34478,81 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, "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==", - "dev": true + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } }, "jest-get-type": { - "version": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, - "jest-regex-util": { - "version": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" - }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } @@ -26461,24 +34561,17 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, "pretty-format": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -26487,41 +34580,22 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "realpath-native": { - "version": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" - }, - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -26529,14 +34603,12 @@ "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -26649,36 +34721,52 @@ } }, "jest-leak-detector": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.3.0.tgz", - "integrity": "sha512-jk7k24dMIfk8LUSQQGN8PyOy9+J0NAfHZWiDmUDYVMctY8FLJQ1eQ8+PjMoN8PgwhLIggUqgYJnyRFvUz3jLRw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", "requires": { "jest-get-type": "^25.2.6", - "pretty-format": "^25.3.0" + "pretty-format": "^25.5.0" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "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 + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "color-convert": { "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.4" } @@ -26686,22 +34774,24 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "jest-get-type": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" }, "pretty-format": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -26710,8 +34800,15 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } } } }, @@ -26813,7 +34910,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", - "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@jest/test-result": "^24.9.0", @@ -26829,7 +34925,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -26840,7 +34935,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -26849,7 +34943,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -26859,8 +34952,7 @@ "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" } } }, @@ -26868,7 +34960,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", - "dev": true, "requires": { "@jest/types": "^24.9.0" }, @@ -26877,7 +34968,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -26888,7 +34978,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -26898,8 +34987,7 @@ "jest-pnp-resolver": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", - "dev": true + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" }, "jest-puppeteer": { "version": "4.4.0", @@ -27005,20 +35093,25 @@ } }, "jest-resolve-dependencies": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.3.0.tgz", - "integrity": "sha512-bDUlLYmHW+f7J7KgcY2lkq8EMRqKonRl0XoD4Wp5SJkgAxKJnsaIOlrrVNTfXYf+YOu3VCjm/Ac2hPF2nfsCIA==", - "dev": true, + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.5.4.tgz", + "integrity": "sha512-yFmbPd+DAQjJQg88HveObcGBA32nqNZ02fjYmtL16t1xw9bAttSn5UGRRhzMHIQbsep7znWvAvnD4kDqOFM0Uw==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "jest-regex-util": "^25.2.6", - "jest-snapshot": "^25.3.0" + "jest-snapshot": "^25.5.1" }, "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } }, "ansi-styles": { "version": "4.2.1", @@ -27029,14 +35122,6 @@ "color-convert": "^2.0.1" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -27059,95 +35144,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "jest-get-type": { - "version": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" - }, - "jest-message-util": { - "version": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "pretty-format": { - "version": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "requires": { - "@jest/types": "^25.3.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "realpath-native": { - "version": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" - }, - "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "semver": { - "version": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" }, "supports-color": { "version": "7.1.0", @@ -27156,84 +35161,73 @@ "requires": { "has-flag": "^4.0.0" } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } } } }, "jest-runner": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.3.0.tgz", - "integrity": "sha512-csDqSC9qGHYWDrzrElzEgFbteztFeZJmKhSgY5jlCIcN0+PhActzRNku0DA1Xa1HxGOb0/AfbP1EGJlP4fGPtA==", - "dev": true, - "requires": { - "@jest/console": "^25.3.0", - "@jest/environment": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-config": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", "jest-docblock": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-jasmine2": "^25.3.0", - "jest-leak-detector": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-resolve": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, - "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", - "dev": true, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -27243,7 +35237,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -27253,7 +35246,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -27262,7 +35254,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -27272,7 +35263,6 @@ "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.4" } @@ -27280,57 +35270,60 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "optional": true }, "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==", - "dev": true + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-haste-map": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.3.0.tgz", - "integrity": "sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A==", - "dev": true, + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", @@ -27338,103 +35331,200 @@ } }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==", - "dev": true + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, "jest-worker": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz", - "integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, "realpath-native": { - "version": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" }, "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -27442,23 +35532,25 @@ "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "which": { "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" } @@ -27466,32 +35558,32 @@ } }, "jest-runtime": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.3.0.tgz", - "integrity": "sha512-gn5KYB1wxXRM3nfw8fVpthFu60vxQUCr+ShGq41+ZBFF3DRHZRKj3HDWVAVB4iTNBj2y04QeAo5cZ/boYaPg0w==", - "dev": true, - "requires": { - "@jest/console": "^25.3.0", - "@jest/environment": "^25.3.0", - "@jest/source-map": "^25.2.6", - "@jest/test-result": "^25.3.0", - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", "@types/yargs": "^15.0.0", "chalk": "^3.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.3", - "jest-config": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", "realpath-native": "^2.0.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", @@ -27499,56 +35591,53 @@ }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", + "graceful-fs": "^4.2.4", "source-map": "^0.6.0" } }, "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/transform": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.3.0.tgz", - "integrity": "sha512-W01p8kTDvvEX6kd0tJc7Y5VdYyFaKwNWy1HQz6Jqlhu48z/8Gxp+yFCDVj+H8Rc7ezl3Mg0hDaGuFVkmHOqirg==", - "dev": true, + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.3.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", "jest-regex-util": "^25.2.6", - "jest-util": "^25.3.0", + "jest-util": "^25.5.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "realpath-native": "^2.0.0", @@ -27557,6 +35646,17 @@ "write-file-atomic": "^3.0.0" } }, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", @@ -27575,7 +35675,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -27585,7 +35684,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -27598,7 +35696,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -27606,14 +35703,12 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -27623,7 +35718,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -27646,14 +35740,12 @@ "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 + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -27662,30 +35754,26 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "dev": true, + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "optional": true }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -27696,47 +35784,44 @@ } }, "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==", - "dev": true + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-fullwidth-code-point": { "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 + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "jest-get-type": { - "version": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" }, "jest-haste-map": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.3.0.tgz", - "integrity": "sha512-LjXaRa+F8wwtSxo9G+hHD/Cp63PPQzvaBL9XCVoJD2rrcJO0Zr2+YYzAFWWYJ5GlPUkoaJFJtOuk0sL6MJY80A==", - "dev": true, + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", @@ -27744,68 +35829,100 @@ } }, "jest-message-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.3.0.tgz", - "integrity": "sha512-5QNy9Id4WxJbRITEbA1T1kem9bk7y2fD0updZMSTNHtbEDnYOGLDPAuFBhFgVmOZpv0n6OMdVkK+WhyXEPCcOw==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.3.0.tgz", - "integrity": "sha512-yRn6GbuqB4j3aYu+Z1ezwRiZfp0o9om5uOcBovVtkcRLeBCNP5mT0ysdenUsxAHnQUgGwPOE1wwhtQYe6NKirQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "requires": { - "@jest/types": "^25.3.0" + "@jest/types": "^25.5.0" } }, "jest-regex-util": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==" + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } }, "jest-serializer": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.2.6.tgz", - "integrity": "sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ==", - "dev": true + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "requires": { + "graceful-fs": "^4.2.4" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, "jest-worker": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.2.6.tgz", - "integrity": "sha512-FJn9XDUSxcOR4cwDzRfL1z56rUofNTFs539FGASpd50RHdb6EVkhxQqktodW2mI49l+W3H+tFJDotCHUQF6dmA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "requires": { "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -27813,30 +35930,37 @@ "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -27845,7 +35969,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -27853,14 +35976,23 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-parse": { "version": "1.0.6", @@ -27868,10 +36000,11 @@ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "pretty-format": { - "version": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -27882,46 +36015,71 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", - "dev": true + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "resolve": { - "version": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "requires": { "path-parse": "^1.0.6" } }, "semver": { - "version": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -27932,7 +36090,6 @@ "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" } @@ -27940,14 +36097,12 @@ "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -27956,16 +36111,19 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "which": { "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" } @@ -27974,7 +36132,6 @@ "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", @@ -27985,7 +36142,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -27996,14 +36152,12 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", - "dev": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -28019,10 +36173,9 @@ } }, "yargs-parser": { - "version": "18.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", - "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", - "dev": true, + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -28033,8 +36186,7 @@ "jest-serializer": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", - "dev": true + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==" }, "jest-serializer-enzyme": { "version": "1.0.0", @@ -28063,38 +36215,47 @@ } }, "jest-snapshot": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.3.0.tgz", - "integrity": "sha512-GGpR6Oro2htJPKh5RX4PR1xwo5jCEjtvSPLW1IS7N85y+2bWKbiknHpJJRKSdGXghElb5hWaeQASJI4IiRayGg==", - "dev": true, + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "@types/prettier": "^1.19.0", "chalk": "^3.0.0", - "expect": "^25.3.0", - "jest-diff": "^25.3.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-resolve": "^25.3.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", "make-dir": "^3.0.0", "natural-compare": "^1.4.0", - "pretty-format": "^25.3.0", + "pretty-format": "^25.5.0", "semver": "^6.3.0" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, "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 + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -28104,7 +36265,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -28113,7 +36273,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -28123,7 +36282,6 @@ "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.4" } @@ -28131,124 +36289,246 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } }, "jest-get-type": { "version": "25.2.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==" + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } }, "jest-message-util": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.4.0.tgz", - "integrity": "sha512-LYY9hRcVGgMeMwmdfh9tTjeux1OjZHMusq/E5f3tJN+dAoVVkJtq5ZUEPIcB7bpxDUt2zjUsrwg0EGgPQ+OhXQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } + } + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "requires": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" } }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, "pretty-format": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.4.0.tgz", - "integrity": "sha512-PI/2dpGjXK5HyXexLPZU/jw5T9Q6S1YVXxxVxco+LIqzUFHXIbKZKdUVt7GcX7QUCr31+3fzhi4gN4/wUYPVxQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "requires": { - "@jest/types": "^25.4.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.4.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.4.0.tgz", - "integrity": "sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==" + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -28257,10 +36537,14 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" } } }, @@ -28268,7 +36552,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", - "dev": true, "requires": { "@jest/console": "^24.9.0", "@jest/fake-timers": "^24.9.0", @@ -28288,7 +36571,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -28299,7 +36581,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -28308,7 +36589,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -28318,185 +36598,140 @@ "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==", - "dev": true + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" }, "slash": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, "jest-validate": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.3.0.tgz", - "integrity": "sha512-3WuXgIZ4HXUvW6gk9twFFkT9j6zUorKnF2oEY8VEsHb7x5LGvVlN3WUsbqazVKuyXwvikO2zFJ/YTySMsMje2w==", - "dev": true, + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^24.9.0", "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", "leven": "^3.1.0", - "pretty-format": "^25.3.0" + "pretty-format": "^24.9.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 + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, + "@types/yargs": { + "version": "13.0.9", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.9.tgz", + "integrity": "sha512-xrvhZ4DZewMDhoH1utLtOAwYQy60eYFoXeje30TzM3VOvQlBwQaEpKFq5m34k1wOw2AKIi2pwtiAjdmhvlBUzg==", "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@types/yargs-parser": "*" } }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "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, + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "requires": { - "color-name": "~1.1.4" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "color-name": { - "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 - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" }, "pretty-format": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.3.0.tgz", - "integrity": "sha512-wToHwF8bkQknIcFkBqNfKu4+UZqnrLn/Vr+wwKQwwvPzkBfDDKp/qIabFqdgtoi5PEnM8LFByVsOrHoa3SpTVA==", - "dev": true, - "requires": { - "@jest/types": "^25.3.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "requires": { - "has-flag": "^4.0.0" + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" } } } }, "jest-watcher": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.3.0.tgz", - "integrity": "sha512-dtFkfidFCS9Ucv8azOg2hkiY3sgJEHeTLtGFHS+jfBEE7eRtrO6+2r1BokyDkaG2FOD7485r/SgpC1MFAENfeA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.5.0.tgz", + "integrity": "sha512-XrSfJnVASEl+5+bb51V0Q7WQx65dTSk7NL4yDdVjPnRNpM0hG+ncFmDYJo9O8jaSRcAitVbuVawyXCRoxGrT5Q==", "requires": { - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-util": "^25.5.0", "string-length": "^3.1.0" }, "dependencies": { "@jest/console": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.3.0.tgz", - "integrity": "sha512-LvSDNqpmZIZyweFaEQ6wKY7CbexPitlsLHGJtcooNECo0An/w49rFhjCJzu6efeb6+a3ee946xss1Jcd9r03UQ==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "requires": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" } }, - "@jest/source-map": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.2.6.tgz", - "integrity": "sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ==", - "dev": true, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "@jest/test-result": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.3.0.tgz", - "integrity": "sha512-mqrGuiiPXl1ap09Mydg4O782F3ouDQfsKqtQzIjitpwv3t1cHDwCto21jThw6WRRE+dKcWQvLG70GpyLJICfGw==", - "dev": true, + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "requires": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, "requires": { "type-fest": "^0.11.0" } @@ -28505,17 +36740,23 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -28525,7 +36766,6 @@ "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.4" } @@ -28533,59 +36773,92 @@ "color-name": { "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 + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "requires": { + "to-regex-range": "^5.0.1" + } }, "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==", - "dev": true + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==" }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } }, "jest-util": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.3.0.tgz", - "integrity": "sha512-dc625P/KS/CpWTJJJxKc4bA3A6c+PJGBAqS8JTJqx4HqPoKNqXg/Ec8biL2Z1TabwK7E7Ilf0/ukSEXM1VwzNA==", - "dev": true, + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "requires": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" } }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "requires": { + "is-number": "^7.0.0" + } + }, "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" } } }, @@ -28593,7 +36866,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", - "dev": true, "requires": { "merge-stream": "^2.0.0", "supports-color": "^6.1.0" @@ -28602,14 +36874,12 @@ "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 + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -28619,8 +36889,7 @@ "jetifier": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/jetifier/-/jetifier-1.6.5.tgz", - "integrity": "sha512-T7yzBSu9PR+DqjYt+I0KVO1XTb1QhAfHnXV5Nd3xpbXM6Xg4e3vP60Q4qkNU8Fh6PHC2PivPUNN3rY7G2MxcDQ==", - "dev": true + "integrity": "sha512-T7yzBSu9PR+DqjYt+I0KVO1XTb1QhAfHnXV5Nd3xpbXM6Xg4e3vP60Q4qkNU8Fh6PHC2PivPUNN3rY7G2MxcDQ==" }, "js-base64": { "version": "2.5.2", @@ -28658,14 +36927,12 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, "optional": true }, "jsc-android": { "version": "245459.0.0", "resolved": "https://registry.npmjs.org/jsc-android/-/jsc-android-245459.0.0.tgz", - "integrity": "sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==", - "dev": true + "integrity": "sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg==" }, "jscodeshift": { "version": "0.7.0", @@ -28735,7 +37002,6 @@ "version": "15.2.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", - "dev": true, "requires": { "abab": "^2.0.0", "acorn": "^7.1.0", @@ -28768,8 +37034,7 @@ "acorn": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==" }, "acorn-walk": { "version": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", @@ -28778,14 +37043,12 @@ "cssom": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -28793,14 +37056,12 @@ "parse5": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "dev": true + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" }, "request-promise-core": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", - "dev": true, "requires": { "lodash": "^4.17.15" } @@ -28809,7 +37070,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", - "dev": true, "requires": { "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", @@ -28820,7 +37080,6 @@ "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.28", "punycode": "^2.1.1" @@ -28836,7 +37095,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, "requires": { "ip-regex": "^2.1.0", "psl": "^1.1.28", @@ -28847,7 +37105,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, "requires": { "iconv-lite": "0.4.24" } @@ -28855,11 +37112,18 @@ "ws": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", - "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==", - "dev": true + "integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==" } } }, + "jsdom-jscore-rn": { + "version": "git+https://github.com/iamcco/jsdom-jscore-rn.git#a562f3d57c27c13e5bfc8cf82d496e69a3ba2800", + "from": "git+https://github.com/iamcco/jsdom-jscore-rn.git#a562f3d57c27c13e5bfc8cf82d496e69a3ba2800", + "requires": { + "htmlparser2-without-node-native": "^3.9.2", + "querystring": "^0.2.0" + } + }, "jsesc": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.1.tgz", @@ -28879,20 +37143,17 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, "requires": { "jsonify": "~0.0.0" } @@ -28906,8 +37167,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json2php": { "version": "0.0.4", @@ -28937,7 +37197,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -28945,8 +37204,7 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, "jsonparse": { "version": "1.3.1", @@ -28958,7 +37216,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -29023,7 +37280,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, "requires": { "graceful-fs": "^4.1.9" } @@ -29067,11 +37323,19 @@ } } }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, "requires": { "invert-kv": "^1.0.0" } @@ -29128,7 +37392,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -29608,7 +37871,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -29637,6 +37899,18 @@ "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", "dev": true }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=", + "dev": true + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, "lodash.differencewith": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.differencewith/-/lodash.differencewith-4.5.0.tgz", @@ -29724,8 +37998,7 @@ "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" }, "lodash.template": { "version": "4.5.0", @@ -29749,7 +38022,12 @@ "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", - "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=", "dev": true }, "lodash.uniq": { @@ -29762,7 +38040,6 @@ "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" }, @@ -29771,7 +38048,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -29807,7 +38083,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/logkitty/-/logkitty-0.6.1.tgz", "integrity": "sha512-cHuXN8qUZuzX/7kB6VyS7kB4xyD24e8gyHXIFNhIv+fjW3P+jEXNUhj0o/7qWJtv7UZpbnPgUqzu/AZQ8RAqxQ==", - "dev": true, "requires": { "ansi-fragments": "^0.2.1", "dayjs": "^1.8.15", @@ -29817,14 +38092,12 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -29837,7 +38110,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -29852,7 +38124,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -29861,7 +38132,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -29869,14 +38139,12 @@ "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, "requires": { "invert-kv": "^2.0.0" } @@ -29885,7 +38153,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -29895,7 +38162,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", @@ -29905,14 +38171,12 @@ "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 + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", @@ -29923,7 +38187,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -29932,7 +38195,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -29940,14 +38202,12 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "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" @@ -29956,14 +38216,12 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "yargs": { "version": "12.0.5", "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, "requires": { "cliui": "^4.0.0", "decamelize": "^1.2.0", @@ -29983,7 +38241,6 @@ "version": "11.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -29995,7 +38252,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } @@ -30056,7 +38312,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -30253,7 +38508,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.2.tgz", "integrity": "sha512-UN1dNocxQq44IhJyMI4TU8phc2m9BddacHRPRjKGLYaF0jqd3xLz0jS0skpAU9WgYyoR4gHtUpzytNBS385FWQ==", - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -30504,7 +38758,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -30892,7 +39145,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, "requires": { "readable-stream": "^2.0.1" } @@ -30910,13 +39162,14 @@ "dev": true }, "metro": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro/-/metro-0.56.3.tgz", - "integrity": "sha512-mxHpvBGWanZ46wAEZVLinNO5IYMcFbTdMZIRhC7r+rvoSK6r9iPj95AujBfzLXMAl36RI2O3D7yp5hOYif/gEQ==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.58.0.tgz", + "integrity": "sha512-yi/REXX+/s4r7RjzXht+E+qE6nzvFIrEXO5Q61h+70Q7RODMU8EnlpXx04JYk7DevHuMhFaX+NWhCtRINzR4zA==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "@babel/core": "^7.0.0", - "@babel/generator": "^7.0.0", + "@babel/generator": "^7.5.0", "@babel/parser": "^7.0.0", "@babel/plugin-external-helpers": "^7.0.0", "@babel/template": "^7.0.0", @@ -30924,9 +39177,10 @@ "@babel/types": "^7.0.0", "absolute-path": "^0.0.0", "async": "^2.4.0", - "babel-preset-fbjs": "^3.1.2", + "babel-preset-fbjs": "^3.3.0", "buffer-crc32": "^0.2.13", "chalk": "^2.4.1", + "ci-info": "^2.0.0", "concat-stream": "^1.6.0", "connect": "^3.6.5", "debug": "^2.2.0", @@ -30942,45 +39196,581 @@ "json-stable-stringify": "^1.0.1", "lodash.throttle": "^4.1.1", "merge-stream": "^1.0.1", - "metro-babel-register": "0.56.3", - "metro-babel-transformer": "0.56.3", - "metro-cache": "0.56.3", - "metro-config": "0.56.3", - "metro-core": "0.56.3", - "metro-inspector-proxy": "0.56.3", - "metro-minify-uglify": "0.56.3", - "metro-react-native-babel-preset": "0.56.3", - "metro-resolver": "0.56.3", - "metro-source-map": "0.56.3", - "metro-symbolicate": "0.56.3", + "metro-babel-register": "0.58.0", + "metro-babel-transformer": "0.58.0", + "metro-cache": "0.58.0", + "metro-config": "0.58.0", + "metro-core": "0.58.0", + "metro-inspector-proxy": "0.58.0", + "metro-minify-uglify": "0.58.0", + "metro-react-native-babel-preset": "0.58.0", + "metro-resolver": "0.58.0", + "metro-source-map": "0.58.0", + "metro-symbolicate": "0.58.0", "mime-types": "2.1.11", "mkdirp": "^0.5.1", "node-fetch": "^2.2.0", - "nullthrows": "^1.1.0", + "nullthrows": "^1.1.1", "resolve": "^1.5.0", "rimraf": "^2.5.4", "serialize-error": "^2.1.0", "source-map": "^0.5.6", + "strip-ansi": "^4.0.0", "temp": "0.8.3", "throat": "^4.1.0", "wordwrap": "^1.0.0", "write-file-atomic": "^1.2.0", "ws": "^1.1.5", "xpipe": "^1.0.5", - "yargs": "^9.0.0" + "yargs": "^14.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "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==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "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" + } + }, + "fbjs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", + "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", + "dev": true, + "requires": { + "core-js": "^2.4.1", + "fbjs-css-vars": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "metro-babel-register": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.58.0.tgz", + "integrity": "sha512-P5+G3ufhSYL6cA3a7xkbSJzzFBvtivj/PhWvGXFXnuFssDlMAX1CTktff+0gpka5Cd6B6QLt0UAMWulUAAE4Eg==", + "dev": true, + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "core-js": "^2.2.2", + "escape-string-regexp": "^1.0.5" + } + }, + "metro-babel-transformer": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.58.0.tgz", + "integrity": "sha512-yBX3BkRhw2TCNPhe+pmLSgsAEA3huMvnX08UwjFqSXXI1aiqzRQobn92uKd1U5MM1Vx8EtXVomlJb95ZHNAv6A==", + "dev": true, + "requires": { + "@babel/core": "^7.0.0", + "metro-source-map": "0.58.0" + } + }, + "metro-cache": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.58.0.tgz", + "integrity": "sha512-jjW9zCTKxhgKcVkyQ6LHyna9Zdf4TK/45vvT1fPyyTk1RY82ZYjU1qs+84ycKEd08Ka4YcK9xcUew9SIDJYI8Q==", + "dev": true, + "requires": { + "jest-serializer": "^24.4.0", + "metro-core": "0.58.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + } + }, + "metro-config": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.58.0.tgz", + "integrity": "sha512-4vgBliXwL56vjUlYplvGMVSNrJJpkHuLcD+O20trV3FvPxKg4ZsvuOcNSxqDSMU26FCtIEJ15ojcuCbRL7KY0w==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.5", + "jest-validate": "^24.7.0", + "metro": "0.58.0", + "metro-cache": "0.58.0", + "metro-core": "0.58.0", + "pretty-format": "^24.7.0" + } + }, + "metro-core": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.58.0.tgz", + "integrity": "sha512-RzXUjGFmCLOyzUqcKDvr91AldGtIOxnzNZrWUIiG8uC3kerVLo0mQp4YH3+XVm6fMNiLMg6iER7HLqD+MbpUjQ==", + "dev": true, + "requires": { + "jest-haste-map": "^24.7.1", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.58.0", + "wordwrap": "^1.0.0" + } + }, + "metro-react-native-babel-preset": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.58.0.tgz", + "integrity": "sha512-MRriNW+fF6jxABsgPphocUY6mIhmCm8idcrQZ58fT3Iti2vCdtkaK32TyCGUNUptzhUe2/cbE57j4aC+eaodAA==", + "dev": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.5.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + }, + "metro-resolver": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.58.0.tgz", + "integrity": "sha512-XFbAKvCHN2iWqKeiRARzEXn69eTDdJVJC7lu16S4dPQJ+Dy82dZBr5Es12iN+NmbJuFgrAuIHbpWrdnA9tOf6Q==", + "dev": true, + "requires": { + "absolute-path": "^0.0.0" + } + }, + "metro-source-map": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.58.0.tgz", + "integrity": "sha512-yvN1YPmejmgiiS7T1aKBiiUTHPw2Vcm3r2TZ+DY92z/9PR4alysIywrCs/fTHs8rbDcKM5VfPCKGLpkBrbKeOw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "invariant": "^2.2.4", + "metro-symbolicate": "0.58.0", + "ob1": "0.58.0", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + } + }, + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=", + "dev": true + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "dev": true, + "requires": { + "mime-db": "~1.23.0" + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "dev": true, + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" + } + }, + "yargs-parser": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "metro-babel-register": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.56.3.tgz", + "integrity": "sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "core-js": "^2.2.2", + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" + } + } + }, + "metro-babel-transformer": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz", + "integrity": "sha512-N5/ftb3rBkt6uKlgYAv+lwtzYc4dK0tBpfZ8pjec3kcypGuGTuf4LTHEh65EuzySreLngYI0bQzoFSn3G3DYsw==", + "requires": { + "@babel/core": "^7.0.0", + "metro-source-map": "0.56.3" + } + }, + "metro-cache": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.56.3.tgz", + "integrity": "sha512-SsryVe/TVkt2IkEGnYhB3gQlg9iMlu8WJikQHcCEjMfPEnSIzmeymrX73fwQNPnTnN7F3E0HVjH6Wvq6fh0mcA==", + "requires": { + "jest-serializer": "^24.4.0", + "metro-core": "0.56.3", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "metro-config": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.56.3.tgz", + "integrity": "sha512-C3ZLA5y5gW5auDSQN5dsCTduJg7LXEiX/tLAADOkgXWVImr5P74x9Wt8y1MMWrKx6p+4p5RMDyEwWDMXJt/DwA==", + "requires": { + "cosmiconfig": "^5.0.5", + "jest-validate": "^24.7.0", + "metro": "0.56.3", + "metro-cache": "0.56.3", + "metro-core": "0.56.3", + "pretty-format": "^24.7.0" }, "dependencies": { + "@jest/types": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + } + }, + "@types/yargs": { + "version": "13.0.8", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", + "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", + "requires": { + "@types/yargs-parser": "*" + } + }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -30991,7 +39781,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -31002,7 +39791,6 @@ "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", @@ -31014,14 +39802,12 @@ "core-js": { "version": "2.6.11", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "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" } @@ -31030,7 +39816,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", - "dev": true, "requires": { "core-js": "^2.4.1", "fbjs-css-vars": "^1.0.0", @@ -31046,7 +39831,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0", @@ -31057,7 +39841,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -31071,25 +39854,53 @@ "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" } }, + "jest-validate": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "requires": { + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", + "chalk": "^2.0.1", + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" + }, + "dependencies": { + "pretty-format": { + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "requires": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + } + } + }, "jsonfile": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", @@ -31097,11 +39908,90 @@ "strip-bom": "^3.0.0" } }, + "metro": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.56.3.tgz", + "integrity": "sha512-mxHpvBGWanZ46wAEZVLinNO5IYMcFbTdMZIRhC7r+rvoSK6r9iPj95AujBfzLXMAl36RI2O3D7yp5hOYif/gEQ==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/plugin-external-helpers": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "absolute-path": "^0.0.0", + "async": "^2.4.0", + "babel-preset-fbjs": "^3.1.2", + "buffer-crc32": "^0.2.13", + "chalk": "^2.4.1", + "concat-stream": "^1.6.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "eventemitter3": "^3.0.0", + "fbjs": "^1.0.0", + "fs-extra": "^1.0.0", + "graceful-fs": "^4.1.3", + "image-size": "^0.6.0", + "invariant": "^2.2.4", + "jest-haste-map": "^24.7.1", + "jest-worker": "^24.6.0", + "json-stable-stringify": "^1.0.1", + "lodash.throttle": "^4.1.1", + "merge-stream": "^1.0.1", + "metro-babel-register": "0.56.3", + "metro-babel-transformer": "0.56.3", + "metro-cache": "0.56.3", + "metro-config": "0.56.3", + "metro-core": "0.56.3", + "metro-inspector-proxy": "0.56.3", + "metro-minify-uglify": "0.56.3", + "metro-react-native-babel-preset": "0.56.3", + "metro-resolver": "0.56.3", + "metro-source-map": "0.56.3", + "metro-symbolicate": "0.56.3", + "mime-types": "2.1.11", + "mkdirp": "^0.5.1", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.0", + "resolve": "^1.5.0", + "rimraf": "^2.5.4", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "temp": "0.8.3", + "throat": "^4.1.0", + "wordwrap": "^1.0.0", + "write-file-atomic": "^1.2.0", + "ws": "^1.1.5", + "xpipe": "^1.0.5", + "yargs": "^9.0.0" + } + }, + "metro-inspector-proxy": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz", + "integrity": "sha512-7WtHinw+VJcunQ3q8El1MqqzYSRvXEjW5QE13VYwcLtnay3pvcqACeiQmGbWI0IqxB1+QH8tf3nkA7z7pQ7Vpw==", + "requires": { + "connect": "^3.6.5", + "debug": "^2.2.0", + "rxjs": "^5.4.3", + "ws": "^1.1.5", + "yargs": "^9.0.0" + } + }, + "metro-minify-uglify": { + "version": "0.56.3", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz", + "integrity": "sha512-b9ljyeUpkJWVlFy8M/i4aNbvEBI0zN9vJh1jfU7yx+k9dX7FulLnpGmAQxxQdEszcM//sJrsKNS1oLYBxr0NMQ==", + "requires": { + "uglify-es": "^3.1.9" + } + }, "metro-react-native-babel-preset": { "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz", "integrity": "sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow==", - "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-export-default-from": "^7.0.0", @@ -31144,7 +40034,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz", "integrity": "sha512-fSQtjjy4eiJDThSl9eloxMElhrs+5PQB+DKKzmTFXT8e2GDga+pa1xTBFRUACMO8BXGuWmxR7SnGDw0wo5Ngrw==", - "dev": true, "requires": { "invariant": "^2.2.4", "metro-source-map": "0.56.3", @@ -31156,14 +40045,12 @@ "mime-db": { "version": "1.23.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", - "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=", - "dev": true + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" }, "mime-types": { "version": "2.1.11", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", - "dev": true, "requires": { "mime-db": "~1.23.0" } @@ -31171,29 +40058,20 @@ "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "dev": true + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, "requires": { "pify": "^2.0.0" } }, - "react-refresh": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.2.tgz", - "integrity": "sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==", - "dev": true - }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, "requires": { "load-json-file": "^2.0.0", "normalize-package-data": "^2.3.2", @@ -31204,7 +40082,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^2.0.0" @@ -31214,31 +40091,47 @@ "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "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==", + "requires": { + "symbol-observable": "1.0.1" + } + }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + } } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" }, "write-file-atomic": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -31249,7 +40142,6 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, "requires": { "options": ">=0.0.5", "ultron": "1.0.x" @@ -31259,7 +40151,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, "requires": { "camelcase": "^4.1.0", "cliui": "^3.2.0", @@ -31274,184 +40165,29 @@ "which-module": "^2.0.0", "y18n": "^3.2.1", "yargs-parser": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + } } }, "yargs-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, "requires": { "camelcase": "^4.1.0" - } - } - } - }, - "metro-babel-register": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.56.3.tgz", - "integrity": "sha512-ILCRtNFdW6vzqmLAG2MYWdTSE1vCAZqDKNggiNhlfViuoxmWAIL0vOqixl1CHZF5z4t55+fk46A0jSN7UgPyVw==", - "dev": true, - "requires": { - "@babel/core": "^7.0.0", - "@babel/plugin-proposal-class-properties": "^7.0.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", - "@babel/plugin-proposal-object-rest-spread": "^7.0.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", - "@babel/plugin-proposal-optional-chaining": "^7.0.0", - "@babel/plugin-transform-async-to-generator": "^7.0.0", - "@babel/plugin-transform-flow-strip-types": "^7.0.0", - "@babel/plugin-transform-modules-commonjs": "^7.0.0", - "@babel/register": "^7.0.0", - "core-js": "^2.2.2", - "escape-string-regexp": "^1.0.5" - }, - "dependencies": { - "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true - } - } - }, - "metro-babel-transformer": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.3.tgz", - "integrity": "sha512-N5/ftb3rBkt6uKlgYAv+lwtzYc4dK0tBpfZ8pjec3kcypGuGTuf4LTHEh65EuzySreLngYI0bQzoFSn3G3DYsw==", - "dev": true, - "requires": { - "@babel/core": "^7.0.0", - "metro-source-map": "0.56.3" - } - }, - "metro-cache": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.56.3.tgz", - "integrity": "sha512-SsryVe/TVkt2IkEGnYhB3gQlg9iMlu8WJikQHcCEjMfPEnSIzmeymrX73fwQNPnTnN7F3E0HVjH6Wvq6fh0mcA==", - "dev": true, - "requires": { - "jest-serializer": "^24.4.0", - "metro-core": "0.56.3", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4" - }, - "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "metro-config": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.56.3.tgz", - "integrity": "sha512-C3ZLA5y5gW5auDSQN5dsCTduJg7LXEiX/tLAADOkgXWVImr5P74x9Wt8y1MMWrKx6p+4p5RMDyEwWDMXJt/DwA==", - "dev": true, - "requires": { - "cosmiconfig": "^5.0.5", - "jest-validate": "^24.7.0", - "metro": "0.56.3", - "metro-cache": "0.56.3", - "metro-core": "0.56.3", - "pretty-format": "^24.7.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" - } - }, - "@types/yargs": { - "version": "13.0.8", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", - "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "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==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "leven": "^3.1.0", - "pretty-format": "^24.9.0" }, "dependencies": { - "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", - "dev": true, - "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" } } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true } } }, @@ -31459,7 +40195,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.56.3.tgz", "integrity": "sha512-OAaHP3mBdlACMZRwDJzZzYC0o2S3qfb4BBK75L8H4Ds+y3QUSrjsDEpHACcpaMTOds8rBvjzn+jjB5tqNoHfBA==", - "dev": true, "requires": { "jest-haste-map": "^24.7.1", "lodash.throttle": "^4.1.1", @@ -31468,46 +40203,39 @@ } }, "metro-inspector-proxy": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.56.3.tgz", - "integrity": "sha512-7WtHinw+VJcunQ3q8El1MqqzYSRvXEjW5QE13VYwcLtnay3pvcqACeiQmGbWI0IqxB1+QH8tf3nkA7z7pQ7Vpw==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.58.0.tgz", + "integrity": "sha512-oFqTyNTJdCdvcw1Ha6SKE7ITbSaoTbO4xpYownIoJR+WZ0ZfxbWpp225JkHuBJm9UcBAnG9c0CME924m3uBbaw==", "dev": true, "requires": { "connect": "^3.6.5", "debug": "^2.2.0", "rxjs": "^5.4.3", "ws": "^1.1.5", - "yargs": "^9.0.0" + "yargs": "^14.2.0" }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "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-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, "debug": { @@ -31519,56 +40247,60 @@ "ms": "2.0.0" } }, - "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=", + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "locate-path": "^3.0.0" } }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" } }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "pify": "^2.0.0" + "p-try": "^2.0.0" } }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "p-limit": "^2.0.0" } }, - "read-pkg-up": { + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "rxjs": { "version": "5.5.12", @@ -31579,20 +40311,25 @@ "symbol-observable": "1.0.1" } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } }, "symbol-observable": { "version": "1.0.1", @@ -31600,6 +40337,17 @@ "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", "dev": true }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, "ws": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", @@ -31610,52 +40358,56 @@ "ultron": "1.0.x" } }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "version": "14.2.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-14.2.3.tgz", + "integrity": "sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", + "cliui": "^5.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" + "y18n": "^4.0.0", + "yargs-parser": "^15.0.1" } }, "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.1.tgz", + "integrity": "sha512-0OAMV2mAZQrs3FkNpDQcBk1x5HXb8X4twADss4S0Iuk+2dGnLOE/fRHrsYm542GduMveyA77OF4wrNJuanRCWw==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } }, "metro-minify-uglify": { - "version": "0.56.3", - "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.56.3.tgz", - "integrity": "sha512-b9ljyeUpkJWVlFy8M/i4aNbvEBI0zN9vJh1jfU7yx+k9dX7FulLnpGmAQxxQdEszcM//sJrsKNS1oLYBxr0NMQ==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.58.0.tgz", + "integrity": "sha512-vRHsA7bCi7eCn3LXLm20EfY2NoWDyYOnmWaq/N8LB0OxL2L5DXRqMYAQK+prWGJ5S1yvVnDuuNVP+peQ9851TA==", "dev": true, "requires": { "uglify-es": "^3.1.9" } }, "metro-react-native-babel-preset": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.55.0.tgz", - "integrity": "sha512-HUI+dEiVym8f1NYIF1grY9PdoY0d3SSS/HED2dDDvTORwndsAEWuXiUgKFOGWX18+RUAQog8obVQuBMgrr8ZBQ==", - "dev": true, + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.57.0.tgz", + "integrity": "sha512-pvLh1QOwdxsjgYE2a+4aTKs3LSF3+t4jscxHtkND6wsJnKVVspLt8FkDaORa6zr3Fq12tVpEt5NJMdgtWqBpaA==", "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-export-default-from": "^7.0.0", @@ -31691,46 +40443,102 @@ "@babel/plugin-transform-typescript": "^7.0.0", "@babel/plugin-transform-unicode-regex": "^7.0.0", "@babel/template": "^7.0.0", - "react-refresh": "^0.2.0" + "react-refresh": "^0.4.0" } }, "metro-react-native-babel-transformer": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.55.0.tgz", - "integrity": "sha512-K5dJh/HXkebKnSgJJ8XeWliwJFmit1u7CnswbhoYd0XTQQIYj6HV+neN/FzJV5tvkFkQC3asH+5xAW92HE6uRg==", - "dev": true, + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.0.tgz", + "integrity": "sha512-9eJ6kzizy80KlqNryg9TjlHdA4PZPWw0TV8Ih7H6RmYmuMzac5gjIW9FUrXsVWI56kQf+L5SdD/dCOWDqez/lQ==", "requires": { "@babel/core": "^7.0.0", "babel-preset-fbjs": "^3.1.2", - "metro-babel-transformer": "0.55.0", - "metro-react-native-babel-preset": "0.55.0", - "metro-source-map": "0.55.0" + "metro-babel-transformer": "0.56.0", + "metro-react-native-babel-preset": "0.56.0", + "metro-source-map": "0.56.0" }, "dependencies": { "metro-babel-transformer": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.55.0.tgz", - "integrity": "sha512-eKslZokx7g0xKinJztOGELlR5N3F9oKVN5Eb9srwgFlfldY2VXN1BIYj8EBKgCA7JWgK4Rqo18/r+u+ktXzlPA==", - "dev": true, + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.0.tgz", + "integrity": "sha512-8w/NpcKovmzkY4/++zX5v+OLOcBPXC9iygNI0ZdexA9U5/ncAY3U1VaF2ScFKzhrpkb8AJioYYioAgrRMLYStg==", "requires": { "@babel/core": "^7.0.0", - "metro-source-map": "0.55.0" + "metro-source-map": "0.56.0" + } + }, + "metro-react-native-babel-preset": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.0.tgz", + "integrity": "sha512-MAo1fm0dNn6MVZmylaz6k2HC1MINHLTLfE7O3a9Xz3fAtbGbApisp06rBUfK5uUqIJDmAaKgbiT34lHJSIiE6Q==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" } }, "metro-source-map": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.55.0.tgz", - "integrity": "sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw==", - "dev": true, + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.0.tgz", + "integrity": "sha512-W3c91L+CtbQTRxOrcVteCi5XlSXh+L0Zy85YBwm+FkWTKfrYjacr/yW1S9/LutpLgWE0W0VBeQeY++aRHwpx0g==", "requires": { "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", "invariant": "^2.2.4", - "metro-symbolicate": "0.55.0", - "ob1": "0.55.0", + "metro-symbolicate": "0.56.0", + "ob1": "0.56.0", "source-map": "^0.5.6", "vlq": "^1.0.0" } + }, + "metro-symbolicate": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.0.tgz", + "integrity": "sha512-5gJtwdSS0eYlTYB7PXatohBknz1sWUTfMBhwjn6zbgoyR6Apkpl2t2TfZxwfDTauhcEV1gRLmuodrVENs01r8g==", + "requires": { + "invariant": "^2.2.4", + "metro-source-map": "0.56.0", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + } + }, + "ob1": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.56.0.tgz", + "integrity": "sha512-3rvepvXPw+OIkcut4MaRYIoy4thTWvWhTK+Hg4+y9fOBWVF9acpBvtm2NSbH9Vw9UBG/9v+T5euwPxUSUIDPWw==" } } }, @@ -31738,7 +40546,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.56.3.tgz", "integrity": "sha512-VvMl4xUp0fy76WiP3YDtzMmrn6tN/jwxOBqlTy9MjN6R9sUXrGyO5thwn/uKQqp5vwBTuJev7nZL7OKzwludKA==", - "dev": true, "requires": { "absolute-path": "^0.0.0" } @@ -31747,7 +40554,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.3.tgz", "integrity": "sha512-CheqWbJZSM0zjcNBqELUiocwH3XArrOk6alhVuzJ2gV/WTMBQFwP0TtQssSMwjnouMHNEzY8RxErXKXBk/zJmQ==", - "dev": true, "requires": { "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", @@ -31762,7 +40568,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.3.tgz", "integrity": "sha512-fSQtjjy4eiJDThSl9eloxMElhrs+5PQB+DKKzmTFXT8e2GDga+pa1xTBFRUACMO8BXGuWmxR7SnGDw0wo5Ngrw==", - "dev": true, "requires": { "invariant": "^2.2.4", "metro-source-map": "0.56.3", @@ -31774,34 +40579,34 @@ "ob1": { "version": "0.56.3", "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.56.3.tgz", - "integrity": "sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ==", - "dev": true + "integrity": "sha512-3JL2ZyWOHDGTEAe4kcG+TxhGPKCCikgyoUIjE82JnXnmpR1LXItM9K3WhGsi4+O7oYngMW6FjpHHoc5xJTMkTQ==" } } }, "metro-symbolicate": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.55.0.tgz", - "integrity": "sha512-3r3Gpv5L4U7rBGpIqw5S1nun5MelfUMLRiScJsPRGZVTX3WY1w+zpaQKlWBi5yuHf5dMQ+ZUVbhb02IdrfJ2Fg==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.58.0.tgz", + "integrity": "sha512-uIVxUQC1E26qOMj13dKROhwAa2FmZk5eR0NcBqej/aXmQhpr8LjJg2sondkoLKUp827Tf/Fm9+pS4icb5XiqCw==", "dev": true, "requires": { - "metro-source-map": "0.55.0", + "invariant": "^2.2.4", + "metro-source-map": "0.58.0", "source-map": "^0.5.6", "through2": "^2.0.1", "vlq": "^1.0.0" }, "dependencies": { "metro-source-map": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.55.0.tgz", - "integrity": "sha512-HZODA0KPl5onJNGIztfTHHWurR2nL6Je/X8wwj+bL4ZBB/hSMVeDk7rWReCAvO3twVz7Ztp8Si0jfMmmH4Ruuw==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.58.0.tgz", + "integrity": "sha512-yvN1YPmejmgiiS7T1aKBiiUTHPw2Vcm3r2TZ+DY92z/9PR4alysIywrCs/fTHs8rbDcKM5VfPCKGLpkBrbKeOw==", "dev": true, "requires": { "@babel/traverse": "^7.0.0", "@babel/types": "^7.0.0", "invariant": "^2.2.4", - "metro-symbolicate": "0.55.0", - "ob1": "0.55.0", + "metro-symbolicate": "0.58.0", + "ob1": "0.58.0", "source-map": "^0.5.6", "vlq": "^1.0.0" } @@ -31847,20 +40652,17 @@ "mime": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "dev": true + "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==" }, "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==" }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, "requires": { "mime-db": "~1.33.0" } @@ -31868,8 +40670,7 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, "mimic-response": { "version": "2.1.0", @@ -31966,7 +40767,6 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -31975,8 +40775,7 @@ "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" } } }, @@ -32062,7 +40861,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, "requires": { "minipass": "^2.2.1" } @@ -32126,7 +40924,6 @@ "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" }, @@ -32134,8 +40931,7 @@ "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" } } }, @@ -32183,7 +40979,6 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", - "dev": true, "requires": { "basic-auth": "~2.0.0", "debug": "2.6.9", @@ -32196,7 +40991,6 @@ "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" } @@ -32273,8 +41067,7 @@ "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" }, "mz": { "version": "2.7.0", @@ -32290,8 +41083,7 @@ "nan": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" }, "nanomatch": { "version": "1.2.13", @@ -32314,8 +41106,7 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "nearley": { "version": "2.15.1", @@ -32342,7 +41133,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "dev": true, "requires": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", @@ -32353,7 +41143,6 @@ "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, "requires": { "ms": "^2.1.1" } @@ -32361,16 +41150,14 @@ "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 + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true + "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" }, "neo-async": { "version": "2.5.1", @@ -32556,7 +41343,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz", "integrity": "sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==", - "dev": true, "requires": { "growly": "^1.3.0", "semver": "^5.5.0", @@ -32567,8 +41353,7 @@ "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" } } }, @@ -33003,7 +41788,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", @@ -33014,8 +41798,7 @@ "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" } } }, @@ -33048,8 +41831,7 @@ "npm-bundled": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", - "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", - "dev": true + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==" }, "npm-lifecycle": { "version": "3.1.4", @@ -33692,7 +42474,6 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz", "integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==", - "dev": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1" @@ -33741,7 +42522,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -33761,8 +42541,7 @@ "nullthrows": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", - "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==", - "dev": true + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" }, "num2fraction": { "version": "1.2.2", @@ -33773,25 +42552,22 @@ "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 + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" }, "ob1": { - "version": "0.55.0", - "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.55.0.tgz", - "integrity": "sha512-pfyiMVsUItl8WiRKMT15eCi662pCRAuYTq2+V3UpE+PpFErJI/TvRh/M/l/9TaLlbFr7krJ7gdl+FXJNcybmvw==", + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.58.0.tgz", + "integrity": "sha512-uZP44cbowAfHafP1k4skpWItk5iHCoRevMfrnUvYCfyNNPPJd3rfDCyj0exklWi2gDXvjlj2ObsfiqP/bs/J7Q==", "dev": true }, "object-assign": { @@ -33942,8 +42718,7 @@ "on-headers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, "once": { "version": "1.4.0", @@ -33957,7 +42732,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, "requires": { "mimic-fn": "^1.0.0" } @@ -33966,7 +42740,6 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", - "dev": true, "requires": { "is-wsl": "^1.1.0" } @@ -34011,7 +42784,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -34024,8 +42796,7 @@ "options": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" }, "ora": { "version": "4.0.2", @@ -34131,14 +42902,12 @@ "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 + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, "requires": { "execa": "^0.7.0", "lcid": "^1.0.0", @@ -34149,7 +42918,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -34159,6 +42927,11 @@ "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" } } }, @@ -34175,14 +42948,12 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -34197,14 +42968,12 @@ "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" }, "p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", - "dev": true + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" }, "p-event": { "version": "4.1.0", @@ -34223,14 +42992,12 @@ "p-is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, "requires": { "p-try": "^1.0.0" } @@ -34239,7 +43006,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, "requires": { "p-limit": "^1.1.0" } @@ -34295,8 +43061,7 @@ "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, "p-waterfall": { "version": "1.0.0", @@ -34378,7 +43143,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, "requires": { "error-ex": "^1.2.0" } @@ -34386,8 +43150,7 @@ "parse-node-version": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", - "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", - "dev": true + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" }, "parse-passwd": { "version": "1.0.0", @@ -34429,8 +43192,7 @@ "parseurl": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true + "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" }, "pascalcase": { "version": "0.1.1", @@ -34525,8 +43287,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "phpegjs": { "version": "1.0.0-beta7", @@ -34541,8 +43302,7 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" }, "pinkie": { "version": "2.0.4", @@ -34604,7 +43364,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", - "dev": true, "requires": { "base64-js": "^1.2.3", "xmlbuilder": "^9.0.7", @@ -34615,7 +43374,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", - "dev": true, "requires": { "ansi-cyan": "^0.1.1", "ansi-red": "^0.1.1", @@ -34628,7 +43386,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", - "dev": true, "requires": { "arr-flatten": "^1.0.1", "array-slice": "^0.2.3" @@ -34637,14 +43394,12 @@ "arr-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", - "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", - "dev": true + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=" }, "extend-shallow": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", - "dev": true, "requires": { "kind-of": "^1.1.0" } @@ -34652,8 +43407,7 @@ "kind-of": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", - "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", - "dev": true + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=" } } }, @@ -34669,8 +43423,7 @@ "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" }, "pnp-webpack-plugin": { "version": "1.5.0", @@ -35670,8 +44423,7 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "1.0.4", @@ -35708,7 +44460,6 @@ "version": "24.7.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.7.0.tgz", "integrity": "sha512-apen5cjf/U4dj7tHetpC7UEFCvtAgnNZnBDkfPv3fokzIqyOJckAG9OlAPC1BlFALnqT/lGB2tl9EJjlK6eCsA==", - "dev": true, "requires": { "@jest/types": "^24.7.0", "ansi-regex": "^4.0.0", @@ -35720,7 +44471,6 @@ "version": "24.9.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", @@ -35731,7 +44481,6 @@ "version": "13.0.8", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.8.tgz", "integrity": "sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -35739,8 +44488,7 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" } } }, @@ -35762,8 +44510,7 @@ "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", - "dev": true + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" }, "process": { "version": "0.11.10", @@ -36149,14 +44896,12 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, "psl": { "version": "1.1.28", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.28.tgz", - "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==", - "dev": true + "integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==" }, "public-encrypt": { "version": "4.0.3", @@ -36370,8 +45115,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer": { "version": "npm:puppeteer-core@3.0.0", @@ -36464,15 +45208,6 @@ "pend": "~1.2.0" } }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -36592,8 +45327,7 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "querystring-es3": { "version": "0.2.1", @@ -36666,8 +45400,7 @@ "range-parser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true + "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" }, "raw-body": { "version": "2.4.0", @@ -36743,7 +45476,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, "requires": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -37089,7 +45821,6 @@ "version": "3.6.3", "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-3.6.3.tgz", "integrity": "sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ==", - "dev": true, "requires": { "shell-quote": "^1.6.1", "ws": "^3.3.1" @@ -37098,14 +45829,12 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", - "dev": true, "requires": { "async-limiter": "~1.0.0", "safe-buffer": "~5.1.0", @@ -37339,7 +46068,6 @@ "version": "0.61.5", "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.61.5.tgz", "integrity": "sha512-MXqE3NoGO0T3dUKIKkIppijBhRRMpfN6ANbhMXHDuyfA+fSilRWgCwYgR/YNCC7ntECoJYikKaNTUBB0DeQy6Q==", - "dev": true, "requires": { "@babel/runtime": "^7.0.0", "@react-native-community/cli": "^3.0.0", @@ -37376,7 +46104,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-3.0.4.tgz", "integrity": "sha512-kt+ENtC+eRUSfWPbbpx3r7fAQDcFwgM03VW/lBdVAUjkNxffPFT2GGdK23CJSBOXTjRSiGuwhvwH4Z28PdrlRA==", - "dev": true, "requires": { "@hapi/joi": "^15.0.3", "@react-native-community/cli-debugger-ui": "^3.0.0", @@ -37422,7 +46149,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -37432,28 +46158,69 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" } } }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } }, "core-js": { "version": "2.6.11", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", - "dev": true + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==" }, "cosmiconfig": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, "requires": { "import-fresh": "^2.0.0", "is-directory": "^0.3.1", @@ -37465,7 +46232,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -37477,22 +46243,27 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, "deepmerge": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz", - "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==", - "dev": true + "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==" }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -37507,7 +46278,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, "requires": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", @@ -37518,7 +46288,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", - "dev": true, "requires": { "core-js": "^2.4.1", "fbjs-css-vars": "^1.0.0", @@ -37534,7 +46303,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -37544,7 +46312,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -37555,7 +46322,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, "requires": { "pump": "^3.0.0" } @@ -37564,7 +46330,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", - "dev": true, "requires": { "caller-path": "^2.0.0", "resolve-from": "^3.0.0" @@ -37574,7 +46339,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", - "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", @@ -37596,7 +46360,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -37607,27 +46370,285 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, + "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=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + } + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "requires": { "p-locate": "^4.1.0" } }, + "metro": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.56.4.tgz", + "integrity": "sha512-Kt3OQJQtQdts0JrKnyGdLpKHDjqYBgIfzvYrvfhmFCkKuZ8aqRlVnvpfjQ4/OBm0Fmm9NyyxbNRD9VIbj7WjnA==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/plugin-external-helpers": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "absolute-path": "^0.0.0", + "async": "^2.4.0", + "babel-preset-fbjs": "^3.1.2", + "buffer-crc32": "^0.2.13", + "chalk": "^2.4.1", + "concat-stream": "^1.6.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "eventemitter3": "^3.0.0", + "fbjs": "^1.0.0", + "fs-extra": "^1.0.0", + "graceful-fs": "^4.1.3", + "image-size": "^0.6.0", + "invariant": "^2.2.4", + "jest-haste-map": "^24.7.1", + "jest-worker": "^24.6.0", + "json-stable-stringify": "^1.0.1", + "lodash.throttle": "^4.1.1", + "merge-stream": "^1.0.1", + "metro-babel-register": "^0.56.4", + "metro-babel-transformer": "^0.56.4", + "metro-cache": "^0.56.4", + "metro-config": "^0.56.4", + "metro-core": "^0.56.4", + "metro-inspector-proxy": "^0.56.4", + "metro-minify-uglify": "^0.56.4", + "metro-react-native-babel-preset": "^0.56.4", + "metro-resolver": "^0.56.4", + "metro-source-map": "^0.56.4", + "metro-symbolicate": "^0.56.4", + "mime-types": "2.1.11", + "mkdirp": "^0.5.1", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.0", + "resolve": "^1.5.0", + "rimraf": "^2.5.4", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "temp": "0.8.3", + "throat": "^4.1.0", + "wordwrap": "^1.0.0", + "write-file-atomic": "^1.2.0", + "ws": "^1.1.5", + "xpipe": "^1.0.5", + "yargs": "^9.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "metro-babel-register": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.56.4.tgz", + "integrity": "sha512-Phm6hMluOWYqfykftjJ1jsTpWvbgb49AC/1taxEctxUdRCZlFgZwBleJZAhQYxJD5J+ikFkEbHDzePEXb29KVA==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "core-js": "^2.2.2", + "escape-string-regexp": "^1.0.5" + } + }, + "metro-babel-transformer": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.56.4.tgz", + "integrity": "sha512-IOi4ILgZvaX7GCGHBJp79paNVOq5QxhhbyqAdEJgDP8bHfl/OVHoVKSypfrsMSKSiBrqxhIjyc4XjkXsQtkx5g==", + "requires": { + "@babel/core": "^7.0.0", + "metro-source-map": "^0.56.4" + } + }, + "metro-config": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.56.4.tgz", + "integrity": "sha512-O85QDHwWdMn/8ERe13y4a6vbZL0AHyO8atTvL+9BCulLEO+FQBi1iJjr3+ViLa8cf0m5dRftDsa7P47m5euk4A==", + "requires": { + "cosmiconfig": "^5.0.5", + "jest-validate": "^24.7.0", + "metro": "^0.56.4", + "metro-cache": "^0.56.4", + "metro-core": "^0.56.4", + "pretty-format": "^24.7.0" + } + }, + "metro-core": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.56.4.tgz", + "integrity": "sha512-hMzkBdgPt5Zm9nr/1KtIT+A6H7TNiLVCEGG5OiAXj8gTRsA2yy7wAdQpwy0xbE+zi88t/pLOzXpd3ClG/YxyWg==", + "requires": { + "jest-haste-map": "^24.7.1", + "lodash.throttle": "^4.1.1", + "metro-resolver": "^0.56.4", + "wordwrap": "^1.0.0" + } + }, + "metro-react-native-babel-preset": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.4.tgz", + "integrity": "sha512-CzbBDM9Rh6w8s1fq+ZqihAh7DDqUAcfo9pPww25+N/eJ7UK436Q7JdfxwdIPpBwLFn6o6MyYn+uwL9OEWBJarA==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.4.0" + } + }, + "metro-source-map": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.4.tgz", + "integrity": "sha512-f1P9/rpFmG3Z0Jatiw2zvLItx1TwR7mXTSDj4qLDCWeVMB3kEXAr3R0ucumTW8c6HfpJljeRBWzYFXF33fd81g==", + "requires": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "invariant": "^2.2.4", + "metro-symbolicate": "^0.56.4", + "ob1": "^0.56.4", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + } + } + } + }, + "metro-cache": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.56.4.tgz", + "integrity": "sha512-d1hiUSKwtRsuMxUhHVJ3tjK2BbpUlJGvTyMWohK8Wxx+0GbnWRWWFcI4vlCzlZfoK0VtZK2MJEl5t7Du1mIniQ==", + "requires": { + "jest-serializer": "^24.4.0", + "metro-core": "^0.56.4", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + }, + "dependencies": { + "metro-core": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.56.4.tgz", + "integrity": "sha512-hMzkBdgPt5Zm9nr/1KtIT+A6H7TNiLVCEGG5OiAXj8gTRsA2yy7wAdQpwy0xbE+zi88t/pLOzXpd3ClG/YxyWg==", + "requires": { + "jest-haste-map": "^24.7.1", + "lodash.throttle": "^4.1.1", + "metro-resolver": "^0.56.4", + "wordwrap": "^1.0.0" + } + } + } + }, + "metro-inspector-proxy": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.56.4.tgz", + "integrity": "sha512-E1S3MO25mWKmcLn1UQuCDiS0hf9P2Fwq8sEAX5lBLoZbehepNH+4xJ3xXSY51JX4dozBrE8GGoKL4ll3II40LA==", + "requires": { + "connect": "^3.6.5", + "debug": "^2.2.0", + "rxjs": "^5.4.3", + "ws": "^1.1.5", + "yargs": "^9.0.0" + } + }, + "metro-minify-uglify": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.56.4.tgz", + "integrity": "sha512-BHgj7+BKEK2pHvWHUR730bIrsZwl8DPtr49x9L0j2grPZ5/UROWXzEr8VZgIss7fl64t845uu1HXNNyuSj2EhA==", + "requires": { + "uglify-es": "^3.1.9" + } + }, "metro-react-native-babel-preset": { "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz", "integrity": "sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow==", - "dev": true, "requires": { "@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-export-default-from": "^7.0.0", @@ -37670,7 +46691,6 @@ "version": "0.56.3", "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.3.tgz", "integrity": "sha512-T87m4jDu0gIvJo8kWEvkodWFgQ8XBzJUESs1hUUTBSMIqTa31MdWfA1gs+MipadG7OsEJpcb9m83mGr8K70MWw==", - "dev": true, "requires": { "@babel/core": "^7.0.0", "babel-preset-fbjs": "^3.1.2", @@ -37679,11 +46699,69 @@ "metro-source-map": "0.56.3" } }, + "metro-resolver": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.56.4.tgz", + "integrity": "sha512-Ug4ulVfpkKZ1Wu7mdYj9XLGuOqZTuWCqEhyx3siKTc/2eBwKZQXmiNo5d/IxWNvmwL/87Abeb724I6CMzMfjiQ==", + "requires": { + "absolute-path": "^0.0.0" + } + }, + "metro-symbolicate": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz", + "integrity": "sha512-8mCNNn6zV5FFKCIcRgI7736Xl+owgvYuy8qanPxZN36f7utiWRYeB+PirEBPcglBk4qQvoy2lT6oPULNXZQbbQ==", + "requires": { + "invariant": "^2.2.4", + "metro-source-map": "^0.56.4", + "source-map": "^0.5.6", + "through2": "^2.0.1", + "vlq": "^1.0.0" + }, + "dependencies": { + "metro-source-map": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.56.4.tgz", + "integrity": "sha512-f1P9/rpFmG3Z0Jatiw2zvLItx1TwR7mXTSDj4qLDCWeVMB3kEXAr3R0ucumTW8c6HfpJljeRBWzYFXF33fd81g==", + "requires": { + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "invariant": "^2.2.4", + "metro-symbolicate": "^0.56.4", + "ob1": "^0.56.4", + "source-map": "^0.5.6", + "vlq": "^1.0.0" + } + } + } + }, + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "~1.23.0" + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "ob1": { + "version": "0.56.4", + "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.56.4.tgz", + "integrity": "sha512-URgFof9z2wotiYFsqlydXtQfGV81gvBI2ODy64xfd3vPo+AYom5PVDX4t4zn23t/O+S2IxqApSQM8uJAybmz7w==" + }, "ora": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", - "dev": true, "requires": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", @@ -37697,7 +46775,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -37710,7 +46787,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -37719,7 +46795,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -37727,14 +46802,12 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" @@ -37743,14 +46816,20 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } }, "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" @@ -37759,20 +46838,112 @@ "react-refresh": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.2.tgz", - "integrity": "sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==", - "dev": true + "integrity": "sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==" + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + } + } + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "requires": { + "symbol-observable": "1.0.1" + } }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" }, @@ -37780,26 +46951,229 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" } } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "symbol-observable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", + "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" + }, "whatwg-fetch": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==", - "dev": true + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } }, "ws": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, "requires": { "options": ">=0.0.5", "ultron": "1.0.x" } + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "react-native-animatable": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/react-native-animatable/-/react-native-animatable-1.3.3.tgz", + "integrity": "sha512-2ckIxZQAsvWn25Ho+DK3d1mXIgj7tITkrS4pYDvx96WyOttSvzzFeQnM2od0+FUMzILbdHDsDEqZvnz1DYNQ1w==", + "requires": { + "prop-types": "^15.7.2" + } + }, + "react-native-dark-mode": { + "version": "git+https://github.com/wordpress-mobile/react-native-dark-mode.git#f09bf1480e7b34536413ab3300f29e4375edb2c6", + "from": "git+https://github.com/wordpress-mobile/react-native-dark-mode.git#f09bf1480e7b34536413ab3300f29e4375edb2c6", + "requires": { + "@types/events": "^3.0.0", + "@types/react": "^16.8.19", + "@types/react-native": "^0.57.60", + "events": "3.0.0", + "toolkit.ts": "0.0.2" + }, + "dependencies": { + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==" + } + } + }, + "react-native-get-random-values": { + "version": "git+https://github.com/wordpress-mobile/react-native-get-random-values.git#f03f2c16414aff4ea76064dcd00a9e3c6efc838d", + "from": "git+https://github.com/wordpress-mobile/react-native-get-random-values.git#f03f2c16414aff4ea76064dcd00a9e3c6efc838d", + "requires": { + "fast-base64-decode": "^1.0.0" + } + }, + "react-native-hr": { + "version": "git+https://github.com/Riglerr/react-native-hr.git#2d01a5cf77212d100e8b99e0310cce5234f977b3", + "from": "git+https://github.com/Riglerr/react-native-hr.git#2d01a5cf77212d100e8b99e0310cce5234f977b3" + }, + "react-native-hsv-color-picker": { + "version": "git+https://github.com/wordpress-mobile/react-native-hsv-color-picker.git#163e78cd4d986a28954a626213b40daee15774e8", + "from": "git+https://github.com/wordpress-mobile/react-native-hsv-color-picker.git", + "requires": { + "react-native-linear-gradient": "git+https://github.com/wordpress-mobile/react-native-linear-gradient.git#52bf43077171cff8714ce3e0155f3ebb7f55bc37", + "tinycolor2": "^1.4.1" + } + }, + "react-native-iphone-x-helper": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-native-iphone-x-helper/-/react-native-iphone-x-helper-1.2.1.tgz", + "integrity": "sha512-/VbpIEp8tSNNHIvstuA3Swx610whci1Zpc9mqNkqn14DkMbw+ORviln2u0XyHG1kPvvwTNGZY6QpeFwxYaSdbQ==" + }, + "react-native-keyboard-aware-scroll-view": { + "version": "git+https://github.com/wordpress-mobile/react-native-keyboard-aware-scroll-view.git#678a4d459caa2f7f448202574dddc6a19954500c", + "from": "git+https://github.com/wordpress-mobile/react-native-keyboard-aware-scroll-view.git#gb-v0.8.8", + "requires": { + "prop-types": "^15.6.2", + "react-native-iphone-x-helper": "^1.0.3" + } + }, + "react-native-linear-gradient": { + "version": "git+https://github.com/wordpress-mobile/react-native-linear-gradient.git#52bf43077171cff8714ce3e0155f3ebb7f55bc37", + "from": "git+https://github.com/wordpress-mobile/react-native-linear-gradient.git#52bf43077171cff8714ce3e0155f3ebb7f55bc37" + }, + "react-native-modal": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-native-modal/-/react-native-modal-6.5.0.tgz", + "integrity": "sha512-ewchdETAGd32xLGLK93NETEGkRcePtN7ZwjmLSQnNW1Zd0SRUYE8NqftjamPyfKvK0i2DZjX4YAghGZTqaRUbA==", + "requires": { + "prop-types": "^15.6.1", + "react-native-animatable": "^1.2.4" + } + }, + "react-native-safe-area": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/react-native-safe-area/-/react-native-safe-area-0.5.1.tgz", + "integrity": "sha512-gBLv93P90sM6hk5HzUwTXzFuSDazTpg2ONi5iL9pnUsUfwdw2L9SKgjgVroxX10leGB9+0zz6/ycV+mItqr8OQ==", + "requires": { + "@types/react": "^16.8.8" + } + }, + "react-native-sass-transformer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-native-sass-transformer/-/react-native-sass-transformer-1.4.0.tgz", + "integrity": "sha512-PlRiaJIcDzYpIVDH0OQuabkMGy/zp7N/A14rqhBrFqhADXC0xR2W53Cb7CicL9CsOL4y7Sh2dv4pgMvqgMdwqQ==", + "requires": { + "app-root-path": "^2.1.0", + "css-to-react-native-transform": "^1.8.1", + "semver": "^5.6.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "react-native-svg": { + "version": "git+https://github.com/wordpress-mobile/react-native-svg.git#a628e92990a2404e30a0086f168bd2b5b7b4ce96", + "from": "git+https://github.com/wordpress-mobile/react-native-svg.git#a628e92990a2404e30a0086f168bd2b5b7b4ce96", + "requires": { + "css-select": "^2.0.2", + "css-tree": "^1.0.0-alpha.37" + }, + "dependencies": { + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-tree": { + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "requires": { + "mdn-data": "2.0.6", + "source-map": "^0.6.1" + } + }, + "css-what": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", + "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==" + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==" + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "requires": { + "boolbase": "~1.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -37823,6 +47197,13 @@ } } }, + "react-native-video": { + "version": "git+https://github.com/wordpress-mobile/react-native-video.git#1b964b107863351ed744fc104d7952bbec3e2d4f", + "from": "git+https://github.com/wordpress-mobile/react-native-video.git#1b964b107863351ed744fc104d7952bbec3e2d4f", + "requires": { + "prop-types": "^15.5.10" + } + }, "react-outside-click-handler": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/react-outside-click-handler/-/react-outside-click-handler-1.2.2.tgz", @@ -37920,10 +47301,9 @@ } }, "react-refresh": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.2.0.tgz", - "integrity": "sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg==", - "dev": true + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.2.tgz", + "integrity": "sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ==" }, "react-resize-aware": { "version": "3.0.1", @@ -38349,14 +47729,12 @@ "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", - "dev": true + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" }, "regenerate-unicode-properties": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", - "dev": true, "requires": { "regenerate": "^1.4.0" } @@ -38364,14 +47742,12 @@ "regenerator-runtime": { "version": "0.13.2", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", - "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", - "dev": true + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" }, "regenerator-transform": { "version": "0.14.4", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", - "dev": true, "requires": { "@babel/runtime": "^7.8.4", "private": "^0.1.8" @@ -38511,7 +47887,6 @@ "version": "4.7.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", - "dev": true, "requires": { "regenerate": "^1.4.0", "regenerate-unicode-properties": "^8.2.0", @@ -38530,14 +47905,12 @@ "regjsgen": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz", - "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==", - "dev": true + "integrity": "sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg==" }, "regjsparser": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", - "dev": true, "requires": { "jsesc": "~0.5.0" }, @@ -38545,8 +47918,7 @@ "jsesc": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" } } }, @@ -38917,7 +48289,6 @@ "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", @@ -38944,14 +48315,12 @@ "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "dev": true + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dev": true, "requires": { "mime-db": "1.40.0" } @@ -38959,8 +48328,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -38992,8 +48360,7 @@ "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "requireindex": { "version": "1.2.0", @@ -39082,8 +48449,7 @@ "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" }, "resolve-url": { "version": "0.2.1", @@ -39103,7 +48469,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" @@ -39151,7 +48516,6 @@ "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" }, @@ -39160,7 +48524,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -39244,7 +48607,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, "requires": { "is-promise": "^2.1.0" }, @@ -39252,8 +48614,7 @@ "is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" } } }, @@ -39292,14 +48653,12 @@ "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" }, "rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, "requires": { "rx-lite": "*" } @@ -39606,14 +48965,12 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" }, "saxes": { "version": "3.1.11", "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "dev": true, "requires": { "xmlchars": "^2.1.1" } @@ -39680,7 +49037,6 @@ "version": "0.16.2", "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -39701,7 +49057,6 @@ "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" } @@ -39709,16 +49064,14 @@ "mime": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true + "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" } } }, "serialize-error": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", - "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=", - "dev": true + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=" }, "serialize-javascript": { "version": "1.5.0", @@ -39757,7 +49110,6 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -39804,8 +49156,7 @@ "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" }, "sha.js": { "version": "2.4.11", @@ -39849,7 +49200,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", - "dev": true, "requires": { "array-filter": "~0.0.0", "array-map": "~0.0.0", @@ -39860,8 +49210,7 @@ "array-filter": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" } } }, @@ -39879,8 +49228,7 @@ "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" }, "showdown": { "version": "1.9.1", @@ -40175,7 +49523,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.1.0.tgz", "integrity": "sha512-2i5Tc0BYAqppM7jVzmNrI+aEUntPolIq4fDgji6WuNNn1D/qYdn2KwoLhZdzQkE04lu9L5tUoeJsjuJAvd+lFg==", - "dev": true, "requires": { "bplist-creator": "0.0.8", "bplist-parser": "0.2.0", @@ -40244,8 +49591,7 @@ "slide": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" }, "smart-buffer": { "version": "4.0.2", @@ -40474,7 +49820,6 @@ "version": "0.5.16", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -40483,8 +49828,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -40529,7 +49873,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -40538,14 +49881,12 @@ "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true + "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -40554,8 +49895,7 @@ "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true + "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==" }, "specificity": { "version": "0.4.1", @@ -40598,7 +49938,6 @@ "version": "1.14.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -40635,7 +49974,6 @@ "version": "0.1.8", "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.8.tgz", "integrity": "sha512-ig5rHJSdJrAsVqdb3oAI/8C6aQ7dEwJXoy/TIEIOTzdJHssmn12o6RsFoeQSLHoKjq0lX+kqhmnLDpyQTuWiJA==", - "dev": true, "requires": { "type-fest": "^0.7.1" }, @@ -40643,8 +49981,7 @@ "type-fest": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==" } } }, @@ -40676,8 +50013,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" }, "stdout-stream": { "version": "1.4.1", @@ -40691,8 +50027,7 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "store2": { "version": "2.10.0", @@ -40713,8 +50048,7 @@ "stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", - "dev": true + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" }, "stream-each": { "version": "1.2.2", @@ -40761,7 +50095,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", - "dev": true, "requires": { "astral-regex": "^1.0.0", "strip-ansi": "^5.2.0" @@ -40770,14 +50103,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -40794,7 +50125,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -41574,7 +50904,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -41607,8 +50936,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" }, "strong-log-transformer": { "version": "2.1.0", @@ -42178,8 +51506,7 @@ "sudo-prompt": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/sudo-prompt/-/sudo-prompt-9.1.1.tgz", - "integrity": "sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA==", - "dev": true + "integrity": "sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA==" }, "sugarss": { "version": "2.0.0", @@ -42202,7 +51529,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.0.0.tgz", "integrity": "sha512-bFhn0MQ8qefLyJ3K7PpHiPUTuTVPWw6RXfaMeV6xgJLXtBbszyboz1bvGTVv4R0YpQm2DqlXXn0fFHhxUHVE5w==", - "dev": true, "requires": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" @@ -42211,14 +51537,12 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -42432,8 +51756,7 @@ "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" }, "symbol.prototype.description": { "version": "1.0.2", @@ -42708,7 +52031,6 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", - "dev": true, "requires": { "os-tmpdir": "^1.0.0", "rimraf": "~2.2.6" @@ -42717,8 +52039,7 @@ "rimraf": { "version": "2.2.8", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" } } }, @@ -42775,7 +52096,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.0.0.tgz", "integrity": "sha512-rdBAY35jUvVapqCuhehjenLbYY73cVgRQ6podD6u9EDBomBBHjCOtmq2InPgPpTysOIOsQ5PdBzwSC/sKjv6ew==", - "dev": true, "requires": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" @@ -42785,7 +52105,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.2.1.tgz", "integrity": "sha512-Cg3ymMAdN10wOk/VYfLV7KCQyv7EDirJ64500sU7n9UlmioEtDuU5Gd+hj73hXSU/ex7tHJSssmyftDdkMLO8Q==", - "dev": true, "requires": { "type-fest": "^0.5.2" } @@ -42793,8 +52112,7 @@ "type-fest": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz", - "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==", - "dev": true + "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==" } } }, @@ -43157,8 +52475,7 @@ "throat": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", - "dev": true + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" }, "throttle-debounce": { "version": "2.1.0", @@ -43169,14 +52486,12 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, "requires": { "readable-stream": "^2.1.5", "xtend": "~4.0.1" @@ -43185,8 +52500,7 @@ "time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" }, "timers-browserify": { "version": "2.0.11", @@ -43237,7 +52551,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -43325,11 +52638,15 @@ "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo=", "dev": true }, + "toolkit.ts": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/toolkit.ts/-/toolkit.ts-0.0.2.tgz", + "integrity": "sha512-yJJTVbCwiD6AfFgReewJCGJuODmyZUeL1sDjnxp33t0UBxnezgQrLbz/F9++RC28CTlk5u5pVji4TbeondYEkw==" + }, "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==", - "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -43338,8 +52655,7 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" } } }, @@ -43347,7 +52663,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -43456,7 +52771,6 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -43470,14 +52784,12 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, "optional": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -43485,8 +52797,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-fest": { "version": "0.3.1", @@ -43529,8 +52840,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -43561,7 +52871,6 @@ "version": "3.3.9", "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, "requires": { "commander": "~2.13.0", "source-map": "~0.6.1" @@ -43570,14 +52879,12 @@ "commander": { "version": "2.13.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" } } }, @@ -43624,8 +52931,7 @@ "ultron": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" }, "umask": { "version": "1.1.0", @@ -43680,14 +52986,12 @@ "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", - "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", - "dev": true + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==" }, "unicode-match-property-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", - "dev": true, "requires": { "unicode-canonical-property-names-ecmascript": "^1.0.4", "unicode-property-aliases-ecmascript": "^1.0.4" @@ -43696,14 +53000,12 @@ "unicode-match-property-value-ecmascript": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", - "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", - "dev": true + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==" }, "unicode-property-aliases-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz", - "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==", - "dev": true + "integrity": "sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg==" }, "unified": { "version": "7.1.0", @@ -43877,14 +53179,12 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, "unquote": { "version": "1.1.1", @@ -43944,7 +53244,6 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, "requires": { "punycode": "^2.1.0" } @@ -44123,8 +53422,7 @@ "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, "uuid": { "version": "7.0.2", @@ -44169,7 +53467,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -44184,11 +53481,16 @@ "builtins": "^1.0.3" } }, + "vargs": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/vargs/-/vargs-0.1.0.tgz", + "integrity": "sha1-a2GE2mUgzDIEzhtAfKwm2SYJ6/8=", + "dev": true + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, "vendors": { "version": "1.0.2", @@ -44200,7 +53502,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -44245,8 +53546,7 @@ "vlq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz", - "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==", - "dev": true + "integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==" }, "vm-browserify": { "version": "1.1.2", @@ -44349,7 +53649,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "dev": true, "requires": { "browser-process-hrtime": "^0.1.2" } @@ -44358,7 +53657,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "dev": true, "requires": { "domexception": "^1.0.1", "webidl-conversions": "^4.0.2", @@ -44469,11 +53767,25 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, "requires": { "defaults": "^1.0.3" } }, + "wd": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/wd/-/wd-1.12.1.tgz", + "integrity": "sha512-O99X8OnOgkqfmsPyLIRzG9LmZ+rjmdGFBCyhGpnsSL4MB4xzHoeWmSVcumDiQ5QqPZcwGkszTgeJvjk2VjtiNw==", + "dev": true, + "requires": { + "archiver": "^3.0.0", + "async": "^2.0.0", + "lodash": "^4.0.0", + "mkdirp": "^0.5.1", + "q": "^1.5.1", + "request": "2.88.0", + "vargs": "^0.1.0" + } + }, "web-namespaces": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.3.tgz", @@ -44483,8 +53795,7 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" }, "webpack": { "version": "4.42.0", @@ -45106,7 +54417,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", - "dev": true, "requires": { "iconv-lite": "0.4.19" }, @@ -45114,8 +54424,7 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" } } }, @@ -45127,14 +54436,12 @@ "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" }, "whatwg-url": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -45173,7 +54480,6 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -45341,8 +54647,7 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-farm": { "version": "1.7.0", @@ -45366,7 +54671,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -45375,14 +54679,12 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "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" } @@ -45391,7 +54693,6 @@ "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", @@ -45402,7 +54703,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, "requires": { "ansi-regex": "^2.0.0" } @@ -45515,7 +54815,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.1.0.tgz", "integrity": "sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ==", - "dev": true, "requires": { "simple-plist": "^1.0.0", "uuid": "^3.3.2" @@ -45524,8 +54823,7 @@ "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" } } }, @@ -45538,26 +54836,22 @@ "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" }, "xmlbuilder": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" }, "xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" }, "xmldoc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-1.1.2.tgz", "integrity": "sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ==", - "dev": true, "requires": { "sax": "^1.2.1" } @@ -45565,14 +54859,12 @@ "xmldom": { "version": "0.1.31", "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz", - "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==", - "dev": true + "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==" }, "xpipe": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz", - "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=", - "dev": true + "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=" }, "xregexp": { "version": "4.3.0", @@ -45586,20 +54878,17 @@ "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" }, "yaml": { "version": "1.7.2", @@ -45766,6 +55055,30 @@ "fd-slicer": "~1.0.1" } }, + "zip-stream": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-2.1.3.tgz", + "integrity": "sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q==", + "dev": true, + "requires": { + "archiver-utils": "^2.1.0", + "compress-commons": "^2.1.1", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "zwitch": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.4.tgz", diff --git a/package.json b/package.json index cfc261e50ec04d..6194d76d5fd616 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,9 @@ "@wordpress/plugins": "file:packages/plugins", "@wordpress/primitives": "file:packages/primitives", "@wordpress/priority-queue": "file:packages/priority-queue", + "@wordpress/react-native-aztec": "file:packages/react-native-aztec", + "@wordpress/react-native-bridge": "file:packages/react-native-bridge", + "@wordpress/react-native-editor": "file:packages/react-native-editor", "@wordpress/redux-routine": "file:packages/redux-routine", "@wordpress/rich-text": "file:packages/rich-text", "@wordpress/server-side-render": "file:packages/server-side-render", @@ -126,6 +129,8 @@ "@wordpress/prettier-config": "file:packages/prettier-config", "@wordpress/project-management-automation": "file:packages/project-management-automation", "@wordpress/scripts": "file:packages/scripts", + "appium": "1.17.1", + "babel-jest": "25.3.0", "babel-loader": "8.1.0", "babel-plugin-emotion": "10.0.33", "babel-plugin-inline-json-import": "0.3.2", @@ -143,6 +148,7 @@ "cssnano": "4.1.10", "deep-freeze": "0.0.1", "enzyme": "3.11.0", + "equivalent-key-map": "0.2.2", "eslint-plugin-eslint-comments": "3.1.2", "eslint-plugin-import": "2.20.2", "execa": "4.0.2", @@ -150,6 +156,7 @@ "glob": "7.1.2", "husky": "3.0.5", "inquirer": "7.1.0", + "jest": "25.3.0", "jest-emotion": "10.0.32", "jest-junit": "10.0.0", "jest-serializer-enzyme": "1.0.0", @@ -158,8 +165,9 @@ "lint-staged": "9.2.5", "lodash": "4.17.15", "make-dir": "3.0.0", - "metro-react-native-babel-preset": "0.55.0", - "metro-react-native-babel-transformer": "0.55.0", + "metro": "0.58.0", + "metro-react-native-babel-preset": "0.57.0", + "metro-react-native-babel-transformer": "0.56.0", "mkdirp": "0.5.1", "nock": "12.0.3", "node-sass": "4.13.1", @@ -184,6 +192,7 @@ "stylelint-config-wordpress": "17.0.0", "typescript": "3.8.3", "uuid": "7.0.2", + "wd": "1.12.1", "webpack": "4.42.0", "worker-farm": "1.7.0" }, @@ -199,7 +208,7 @@ "build": "npm run build:packages && wp-scripts build", "changelog": "./bin/plugin/cli.js changelog", "check-engines": "wp-scripts check-engines", - "check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2\" \"wp-scripts check-licenses --dev\"", + "check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2 --ignore=@react-native-community/cli,@react-native-community/cli-platform-ios\" \"wp-scripts check-licenses --dev\"", "precheck-local-changes": "npm run docs:build", "check-local-changes": "( git diff -U0 | xargs -0 node bin/process-git-diff ) || ( echo \"There are local uncommitted changes after one or both of 'npm install' or 'npm run docs:build'!\" && exit 1 );", "predev": "npm run check-engines", @@ -221,6 +230,7 @@ "lint-css:fix": "npm run lint-css -- --fix", "lint:md-js": "wp-scripts lint-md-js", "lint:md-docs": "wp-scripts lint-md-docs", + "native": "npm run --prefix packages/react-native-editor", "pot-to-php": "./bin/pot-to-php.js", "publish:check": "lerna updated", "publish:dev": "npm run clean:package-types && npm run build:packages && lerna publish --dist-tag next", @@ -240,7 +250,7 @@ "test-unit-php": "wp-env run phpunit 'phpunit -c /var/www/html/wp-content/plugins/gutenberg/phpunit.xml.dist --verbose'", "test-unit-php-multisite": "wp-env run phpunit 'WP_MULTISITE=1 phpunit -c /var/www/html/wp-content/plugins/gutenberg/phpunit/multisite.xml --verbose'", "test-unit:native": "cd test/native/ && cross-env NODE_ENV=test jest --config ./jest.config.js", - "test-unit:native:debug": "cd test/native/ && node --inspect-brk ../../node_modules/.bin/jest --runInBand --verbose --config ./jest.config.js", + "test-unit:native:debug": "cd test/native/ && node --inspect ../../node_modules/.bin/jest --runInBand --config ./jest.config.js", "prestorybook:build": "npm run build:packages", "storybook:build": "build-storybook -c ./storybook -o ./playground/dist", "prestorybook:dev": "npm run build:packages", @@ -293,5 +303,8 @@ " `---'" ], "welcome-build-command": "npm run dev" + }, + "resolutions": { + "metro-config": "0.58.0" } } diff --git a/packages/base-styles/_colors.native.scss b/packages/base-styles/_colors.native.scss new file mode 100644 index 00000000000000..f1b08583173ee0 --- /dev/null +++ b/packages/base-styles/_colors.native.scss @@ -0,0 +1,171 @@ +/** @format */ + +// Hugo's new WordPress shades of gray, from http://codepen.io/hugobaeta/pen/grJjVp. +$black: #000; +$dark-gray-900: #191e23; +$dark-gray-800: #23282d; +$dark-gray-700: #32373c; +$dark-gray-600: #40464d; +$dark-gray-500: #555d66; // Use this most of the time for dark items. +$dark-gray-400: #606a73; +$dark-gray-300: #6c7781; // Lightest gray that can be used for AA text contrast. +$dark-gray-200: #7e8993; +$dark-gray-150: #8d96a0; // Lightest gray that can be used for AA non-text contrast. +$dark-gray-100: #8f98a1; +$light-gray-900: #a2aab2; +$light-gray-800: #b5bcc2; +$light-gray-700: #ccd0d4; +$light-gray-600: #d7dade; +$light-gray-500: #e2e4e7; // Good for "grayed" items and borders. +$light-gray-400: #e8eaeb; // Good for "readonly" input fields and special text selection. +$light-gray-300: #edeff0; +$light-gray-200: #f3f4f5; +$light-gray-100: #f8f9f9; +$white: #fff; + +// Dark opacities, for use with light themes. +$dark-opacity-900: rgba(#000510, 0.9); +$dark-opacity-800: rgba(#00000a, 0.85); +$dark-opacity-700: rgba(#06060b, 0.8); +$dark-opacity-600: rgba(#000913, 0.75); +$dark-opacity-500: rgba(#0a1829, 0.7); +$dark-opacity-400: rgba(#0a1829, 0.65); +$dark-opacity-300: rgba(#0e1c2e, 0.62); +$dark-opacity-200: rgba(#162435, 0.55); +$dark-opacity-100: rgba(#223443, 0.5); +$dark-opacity-light-900: rgba(#304455, 0.45); +$dark-opacity-light-800: rgba(#425863, 0.4); +$dark-opacity-light-700: rgba(#667886, 0.35); +$dark-opacity-light-600: rgba(#7b86a2, 0.3); +$dark-opacity-light-500: rgba(#9197a2, 0.25); +$dark-opacity-light-400: rgba(#95959c, 0.2); +$dark-opacity-light-300: rgba(#829493, 0.15); +$dark-opacity-light-200: rgba(#8b8b96, 0.1); +$dark-opacity-light-100: rgba(#747474, 0.05); + +// Light opacities, for use with dark themes. +$light-opacity-900: rgba($white, 1); +$light-opacity-800: rgba($white, 0.9); +$light-opacity-700: rgba($white, 0.85); +$light-opacity-600: rgba($white, 0.8); +$light-opacity-500: rgba($white, 0.75); +$light-opacity-400: rgba($white, 0.7); +$light-opacity-300: rgba($white, 0.65); +$light-opacity-200: rgba($white, 0.6); +$light-opacity-100: rgba($white, 0.55); +$light-opacity-light-900: rgba($white, 0.5); +$light-opacity-light-800: rgba($white, 0.45); +$light-opacity-light-700: rgba($white, 0.4); +$light-opacity-light-600: rgba($white, 0.35); +$light-opacity-light-500: rgba($white, 0.3); +$light-opacity-light-400: rgba($white, 0.25); +$light-opacity-light-300: rgba($white, 0.2); +$light-opacity-light-200: rgba($white, 0.15); +$light-opacity-light-100: rgba($white, 0.1); + +// Additional colors. +// Some are from https://make.wordpress.org/design/handbook/foundations/colors/. +$blue-wordpress-700: #00669b; +$blue-dark-900: #0071a1; + +$blue-medium-900: #006589; +$blue-medium-800: #00739c; +$blue-medium-700: #007fac; +$blue-medium-600: #008dbe; +$blue-medium-500: #00a0d2; +$blue-medium-400: #33b3db; +$blue-medium-300: #66c6e4; +$blue-medium-200: #bfe7f3; +$blue-medium-100: #e5f5fa; +$blue-medium-highlight: #b3e7fe; +$blue-medium-focus: #007cba; + +// Alert colors. +$alert-yellow: #f0b849; +$alert-red: #d94f4f; +$alert-green: #4ab866; + +// Primary Accent (Blues) +$blue-wordpress: #0087be; +$blue-light: #78dcfa; +$blue-medium: #00aadc; +$blue-dark: #005082; +$blue-500: #016087; + +// Grays +$gray: #87a6bc; +$gray-light: lighten($gray, 33%); //#f3f6f8 +$gray-dark: darken($gray, 38%); //#2e4453 +$gray-900: #1a1a1a; + +// $gray-text: ideal for standard, non placeholder text +// $gray-text-min: minimum contrast needed for WCAG 2.0 AA on white background +$gray-text: $gray-dark; +$gray-text-min: darken($gray, 18%); //#537994 + +// Shades of gray +$gray-lighten-10: lighten($gray, 10%); // #a8bece +$gray-lighten-20: lighten($gray, 20%); // #c8d7e1 +$gray-lighten-30: lighten($gray, 30%); // #e9eff3 +$gray-darken-10: darken($gray, 10%); // #668eaa +$gray-darken-20: darken($gray, 20%); // #4f748e +$gray-darken-30: darken($gray, 30%); // #3d596d + +// +// See wordpress.com/design-handbook/colors/ for more info. + +// Secondary Accent (Oranges) +$orange-jazzy: #f0821e; +$orange-fire: #d54e21; + +// Alerts +$alert-yellow: #f0b849; +$alert-red: #d94f4f; +$alert-green: #4ab866; +$alert-purple: #855da6; +$red-40: #e65054; + +// Custom +$toolbar-button: #7b9ab1; +$toolbar-button-disabled: $gray-lighten-30; + +$background-dark-elevated: #2e2e2e; +$background-dark-secondary: #1e2327; + +// Primary tint color (light) +$blue-50: #2271b1; +// Primary tint color (dark) +$blue-30: #5198d9; + +$button-default-bg: #2271b1; +$button-fallback-bg: #595959; + +// color-studio +$gray-0: #f6f7f7; +$gray-5: #dcdcde; +$gray-10: #c3c4c7; +$gray-20: #a7aaad; +$gray-30: #8e9196; +$gray-40: #787c82; +$gray-50: #646970; +$gray-60: #50575e; +$gray-70: #3c434a; +$gray-90: #1d2327; +$gray-95: #1d2327; +$gray-100: #101517; + +// neutral (light) - black is a base color in light mode +$light-primary: #000d; //rgba(0, 0, 0, 0.87); +$light-secondary: #0009; //rgba(0, 0, 0, 0.6); +$light-tertiary: #0000006d; //rgba(0, 0, 0, 0.43); +$light-quaternary: #0000003f; //rgba(0, 0, 0, 0.25); +$light-dim: #0000001e; //rgba(0, 0, 0, 0.12); +$light-ultra-dim: #0000000a; //rgba(0, 0, 0, 0.04); + +// neutral (dark) - white is a base color in dark mode +$dark-primary: #fffd; //rgba(255, 255, 255, 0.87); +$dark-secondary: #fff9; //rgba(255, 255, 255, 0.6); +$dark-tertiary: #ffffff6d; //rgba(255, 255, 255, 0.43); +$dark-quaternary: #ffffff3f; //rgba(255, 255, 255, 0.25); +$dark-dim: #ffffff26; //rgba(255, 255, 255, 0.15); +$dark-ultra-dim: #ffffff14; //rgba(255, 255, 255, 0.08); diff --git a/packages/block-editor/src/components/media-edit/index.native.js b/packages/block-editor/src/components/media-edit/index.native.js index ac7bf08e9da82a..91aee58f988bf0 100644 --- a/packages/block-editor/src/components/media-edit/index.native.js +++ b/packages/block-editor/src/components/media-edit/index.native.js @@ -2,10 +2,6 @@ * External dependencies */ import React from 'react'; -import { - requestMediaEditor, - mediaSources, -} from 'react-native-gutenberg-bridge'; /** * WordPress dependencies @@ -13,6 +9,10 @@ import { import { __ } from '@wordpress/i18n'; import { Picker } from '@wordpress/components'; import { update, brush } from '@wordpress/icons'; +import { + requestMediaEditor, + mediaSources, +} from '@wordpress/react-native-bridge'; export const MEDIA_TYPE_IMAGE = 'image'; diff --git a/packages/block-editor/src/components/media-upload-progress/index.native.js b/packages/block-editor/src/components/media-upload-progress/index.native.js index a417ad107339e7..7f2f7d380ad32d 100644 --- a/packages/block-editor/src/components/media-upload-progress/index.native.js +++ b/packages/block-editor/src/components/media-upload-progress/index.native.js @@ -3,13 +3,13 @@ */ import React from 'react'; import { View } from 'react-native'; -import { subscribeMediaUpload } from 'react-native-gutenberg-bridge'; /** * WordPress dependencies */ import { Spinner } from '@wordpress/components'; import { __ } from '@wordpress/i18n'; +import { subscribeMediaUpload } from '@wordpress/react-native-bridge'; /** * Internal dependencies diff --git a/packages/block-editor/src/components/media-upload-progress/test/index.native.js b/packages/block-editor/src/components/media-upload-progress/test/index.native.js index 41a542b3703caa..030fba6b37a20f 100644 --- a/packages/block-editor/src/components/media-upload-progress/test/index.native.js +++ b/packages/block-editor/src/components/media-upload-progress/test/index.native.js @@ -2,7 +2,11 @@ * External dependencies */ import { shallow } from 'enzyme'; -import { sendMediaUpload } from 'react-native-gutenberg-bridge'; + +/** + * WordPress dependencies + */ +import { sendMediaUpload } from '@wordpress/react-native-bridge'; /** * Internal dependencies @@ -15,7 +19,7 @@ import { MEDIA_UPLOAD_STATE_RESET, } from '../'; -jest.mock( 'react-native-gutenberg-bridge', () => { +jest.mock( '@wordpress/react-native-bridge', () => { const callUploadCallback = ( payload ) => { this.uploadCallBack( payload ); }; diff --git a/packages/block-editor/src/components/media-upload/index.native.js b/packages/block-editor/src/components/media-upload/index.native.js index a2cc12e6028f7b..655dbdcfaa35e1 100644 --- a/packages/block-editor/src/components/media-upload/index.native.js +++ b/packages/block-editor/src/components/media-upload/index.native.js @@ -2,17 +2,17 @@ * External dependencies */ import React from 'react'; -import { - getOtherMediaOptions, - requestMediaPicker, - mediaSources, -} from 'react-native-gutenberg-bridge'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { Picker } from '@wordpress/components'; +import { + getOtherMediaOptions, + requestMediaPicker, + mediaSources, +} from '@wordpress/react-native-bridge'; import { capturePhoto, captureVideo, image, wordpress } from '@wordpress/icons'; export const MEDIA_TYPE_IMAGE = 'image'; diff --git a/packages/block-editor/src/components/media-upload/test/index.native.js b/packages/block-editor/src/components/media-upload/test/index.native.js index 539f9f4361c5d9..222e8e1b78f4bc 100644 --- a/packages/block-editor/src/components/media-upload/test/index.native.js +++ b/packages/block-editor/src/components/media-upload/test/index.native.js @@ -3,10 +3,14 @@ */ import { shallow } from 'enzyme'; import { TouchableWithoutFeedback } from 'react-native'; + +/** + * WordPress dependencies + */ import { requestMediaPicker, mediaSources, -} from 'react-native-gutenberg-bridge'; +} from '@wordpress/react-native-bridge'; /** * Internal dependencies diff --git a/packages/block-editor/src/components/page-template-picker/picker.native.js b/packages/block-editor/src/components/page-template-picker/picker.native.js index b6193b4bc14715..368ddde67f683e 100644 --- a/packages/block-editor/src/components/page-template-picker/picker.native.js +++ b/packages/block-editor/src/components/page-template-picker/picker.native.js @@ -17,7 +17,7 @@ import { userEvents, requestStarterPageTemplatesTooltipShown, setStarterPageTemplatesTooltipShown, -} from 'react-native-gutenberg-bridge'; +} from '@wordpress/react-native-bridge'; import { Animated, Dimensions, Keyboard } from 'react-native'; /** diff --git a/packages/block-editor/src/components/page-template-picker/preview.native.js b/packages/block-editor/src/components/page-template-picker/preview.native.js index 68a6fe983f5beb..cd0d4e85d73f69 100644 --- a/packages/block-editor/src/components/page-template-picker/preview.native.js +++ b/packages/block-editor/src/components/page-template-picker/preview.native.js @@ -7,12 +7,12 @@ import { usePreferredColorSchemeStyle } from '@wordpress/compose'; import { useSelect } from '@wordpress/data'; import { useEffect, useRef } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; +import { subscribeAndroidModalClosed } from '@wordpress/react-native-bridge'; /** * External dependencies */ import { Modal, Platform, View, SafeAreaView } from 'react-native'; -import { subscribeAndroidModalClosed } from 'react-native-gutenberg-bridge'; /** * Internal dependencies diff --git a/packages/block-library/src/cover/edit.native.js b/packages/block-library/src/cover/edit.native.js index 8c00981f2c9bee..df81a2f9b1d1ee 100644 --- a/packages/block-library/src/cover/edit.native.js +++ b/packages/block-library/src/cover/edit.native.js @@ -2,16 +2,16 @@ * External dependencies */ import { View, TouchableWithoutFeedback } from 'react-native'; -import { - requestImageFailedRetryDialog, - requestImageUploadCancelDialog, - mediaUploadSync, -} from 'react-native-gutenberg-bridge'; import Video from 'react-native-video'; /** * WordPress dependencies */ +import { + requestImageFailedRetryDialog, + requestImageUploadCancelDialog, + mediaUploadSync, +} from '@wordpress/react-native-bridge'; import { __ } from '@wordpress/i18n'; import { Icon, diff --git a/packages/block-library/src/gallery/gallery-image.native.js b/packages/block-library/src/gallery/gallery-image.native.js index 4a4b23ee4e1199..d34362efd5e68e 100644 --- a/packages/block-library/src/gallery/gallery-image.native.js +++ b/packages/block-library/src/gallery/gallery-image.native.js @@ -9,15 +9,15 @@ import { Text, TouchableWithoutFeedback, } from 'react-native'; -import { - requestImageFailedRetryDialog, - requestImageUploadCancelDialog, -} from 'react-native-gutenberg-bridge'; import { isEmpty } from 'lodash'; /** * WordPress dependencies */ +import { + requestImageFailedRetryDialog, + requestImageUploadCancelDialog, +} from '@wordpress/react-native-bridge'; import { Component } from '@wordpress/element'; import { Icon } from '@wordpress/components'; import { __, sprintf } from '@wordpress/i18n'; diff --git a/packages/block-library/src/gallery/gallery.native.js b/packages/block-library/src/gallery/gallery.native.js index 910e1ed0ccb43d..d5e590711dff07 100644 --- a/packages/block-library/src/gallery/gallery.native.js +++ b/packages/block-library/src/gallery/gallery.native.js @@ -7,7 +7,6 @@ import { isEmpty } from 'lodash'; /** * Internal dependencies */ -import { mediaUploadSync } from 'react-native-gutenberg-bridge'; import GalleryImage from './gallery-image'; import { defaultColumnsNumber } from './shared'; import styles from './gallery-styles.scss'; @@ -19,6 +18,7 @@ import Tiles from './tiles'; import { __, sprintf } from '@wordpress/i18n'; import { BlockCaption } from '@wordpress/block-editor'; import { useState, useEffect } from '@wordpress/element'; +import { mediaUploadSync } from '@wordpress/react-native-bridge'; import { useSelect } from '@wordpress/data'; const TILE_SPACING = 15; diff --git a/packages/block-library/src/image/edit.native.js b/packages/block-library/src/image/edit.native.js index a949906d8f6f45..e0ecc3ed7cb073 100644 --- a/packages/block-library/src/image/edit.native.js +++ b/packages/block-library/src/image/edit.native.js @@ -9,13 +9,16 @@ import { TouchableWithoutFeedback, Dimensions, } from 'react-native'; +/** + * WordPress dependencies + */ import { requestMediaImport, mediaUploadSync, requestImageFailedRetryDialog, requestImageUploadCancelDialog, requestImageFullscreenPreview, -} from 'react-native-gutenberg-bridge'; +} from '@wordpress/react-native-bridge'; import { isEmpty, get, find, map } from 'lodash'; /** diff --git a/packages/block-library/src/media-text/media-container.native.js b/packages/block-library/src/media-text/media-container.native.js index cac4d5615a7265..52d8e72f82a899 100644 --- a/packages/block-library/src/media-text/media-container.native.js +++ b/packages/block-library/src/media-text/media-container.native.js @@ -7,15 +7,15 @@ import { Text, TouchableWithoutFeedback, } from 'react-native'; -import { - mediaUploadSync, - requestImageFailedRetryDialog, - requestImageUploadCancelDialog, -} from 'react-native-gutenberg-bridge'; /** * WordPress dependencies */ +import { + mediaUploadSync, + requestImageFailedRetryDialog, + requestImageUploadCancelDialog, +} from '@wordpress/react-native-bridge'; import { Icon, Button, ToolbarGroup, withNotices } from '@wordpress/components'; import { BlockControls, diff --git a/packages/block-library/src/missing/edit.native.js b/packages/block-library/src/missing/edit.native.js index 1d87e5c729804c..7be098661cd482 100644 --- a/packages/block-library/src/missing/edit.native.js +++ b/packages/block-library/src/missing/edit.native.js @@ -2,11 +2,11 @@ * External dependencies */ import { Platform, View, Text, TouchableWithoutFeedback } from 'react-native'; -import { requestUnsupportedBlockFallback } from 'react-native-gutenberg-bridge'; /** * WordPress dependencies */ +import { requestUnsupportedBlockFallback } from '@wordpress/react-native-bridge'; import { BottomSheet, Icon } from '@wordpress/components'; import { withPreferredColorScheme } from '@wordpress/compose'; import { coreBlocks } from '@wordpress/block-library'; diff --git a/packages/block-library/src/video/edit.native.js b/packages/block-library/src/video/edit.native.js index 42d7d6df448a5e..5a7a177a06eabd 100644 --- a/packages/block-library/src/video/edit.native.js +++ b/packages/block-library/src/video/edit.native.js @@ -6,17 +6,13 @@ import { View, TouchableWithoutFeedback, Text } from 'react-native'; import { isEmpty } from 'lodash'; /** - * Internal dependencies + * WordPress dependencies */ import { mediaUploadSync, requestImageFailedRetryDialog, requestImageUploadCancelDialog, -} from 'react-native-gutenberg-bridge'; - -/** - * WordPress dependencies - */ +} from '@wordpress/react-native-bridge'; import { Icon, ToolbarButton, diff --git a/packages/components/src/mobile/bottom-sheet/index.native.js b/packages/components/src/mobile/bottom-sheet/index.native.js index 9544d7f33eaf50..655e2d414dad63 100644 --- a/packages/components/src/mobile/bottom-sheet/index.native.js +++ b/packages/components/src/mobile/bottom-sheet/index.native.js @@ -14,11 +14,11 @@ import { } from 'react-native'; import Modal from 'react-native-modal'; import SafeArea from 'react-native-safe-area'; -import { subscribeAndroidModalClosed } from 'react-native-gutenberg-bridge'; /** * WordPress dependencies */ +import { subscribeAndroidModalClosed } from '@wordpress/react-native-bridge'; import { Component } from '@wordpress/element'; import { withPreferredColorScheme } from '@wordpress/compose'; diff --git a/packages/compose/src/hooks/use-preferred-color-scheme/index.android.js b/packages/compose/src/hooks/use-preferred-color-scheme/index.android.js index 074f19b280a47a..388eda02664a08 100644 --- a/packages/compose/src/hooks/use-preferred-color-scheme/index.android.js +++ b/packages/compose/src/hooks/use-preferred-color-scheme/index.android.js @@ -1,14 +1,11 @@ /** - * External dependencies + * WordPress dependencies */ +import { useState, useEffect } from '@wordpress/element'; import { subscribePreferredColorScheme, isInitialColorSchemeDark, -} from 'react-native-gutenberg-bridge'; -/** - * WordPress dependencies - */ -import { useState, useEffect } from '@wordpress/element'; +} from '@wordpress/react-native-bridge'; /** * Returns the color scheme value when it changes. Possible values: [ 'light', 'dark' ] diff --git a/packages/edit-post/src/components/layout/index.native.js b/packages/edit-post/src/components/layout/index.native.js index 94291b0db06e35..eb989d7d4f32bd 100644 --- a/packages/edit-post/src/components/layout/index.native.js +++ b/packages/edit-post/src/components/layout/index.native.js @@ -3,7 +3,6 @@ */ import { Platform, SafeAreaView, View } from 'react-native'; import SafeArea from 'react-native-safe-area'; -import { sendNativeEditorDidLayout } from 'react-native-gutenberg-bridge'; /** * WordPress dependencies @@ -19,6 +18,7 @@ import { import { compose, withPreferredColorScheme } from '@wordpress/compose'; import { HTMLTextInput, KeyboardAvoidingView } from '@wordpress/components'; import { AutosaveMonitor } from '@wordpress/editor'; +import { sendNativeEditorDidLayout } from '@wordpress/react-native-bridge'; /** * Internal dependencies diff --git a/packages/edit-post/src/editor.native.js b/packages/edit-post/src/editor.native.js index 2d50cf76b90867..93b00ac529944b 100644 --- a/packages/edit-post/src/editor.native.js +++ b/packages/edit-post/src/editor.native.js @@ -3,7 +3,6 @@ */ import memize from 'memize'; import { size, map, without } from 'lodash'; -import { subscribeSetFocusOnTitle } from 'react-native-gutenberg-bridge'; import { I18nManager } from 'react-native'; /** @@ -14,6 +13,7 @@ import { EditorProvider } from '@wordpress/editor'; import { parse, serialize } from '@wordpress/blocks'; import { withDispatch, withSelect } from '@wordpress/data'; import { compose } from '@wordpress/compose'; +import { subscribeSetFocusOnTitle } from '@wordpress/react-native-bridge'; import { SlotFillProvider, SiteCapabilitiesContext, @@ -112,6 +112,7 @@ class Editor extends Component { hiddenBlockTypes, blockTypes, post, + postId, postType, colors, gradients, @@ -129,9 +130,9 @@ class Editor extends Component { ); const normalizedPost = post || { - id: 1, + id: postId, title: { - raw: props.initialTitle, + raw: props.initialTitle || '', }, content: { // make sure the post content is in sync with gutenberg store diff --git a/packages/edit-post/src/index.native.js b/packages/edit-post/src/index.native.js index 13cf9ce44efe3c..8ce74146376297 100644 --- a/packages/edit-post/src/index.native.js +++ b/packages/edit-post/src/index.native.js @@ -3,23 +3,29 @@ */ import '@wordpress/core-data'; import '@wordpress/block-editor'; -import '@wordpress/editor'; import '@wordpress/viewport'; import '@wordpress/notices'; import { registerCoreBlocks } from '@wordpress/block-library'; import '@wordpress/format-library'; +import { render } from '@wordpress/element'; /** * Internal dependencies */ import './store'; +import Editor from './editor'; let blocksRegistered = false; /** - * Initializes the Editor. + * Initializes the Editor and returns a componentProvider + * that can be registered with `AppRegistry.registerComponent` + * + * @param {string} id Unique identifier for editor instance. + * @param {Object} postType Post type of the post to edit. + * @param {Object} postId ID of the post to edit (unused right now) */ -export function initializeEditor() { +export function initializeEditor( id, postType, postId ) { if ( blocksRegistered ) { return; } @@ -27,6 +33,6 @@ export function initializeEditor() { // register and setup blocks registerCoreBlocks(); blocksRegistered = true; -} -export { default as Editor } from './editor'; + render( , id ); +} diff --git a/packages/edit-post/src/test/editor.native.js b/packages/edit-post/src/test/editor.native.js index 08866099cb3d5a..e153cee4b6a4fe 100644 --- a/packages/edit-post/src/test/editor.native.js +++ b/packages/edit-post/src/test/editor.native.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import RNReactNativeGutenbergBridge from 'react-native-gutenberg-bridge'; import { mount } from 'enzyme'; import { act } from 'react-dom/test-utils'; @@ -9,6 +8,7 @@ import { act } from 'react-dom/test-utils'; * WordPress dependencies */ import { registerCoreBlocks } from '@wordpress/block-library'; +import RNReactNativeGutenbergBridge from '@wordpress/react-native-bridge'; // Force register 'core/editor' store. import { store } from '@wordpress/editor'; // eslint-disable-line no-unused-vars @@ -57,6 +57,7 @@ const renderEditorWith = ( content ) => { initialHtmlModeEnabled={ false } initialTitle={ '' } postType="post" + postId="1" /> ); }; diff --git a/packages/editor/src/components/provider/index.native.js b/packages/editor/src/components/provider/index.native.js index b45aedd1532c1c..9cd660a1d59ebc 100644 --- a/packages/editor/src/components/provider/index.native.js +++ b/packages/editor/src/components/provider/index.native.js @@ -1,6 +1,9 @@ /** * External dependencies */ +/** + * WordPress dependencies + */ import RNReactNativeGutenbergBridge, { subscribeParentGetHtml, subscribeParentToggleHTMLMode, @@ -9,7 +12,7 @@ import RNReactNativeGutenbergBridge, { subscribeMediaAppend, subscribeReplaceBlock, subscribeUpdateTheme, -} from 'react-native-gutenberg-bridge'; +} from '@wordpress/react-native-bridge'; /** * WordPress dependencies diff --git a/packages/editor/src/store/actions.native.js b/packages/editor/src/store/actions.native.js index 0154c92324640e..49d40749cb1c7a 100644 --- a/packages/editor/src/store/actions.native.js +++ b/packages/editor/src/store/actions.native.js @@ -1,7 +1,7 @@ /** - * External dependencies + * WordPress dependencies */ -import RNReactNativeGutenbergBridge from 'react-native-gutenberg-bridge'; +import RNReactNativeGutenbergBridge from '@wordpress/react-native-bridge'; export * from './actions.js'; diff --git a/packages/element/src/react-platform.native.js b/packages/element/src/react-platform.native.js index e69de29bb2d1d6..fd4db1139156f4 100644 --- a/packages/element/src/react-platform.native.js +++ b/packages/element/src/react-platform.native.js @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import { AppRegistry } from 'react-native'; +import { omit } from 'lodash'; + +/** + * WordPress dependencies + */ +import { applyFilters, doAction } from '@wordpress/hooks'; + +/** + * Internal dependencies + */ +import { cloneElement } from './react'; + +const render = ( element, id ) => + AppRegistry.registerComponent( id, () => ( propsFromParent ) => { + const parentProps = omit( propsFromParent || {}, [ 'rootTag' ] ); + + doAction( 'native.pre-render', parentProps ); + + const filteredProps = applyFilters( + 'native.block_editor_props', + parentProps + ); + + doAction( 'native.render', filteredProps ); + + return cloneElement( element, filteredProps ); + } ); + +/** + * Render a given element on Native. + * This actually returns a componentProvider that can be registered with `AppRegistry.registerComponent` + * + * @param {WPElement} element Element to render. + */ +export { render }; diff --git a/packages/primitives/src/block-quotation/index.native.js b/packages/primitives/src/block-quotation/index.native.js index d38673b89c5019..6d34fdc0b5aee2 100644 --- a/packages/primitives/src/block-quotation/index.native.js +++ b/packages/primitives/src/block-quotation/index.native.js @@ -6,20 +6,12 @@ import { View } from 'react-native'; * WordPress dependencies */ import { Children, cloneElement } from '@wordpress/element'; -import { withPreferredColorScheme } from '@wordpress/compose'; /** * Internal dependencies */ import styles from './style.scss'; -export const BlockQuotation = withPreferredColorScheme( ( props ) => { - const { getStylesFromColorScheme } = props; - - const blockQuoteStyle = getStylesFromColorScheme( - styles.wpBlockQuoteLight, - styles.wpBlockQuoteDark - ); - +export const BlockQuotation = ( props ) => { const newChildren = Children.map( props.children, ( child ) => { if ( child && child.props.identifier === 'citation' ) { return cloneElement( child, { @@ -27,12 +19,9 @@ export const BlockQuotation = withPreferredColorScheme( ( props ) => { } ); } if ( child && child.props.identifier === 'value' ) { - return cloneElement( child, { - tagsToEliminate: [ 'div' ], - style: styles.wpBlockQuoteValue, - } ); + return cloneElement( child, { tagsToEliminate: [ 'div' ] } ); } return child; } ); - return { newChildren }; -} ); + return { newChildren }; +}; diff --git a/packages/primitives/src/block-quotation/style.native.scss b/packages/primitives/src/block-quotation/style.native.scss index b143a3cf499101..2e88c68cf26fa9 100644 --- a/packages/primitives/src/block-quotation/style.native.scss +++ b/packages/primitives/src/block-quotation/style.native.scss @@ -1,26 +1,12 @@ -%wpBlockQuote-shared { - border-left-width: 3px; +.wpBlockQuote { + border-left-width: 4px; + border-left-color: $black; border-left-style: solid; - padding-left: 13px; + padding-left: 8px; margin-left: 0; } -.wpBlockQuoteLight { - @extend %wpBlockQuote-shared; - border-left-color: $black; -} - -.wpBlockQuoteDark { - @extend %wpBlockQuote-shared; - border-left-color: $white; -} - .wpBlockQuoteCitation { - margin-top: 12px; + margin-top: 16px; font-size: 14px; } - -.wpBlockQuoteValue { - margin-top: 0; // FIXME: On iOS without margin-top (or any other additional style) the font-size is not applied - font-size: 18px; -} diff --git a/packages/react-native-aztec/.gitignore b/packages/react-native-aztec/.gitignore new file mode 100644 index 00000000000000..80b371f149ae9f --- /dev/null +++ b/packages/react-native-aztec/.gitignore @@ -0,0 +1,118 @@ +# OS X generated file +.DS_Store + +# built application files +*.apk +*.ap_ + +# files for the dex VM +*.dex + +# Java class files +*.class + +# generated files +bin/ +gen/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Eclipse project files +.settings/ +.classpath +.project + +# Intellij project files +*.iml +*.ipr +*.iws +.idea/ + +# Gradle +.gradle/ + +# Generated by gradle +crashlytics.properties + +# npm +node_modules/ + +# yarn +yarn-error.log + +### +### Starting at this point, the Swift .gitignore rules from https://github.com/github/gitignore/blob/master/Swift.gitignore +### + +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. + +ios/Carthage +Carthage/Checkouts +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output + diff --git a/packages/react-native-aztec/.npmrc b/packages/react-native-aztec/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/react-native-aztec/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/react-native-aztec/README.md b/packages/react-native-aztec/README.md new file mode 100644 index 00000000000000..7233c1e2fdbe3b --- /dev/null +++ b/packages/react-native-aztec/README.md @@ -0,0 +1,7 @@ +# react-native-aztec + +Wrapping Aztec Android and Aztec iOS in a React Native component + +# License + +GPL v2 diff --git a/packages/react-native-aztec/RNTAztecView.podspec b/packages/react-native-aztec/RNTAztecView.podspec new file mode 100644 index 00000000000000..6063828cdf28ff --- /dev/null +++ b/packages/react-native-aztec/RNTAztecView.podspec @@ -0,0 +1,23 @@ +require 'json' + +package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) + +Pod::Spec.new do |s| + s.name = 'RNTAztecView' + s.version = package['version'] + s.summary = 'Aztec editor for React Native' + s.license = package['license'] + s.homepage = package['homepage'] + s.authors = 'Automattic' + s.source = { :git => 'https://github.com/WordPress/gutenberg.git' } + s.source_files = 'ios/RNTAztecView/*.{h,m,swift}' + s.public_header_files = 'ios/RNTAztecView/*.h' + s.requires_arc = true + s.platforms = { :ios => "11.0" } + s.swift_version = '5.0' + s.xcconfig = {'OTHER_LDFLAGS' => '-lxml2', + 'HEADER_SEARCH_PATHS' => '/usr/include/libxml2'} + s.dependency 'React-Core' + s.dependency 'WordPress-Aztec-iOS', '~> 1.19.2' + +end diff --git a/packages/react-native-aztec/android/build.gradle b/packages/react-native-aztec/android/build.gradle new file mode 100644 index 00000000000000..a6bd6cf63d50f6 --- /dev/null +++ b/packages/react-native-aztec/android/build.gradle @@ -0,0 +1,124 @@ +buildscript { + ext { + gradlePluginVersion = '3.4.2' + kotlinVersion = '1.3.61' + supportLibVersion = '28.0.0' + tagSoupVersion = '1.2.1' + glideVersion = '3.7.0' + picassoVersion = '2.5.2' + robolectricVersion = '3.5.1' + jUnitVersion = '4.12' + jSoupVersion = '1.10.3' + wordpressUtilsVersion = '1.22' + espressoVersion = '3.0.1' + aztecVersion = 'v1.3.42' + } + + repositories { + jcenter() + google() + } + + dependencies { + classpath "com.android.tools.build:gradle:$gradlePluginVersion" + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'com.github.dcendents.android-maven' + +group = 'com.github.wordpress-mobile.gutenberg-mobile' + +// fallback flag value for when lib is compiled individually (e.g. via jitpack) +project.ext.buildGutenbergFromSource = false + +// The sample build uses multiple directories to +// keep boilerplate and common code separate from +// the main sample code. +List dirs = [ + 'main', // main sample code; look here for the interesting stuff. + 'common', // components that are reused by multiple samples + 'template'] // boilerplate code that is generated by the sample template process + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 28 + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + sourceSets { + main { + dirs.each { dir -> + java.srcDirs "src/${dir}/java" + java.srcDirs += "src/${dir}/kotlin" + res.srcDirs "src/${dir}/res" + } + } + + androidTest.setRoot('tests') + androidTest.java.srcDirs = ['tests/src'] + } + + lintOptions { + disable 'GradleCompatible' + abortOnError false + } +} + +repositories { + jcenter() + google() + + maven { url "https://jitpack.io" } + + if (!rootProject.ext.buildGutenbergFromSource) { + // if not building from source (where the node_modules dir is used), use a remote RN maven repo + def reactNativeRepo = 'https://dl.bintray.com/wordpress-mobile/react-native-mirror/' + println "Will use the RN maven repo at ${reactNativeRepo}" + maven { url reactNativeRepo } + } +} + +dependencies { + api "com.github.wordpress-mobile.WordPress-Aztec-Android:aztec:$aztecVersion" + api "com.github.wordpress-mobile.WordPress-Aztec-Android:wordpress-shortcodes:$aztecVersion" + api "com.github.wordpress-mobile.WordPress-Aztec-Android:wordpress-comments:$aztecVersion" + api "com.github.wordpress-mobile.WordPress-Aztec-Android:glide-loader:$aztecVersion" + api "org.wordpress:utils:$wordpressUtilsVersion" + + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" + + implementation 'androidx.appcompat:appcompat:1.0.0' + + implementation 'androidx.legacy:legacy-support-v4:1.0.0' + implementation 'androidx.gridlayout:gridlayout:1.0.0' + implementation 'androidx.cardview:cardview:1.0.0' + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation 'androidx.recyclerview:recyclerview:1.0.0' + testImplementation 'junit:junit:4.12' + + def reactNativeVersion = reactNativeVersion() + logger.quiet("Using react-native version: $reactNativeVersion") + implementation "com.facebook.react:react-native:$reactNativeVersion" +} + +// Returns react-native version based on environment +def reactNativeVersion() { + if (rootProject.ext.buildGutenbergFromSource) { + return '+' + } + + def packageFile = new File("$projectDir/../../../package.json") + def packageContent = new groovy.json.JsonSlurper().parseText(packageFile.text) + return packageContent['devDependencies']['react-native'] +} diff --git a/packages/react-native-aztec/android/gradle.properties b/packages/react-native-aztec/android/gradle.properties new file mode 100644 index 00000000000000..938b16188c39d1 --- /dev/null +++ b/packages/react-native-aztec/android/gradle.properties @@ -0,0 +1,3 @@ +android.useAndroidX=true +android.enableJetifier=true + diff --git a/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.jar b/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000000..29953ea141f55e Binary files /dev/null and b/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.properties b/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000000..e0c4de36dddba5 --- /dev/null +++ b/packages/react-native-aztec/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/packages/react-native-aztec/android/gradlew b/packages/react-native-aztec/android/gradlew new file mode 100755 index 00000000000000..cccdd3d517fc52 --- /dev/null +++ b/packages/react-native-aztec/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/packages/react-native-aztec/android/gradlew.bat b/packages/react-native-aztec/android/gradlew.bat new file mode 100644 index 00000000000000..e95643d6a2ca62 --- /dev/null +++ b/packages/react-native-aztec/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/react-native-aztec/android/settings.gradle b/packages/react-native-aztec/android/settings.gradle new file mode 100644 index 00000000000000..d47ff8a71063a0 --- /dev/null +++ b/packages/react-native-aztec/android/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = '@wordpress/react-native-aztec' + diff --git a/packages/react-native-aztec/android/src/main/AndroidManifest.xml b/packages/react-native-aztec/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000000000..d937b1806d40fe --- /dev/null +++ b/packages/react-native-aztec/android/src/main/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/IllegalSelectionIndexException.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/IllegalSelectionIndexException.java new file mode 100644 index 00000000000000..454d9fb993b3da --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/IllegalSelectionIndexException.java @@ -0,0 +1,49 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; + +import org.jetbrains.annotations.NotNull; +import org.wordpress.aztec.spans.UnknownHtmlSpan; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +class IllegalSelectionIndexException extends Exception { + IllegalSelectionIndexException(int selectionStart, int selectionEnd, int textLength, ReactAztecText view) { + super(createMessage(selectionStart, selectionEnd, textLength, getUnknownHtmlTags(view, textLength))); + } + + private static String createMessage(int selectionStart, + int selectionEnd, + int textLength, + List unknownHtmlTags) { + return "Illegal selection index for text with length " + textLength + + ", selectionStart: " + selectionStart + + ", selectionEnd: " + selectionEnd + + ", with " + UnknownHtmlSpan.class.getSimpleName() + " tags: " + unknownHtmlTags; + } + + @NotNull + private static List getUnknownHtmlTags(ReactAztecText view, int textLength) { + List unknownHtmlTags = new ArrayList<>(); + for (UnknownHtmlSpan span : view.getText().getSpans(0, textLength, UnknownHtmlSpan.class)) { + String rawHtml = span.getRawHtml().toString(); + unknownHtmlTags.addAll(parseTags(rawHtml)); + } + return unknownHtmlTags; + } + + @VisibleForTesting + @NonNull + static List parseTags(String html) { + List tags = new ArrayList<>(); + Matcher matcher = Pattern.compile("<([^\\\\s>/]+)>").matcher(html); + while (matcher.find()) { + tags.add(matcher.group(1)); + } + return tags; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecArrowKeyMovementMethod.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecArrowKeyMovementMethod.java new file mode 100644 index 00000000000000..97e25c35f02ee3 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecArrowKeyMovementMethod.java @@ -0,0 +1,21 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import android.text.Selection; +import android.text.Spannable; +import android.text.method.ArrowKeyMovementMethod; +import android.view.View; +import android.widget.TextView; + +public class ReactAztecArrowKeyMovementMethod extends ArrowKeyMovementMethod { + + @Override + public void onTakeFocus(TextView view, Spannable text, int dir) { + if ((dir & (View.FOCUS_FORWARD | View.FOCUS_DOWN)) != 0) { + if (view.getLayout() == null) { + Selection.setSelection(text, 0); // <-- setting caret to end of text + } + } else { + Selection.setSelection(text, text.length()); // <-- same as original Android implementation. Not sure if we should change this too + } + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBackSpaceEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBackSpaceEvent.java new file mode 100644 index 00000000000000..01f05b4849c38c --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBackSpaceEvent.java @@ -0,0 +1,49 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when Backspace is detected. + */ +class ReactAztecBackspaceEvent extends Event { + + private static final String EVENT_NAME = "topTextInputBackspace"; + + private String mText; + private int mSelectionStart; + private int mSelectionEnd; + + public ReactAztecBackspaceEvent(int viewId, String text, int selectionStart, int selectionEnd) { + super(viewId); + mText = text; + mSelectionStart = selectionStart; + mSelectionEnd = selectionEnd; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + eventData.putString("text", mText); + eventData.putInt("selectionStart", mSelectionStart); + eventData.putInt("selectionEnd", mSelectionEnd); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBlurEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBlurEvent.java new file mode 100644 index 00000000000000..3a8192b4397e63 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecBlurEvent.java @@ -0,0 +1,39 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when it loses focus. + */ +class ReactAztecBlurEvent extends Event { + + private static final String EVENT_NAME = "topBlur"; + + public ReactAztecBlurEvent(int viewId) { + super(viewId); + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEndEditingEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEndEditingEvent.java new file mode 100644 index 00000000000000..b6f38a012bac94 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEndEditingEvent.java @@ -0,0 +1,46 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by AztecText native view when text editing ends, + * because of the user leaving the text input. + */ +class ReactAztecEndEditingEvent extends Event { + + private static final String EVENT_NAME = "topEndEditing"; + + private String mText; + + public ReactAztecEndEditingEvent( + int viewId, + String text) { + super(viewId); + mText = text; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + eventData.putString("text", mText); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEnterEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEnterEvent.java new file mode 100644 index 00000000000000..3fc6d11653111d --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecEnterEvent.java @@ -0,0 +1,56 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when KEYCODE_ENTER is detected. + */ +class ReactAztecEnterEvent extends Event { + + private static final String EVENT_NAME = "topTextInputEnter"; + + private String mText; + private int mSelectionStart; + private int mSelectionEnd; + private boolean mFiredAfterTextChanged; + private int mEventCount; + + public ReactAztecEnterEvent(int viewId, String text, int selectionStart, int selectionEnd, + boolean firedAfterTextChanged, int eventCount) { + super(viewId); + mText = text; + mSelectionStart = selectionStart; + mSelectionEnd = selectionEnd; + mFiredAfterTextChanged = firedAfterTextChanged; + mEventCount = eventCount; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + eventData.putString("text", mText); + eventData.putInt("selectionStart", mSelectionStart); + eventData.putInt("selectionEnd", mSelectionEnd); + eventData.putBoolean("firedAfterTextChanged", mFiredAfterTextChanged); + eventData.putInt("eventCount", mEventCount); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFocusEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFocusEvent.java new file mode 100644 index 00000000000000..1cfb18fd136436 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFocusEvent.java @@ -0,0 +1,39 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when it receives focus. + */ +class ReactAztecFocusEvent extends Event { + + private static final String EVENT_NAME = "topFocus"; + + public ReactAztecFocusEvent(int viewId) { + super(viewId); + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFormattingChangeEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFormattingChangeEvent.java new file mode 100644 index 00000000000000..2929f2cda7ea5a --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecFormattingChangeEvent.java @@ -0,0 +1,45 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when it receives focus. + */ +class ReactAztecFormattingChangeEvent extends Event { + + private static final String EVENT_NAME = "topFormatsChanges"; + + private String[] mFormats; + + public ReactAztecFormattingChangeEvent(int viewId, String[] formats) { + super(viewId); + this.mFormats = formats; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + WritableArray newFormats = Arguments.fromArray(mFormats); + eventData.putArray("formats", newFormats); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecManager.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecManager.java new file mode 100644 index 00000000000000..013b9794ea54ad --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecManager.java @@ -0,0 +1,738 @@ +package org.wordpress.mobile.ReactNativeAztec; + + +import android.graphics.Color; +import android.graphics.Typeface; +import android.os.Build; +import androidx.annotation.Nullable; +import androidx.core.graphics.ColorUtils; +import androidx.core.util.Consumer; + +import android.os.Handler; +import android.os.Looper; +import android.text.Editable; +import android.text.Layout; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.util.TypedValue; +import android.view.Gravity; +import android.view.View; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.MapBuilder; +import com.facebook.react.uimanager.BaseViewManager; +import com.facebook.react.uimanager.LayoutShadowNode; +import com.facebook.react.uimanager.PixelUtil; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.ViewDefaults; +import com.facebook.react.uimanager.ViewProps; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.uimanager.events.EventDispatcher; +import com.facebook.react.views.scroll.ScrollEvent; +import com.facebook.react.views.scroll.ScrollEventType; +import com.facebook.react.views.text.DefaultStyleValuesUtil; +import com.facebook.react.views.text.ReactFontManager; +import com.facebook.react.views.text.ReactTextUpdate; +import com.facebook.react.views.textinput.ReactContentSizeChangedEvent; +import com.facebook.react.views.textinput.ReactTextChangedEvent; +import com.facebook.react.views.textinput.ReactTextInputEvent; +import com.facebook.react.views.textinput.ReactTextInputManager; +import com.facebook.react.views.textinput.ScrollWatcher; + +import org.wordpress.aztec.formatting.LinkFormatter; +import org.wordpress.aztec.glideloader.GlideImageLoader; +import org.wordpress.aztec.glideloader.GlideVideoThumbnailLoader; +import org.wordpress.aztec.plugins.CssUnderlinePlugin; +import org.wordpress.aztec.plugins.shortcodes.AudioShortcodePlugin; +import org.wordpress.aztec.plugins.shortcodes.CaptionShortcodePlugin; +import org.wordpress.aztec.plugins.shortcodes.VideoShortcodePlugin; +import org.wordpress.aztec.plugins.wpcomments.HiddenGutenbergPlugin; +import org.wordpress.aztec.plugins.wpcomments.WordPressCommentsPlugin; +import org.wordpress.aztec.plugins.wpcomments.toolbar.MoreToolbarButton; + +import java.util.Map; +import java.util.ArrayList; +import java.util.Arrays; + +public class ReactAztecManager extends BaseViewManager { + + public static final String REACT_CLASS = "RCTAztecView"; + + private static final int FOCUS_TEXT_INPUT = 1; + private static final int BLUR_TEXT_INPUT = 2; + private static final int UNSET = -1; + + // we define the same codes in ReactAztecText as they have for ReactNative's TextInput, so + // it's easier to handle focus between Aztec and TextInput instances on the same screen. + // see https://github.com/wordpress-mobile/react-native-aztec/pull/79 + private int mFocusTextInputCommandCode = FOCUS_TEXT_INPUT; // pre-init + private int mBlurTextInputCommandCode = BLUR_TEXT_INPUT; // pre-init + + private static final String TAG = "ReactAztecText"; + + private static final String BLOCK_TYPE_TAG_KEY = "tag"; + + @Nullable private final Consumer exceptionLogger; + @Nullable private final Consumer breadcrumbLogger; + + public ReactAztecManager(@Nullable Consumer exceptionLogger, @Nullable Consumer breadcrumbLogger) { + this.exceptionLogger = exceptionLogger; + this.breadcrumbLogger = breadcrumbLogger; + initializeFocusAndBlurCommandCodes(); + } + + private void initializeFocusAndBlurCommandCodes() { + // For this, we'd like to keep track of potential command code changes in the future, + // so we obtain an instance of ReactTextInputManager and call getCommandsMap in our + // constructor to use the very same codes as TextInput does. + ReactTextInputManager reactTextInputManager = new ReactTextInputManager(); + Map map = reactTextInputManager.getCommandsMap(); + mFocusTextInputCommandCode = map.get("focusTextInput"); + mBlurTextInputCommandCode = map.get("blurTextInput"); + } + + @Override + public String getName() { + return REACT_CLASS; + } + + @Override + protected ReactAztecText createViewInstance(ThemedReactContext reactContext) { + ReactAztecText aztecText = new ReactAztecText(reactContext); + aztecText.setFocusableInTouchMode(false); + aztecText.setFocusable(false); + aztecText.setCalypsoMode(false); + aztecText.setPadding(0, 0, 0, 0); + // This is a temporary hack that sets the correct GB link color and underline + // see: https://github.com/wordpress-mobile/gutenberg-mobile/pull/1109 + aztecText.setLinkFormatter(new LinkFormatter(aztecText, + new LinkFormatter.LinkStyle( + Color.parseColor("#016087"), true) + )); + aztecText.addPlugin(new CssUnderlinePlugin()); + return aztecText; + } + + @Override + public LayoutShadowNode createShadowNodeInstance() { + return new ReactAztecTextShadowNode(); + } + + @Override + public Class getShadowNodeClass() { + return ReactAztecTextShadowNode.class; + } + + @Nullable + @Override + public Map getExportedCustomBubblingEventTypeConstants() { + return MapBuilder.builder() + /* .put( + "topSubmitEditing", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of( + "bubbled", "onSubmitEditing", "captured", "onSubmitEditingCapture")))*/ + .put( + "topChange", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onChange"))) + .put( + "topFormatsChanges", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onActiveFormatsChange"))) + .put( + "topEndEditing", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onEndEditing", "captured", "onEndEditingCapture"))) + .put( + "topTextInput", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onTextInput", "captured", "onTextInputCapture"))) + .put( + "topTextInputEnter", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onEnter"))) + .put( + "topTextInputBackspace", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onBackspace"))) + .put( + "topTextInputPaste", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onPaste"))) + .put( + "topFocus", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onFocus", "captured", "onFocusCapture"))) + .put( + "topBlur", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onBlur", "captured", "onBlurCapture"))) + /* .put( + "topKeyPress", + MapBuilder.of( + "phasedRegistrationNames", + MapBuilder.of("bubbled", "onKeyPress", "captured", "onKeyPressCapture")))*/ + .build(); + } + + @Nullable + @Override + public Map getExportedCustomDirectEventTypeConstants() { + return MapBuilder.of( + "topSelectionChange", + MapBuilder.of("registrationName", "onSelectionChange") + ); + } + + @ReactProp(name = "text") + public void setText(ReactAztecText view, ReadableMap inputMap) { + if (!inputMap.hasKey("eventCount")) { + setTextfromJS(view, inputMap.getString("text"), inputMap.getMap("selection")); + } else { + // Don't think there is necessity of this branch, but justin case we want to + // force a 2nd setText from JS side to Native, just set a high eventCount + int eventCount = inputMap.getInt("eventCount"); + + if (view.mNativeEventCount < eventCount) { + setTextfromJS(view, inputMap.getString("text"), inputMap.getMap("selection")); + } + } + } + + private void setTextfromJS(ReactAztecText view, String text, @Nullable ReadableMap selection) { + view.setIsSettingTextFromJS(true); + view.disableOnSelectionListener(); + view.fromHtml(text, true); + view.enableOnSelectionListener(); + view.setIsSettingTextFromJS(false); + updateSelectionIfNeeded(view, selection); + } + + private void updateSelectionIfNeeded(ReactAztecText view, @Nullable ReadableMap selection) { + if ( selection != null ) { + int start = selection.getInt("start"); + int end = selection.getInt("end"); + int textLength = view.getText().length(); + boolean startAndEndAreValid = start >= 0 && + end >= 0 && + start <= textLength && + end <= textLength; + if (startAndEndAreValid) { + view.setSelection(start, end); + } else { + // Calling view.setSelection would have thrown an exception, so let's send information about + // what happened to help us figure out how we got into a bad state. + try { + IllegalSelectionIndexException customException = + new IllegalSelectionIndexException(start, end, textLength, view); + customException.printStackTrace(); + if (exceptionLogger != null) { + exceptionLogger.accept(customException); + } + if (breadcrumbLogger != null) { + breadcrumbLogger.accept(customException.getMessage()); + } + } catch (Exception e) { + // Should never happen, but if it does don't let logging cause a crash + e.printStackTrace(); + } + } + } + } + + @ReactProp(name = "activeFormats", defaultBoolean = false) + public void setActiveFormats(final ReactAztecText view, @Nullable ReadableArray activeFormats) { + if (activeFormats != null) { + String[] activeFormatsArray = new String[activeFormats.size()]; + for (int i = 0; i < activeFormats.size(); i++) { + activeFormatsArray[i] = activeFormats.getString(i); + } + view.setActiveFormats(Arrays.asList(activeFormatsArray)); + } else { + view.setActiveFormats(new ArrayList()); + } + } + + /* + The code below was taken from the class ReactTextInputManager + */ + @ReactProp(name = ViewProps.FONT_SIZE, defaultFloat = ViewDefaults.FONT_SIZE_SP) + public void setFontSize(ReactAztecText view, float fontSize) { + view.setTextSize( + TypedValue.COMPLEX_UNIT_PX, + (int) Math.ceil(PixelUtil.toPixelFromSP(fontSize))); + } + + @ReactProp(name = ViewProps.FONT_FAMILY) + public void setFontFamily(ReactAztecText view, String fontFamily) { + int style = Typeface.NORMAL; + if (view.getTypeface() != null) { + style = view.getTypeface().getStyle(); + } + Typeface newTypeface = ReactFontManager.getInstance().getTypeface( + fontFamily, + style, + view.getContext().getAssets()); + view.setTypeface(newTypeface); + } + + /** + /* This code was taken from the method setFontWeight of the class ReactTextShadowNode + /* TODO: Factor into a common place they can both use + */ + @ReactProp(name = ViewProps.FONT_WEIGHT) + public void setFontWeight(ReactAztecText view, @Nullable String fontWeightString) { + int fontWeightNumeric = fontWeightString != null ? + parseNumericFontWeight(fontWeightString) : -1; + int fontWeight = UNSET; + if (fontWeightNumeric >= 500 || "bold".equals(fontWeightString)) { + fontWeight = Typeface.BOLD; + } else if ("normal".equals(fontWeightString) || + (fontWeightNumeric != -1 && fontWeightNumeric < 500)) { + fontWeight = Typeface.NORMAL; + } + Typeface currentTypeface = view.getTypeface(); + if (currentTypeface == null) { + currentTypeface = Typeface.DEFAULT; + } + if (fontWeight != currentTypeface.getStyle()) { + view.setTypeface(currentTypeface, fontWeight); + } + } + + /** + /* This code was taken from the method setFontStyle of the class ReactTextShadowNode + /* TODO: Factor into a common place they can both use + */ + @ReactProp(name = ViewProps.FONT_STYLE) + public void setFontStyle(ReactAztecText view, @Nullable String fontStyleString) { + int fontStyle = UNSET; + if ("italic".equals(fontStyleString)) { + fontStyle = Typeface.ITALIC; + } else if ("normal".equals(fontStyleString)) { + fontStyle = Typeface.NORMAL; + } + + Typeface currentTypeface = view.getTypeface(); + if (currentTypeface == null) { + currentTypeface = Typeface.DEFAULT; + } + if (fontStyle != currentTypeface.getStyle()) { + view.setTypeface(currentTypeface, fontStyle); + } + } + + /** + * This code was taken from the method parseNumericFontWeight of the class ReactTextShadowNode + * TODO: Factor into a common place they can both use + * + * Return -1 if the input string is not a valid numeric fontWeight (100, 200, ..., 900), otherwise + * return the weight. + */ + private static int parseNumericFontWeight(String fontWeightString) { + // This should be much faster than using regex to verify input and Integer.parseInt + return fontWeightString.length() == 3 && fontWeightString.endsWith("00") + && fontWeightString.charAt(0) <= '9' && fontWeightString.charAt(0) >= '1' ? + 100 * (fontWeightString.charAt(0) - '0') : -1; + } + + /** + * This method is based on {@link ReactTextInputManager#setTextAlign}. The only change made to that method is to + * use {@link android.widget.TextView#setGravity} instead of a custom method that preserves vertical gravity + * like the setGravityHorizontal method from {@link com.facebook.react.views.textinput.ReactEditText}. The + * reason for this change was to simplify the code. Since we never set vertical gravity, we do not need to add + * the complexity of preserving vertical gravity—we can just use {@link android.widget.TextView#setGravity} + * directly. + */ + @ReactProp(name = ViewProps.TEXT_ALIGN) + public void setTextAlign(ReactAztecText view, @Nullable String textAlign) { + if ("justify".equals(textAlign)) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + view.setJustificationMode(Layout.JUSTIFICATION_MODE_INTER_WORD); + } + view.setGravity(Gravity.START); + } else { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + view.setJustificationMode(Layout.JUSTIFICATION_MODE_NONE); + } + + if (textAlign == null || "auto".equals(textAlign)) { + view.setGravity(Gravity.NO_GRAVITY); + } else if ("left".equals(textAlign)) { + view.setGravity(Gravity.START); + } else if ("right".equals(textAlign)) { + view.setGravity(Gravity.END); + } else if ("center".equals(textAlign)) { + view.setGravity(Gravity.CENTER_HORIZONTAL); + } else { + throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlign); + } + } + } + + @ReactProp(name = "linkTextColor", customType = "Color") + public void setLinkTextColor(ReactAztecText view, @Nullable Integer color) { + view.setLinkFormatter(new LinkFormatter(view, + new LinkFormatter.LinkStyle( + color, true) + )); + } + + /* End of the code taken from ReactTextInputManager */ + + @ReactProp(name = "color", customType = "Color") + public void setColor(ReactAztecText view, @Nullable Integer color) { + int newColor = Color.BLACK; + if (color != null) { + newColor = color; + } + view.setTextColor(newColor); + } + + @ReactProp(name = "selectionColor", customType = "Color") + public void setSelectionColor(ReactAztecText view, @Nullable Integer color) { + if (color != null) { + view.setHighlightColor(ColorUtils.setAlphaComponent(color, 51)); + view.setCursorColor(color); + } + } + + @ReactProp(name = "blockType") + public void setBlockType(ReactAztecText view, ReadableMap inputMap) { + if (inputMap.hasKey(BLOCK_TYPE_TAG_KEY)) { + view.setTagName(inputMap.getString(BLOCK_TYPE_TAG_KEY)); + } + } + + @ReactProp(name = "placeholder") + public void setPlaceholder(ReactAztecText view, @Nullable String placeholder) { + view.setHint(placeholder); + } + + @ReactProp(name = "placeholderTextColor", customType = "Color") + public void setPlaceholderTextColor(ReactAztecText view, @Nullable Integer color) { + if (color == null) { + view.setHintTextColor(DefaultStyleValuesUtil.getDefaultTextColorHint(view.getContext())); + } else { + view.setHintTextColor(color); + } + } + + @ReactProp(name = "maxImagesWidth") + public void setMaxImagesWidth(ReactAztecText view, int maxWidth) { + view.setMaxImagesWidth(maxWidth); + } + + @ReactProp(name = "minImagesWidth") + public void setMinImagesWidth(ReactAztecText view, int minWidth) { + view.setMinImagesWidth(minWidth); + } + + /* + * This property/method is used to disable the Gutenberg compatibility mode on AztecRN. + * + * Aztec comes along with some nice plugins that are able to show preview of Pictures/Videos/shortcodes, + * and WP specific features, in the visual editor. + * + * We don't need those improvements in Gutenberg mobile, so this RN wrapper around Aztec + * that's only used in GB-mobile at the moment, does have them OFF by default. + * + * An external 3rd party RN-app can use AztecRN wrapper and set the `disableGutenbergMode` to false to have a fully + * working visual editor. See the demo app, where `disableGutenbergMode` is already OFF. + */ + @ReactProp(name = "disableGutenbergMode", defaultBoolean = false) + public void disableGBMode(final ReactAztecText view, boolean disable) { + if (disable) { + view.addPlugin(new WordPressCommentsPlugin(view)); + view.addPlugin(new MoreToolbarButton(view)); + view.addPlugin(new CaptionShortcodePlugin(view)); + view.addPlugin(new VideoShortcodePlugin()); + view.addPlugin(new AudioShortcodePlugin()); + view.addPlugin(new HiddenGutenbergPlugin(view)); + view.setImageGetter(new GlideImageLoader(view.getContext())); + view.setVideoThumbnailGetter(new GlideVideoThumbnailLoader(view.getContext())); + // we need to restart the editor now + String content = view.toHtml(view.getText(), false); + view.fromHtml(content, false); + } + } + + @ReactProp(name = "onContentSizeChange", defaultBoolean = false) + public void setOnContentSizeChange(final ReactAztecText view, boolean onContentSizeChange) { + if (onContentSizeChange) { + view.setContentSizeWatcher(new AztecContentSizeWatcher(view)); + } else { + view.setContentSizeWatcher(null); + } + } + + @ReactProp(name = "onSelectionChange", defaultBoolean = false) + public void setOnSelectionChange(final ReactAztecText view, boolean onSelectionChange) { + view.shouldHandleOnSelectionChange = onSelectionChange; + } + + @ReactProp(name = "onScroll", defaultBoolean = false) + public void setOnScroll(final ReactAztecText view, boolean onScroll) { + if (onScroll) { + view.setScrollWatcher(new AztecScrollWatcher(view)); + } else { + view.setScrollWatcher(null); + } + } + + @ReactProp(name = "onEnter", defaultBoolean = false) + public void setOnEnterHandling(final ReactAztecText view, boolean onEnterHandling) { + view.shouldHandleOnEnter = onEnterHandling; + } + + @ReactProp(name = "onBackspace", defaultBoolean = false) + public void setOnBackspaceHandling(final ReactAztecText view, boolean onBackspaceHandling) { + view.shouldHandleOnBackspace = onBackspaceHandling; + } + + @ReactProp(name = "onPaste", defaultBoolean = false) + public void setOnPasteHandling(final ReactAztecText view, boolean onPasteHandling) { + view.shouldHandleOnPaste = onPasteHandling; + } + + @ReactProp(name = "deleteEnter", defaultBoolean = false) + public void setShouldDeleteEnter(final ReactAztecText view, boolean shouldDeleteEnter) { + view.shouldDeleteEnter = shouldDeleteEnter; + } + + @Override + public Map getCommandsMap() { + return MapBuilder.builder() + .put("focusTextInput", mFocusTextInputCommandCode) + .put("blurTextInput", mBlurTextInputCommandCode) + .build(); + } + + @Override + public void receiveCommand(final ReactAztecText parent, int commandType, @Nullable ReadableArray args) { + Assertions.assertNotNull(parent); + if (commandType == mFocusTextInputCommandCode) { + // schedule a request to focus in the next layout, to fix https://github.com/wordpress-mobile/gutenberg-mobile/issues/1870 + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + parent.requestFocusFromJS(); + } + }); + return; + } else if (commandType == mBlurTextInputCommandCode) { + parent.clearFocusFromJS(); + return; + } + super.receiveCommand(parent, commandType, args); + } + + @Override + protected void addEventEmitters(final ThemedReactContext reactContext, final ReactAztecText aztecText) { + aztecText.addTextChangedListener(new AztecTextWatcher(reactContext, aztecText)); + aztecText.setOnFocusChangeListener( + new View.OnFocusChangeListener() { + public void onFocusChange(View v, boolean hasFocus) { + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + final ReactAztecText editText = (ReactAztecText)v; + if (hasFocus) { + eventDispatcher.dispatchEvent( + new ReactAztecFocusEvent( + editText.getId())); + } else { + eventDispatcher.dispatchEvent( + new ReactAztecBlurEvent( + editText.getId())); + + eventDispatcher.dispatchEvent( + new ReactAztecEndEditingEvent( + editText.getId(), + editText.toHtml(editText.getText(), false))); + } + } + }); + + // Don't think we need to add setOnEditorActionListener here (intercept Enter for example), but + // in case check ReactTextInputManager + } + + @Override + public void updateExtraData(ReactAztecText view, Object extraData) { + if (extraData instanceof ReactTextUpdate) { + ReactTextUpdate update = (ReactTextUpdate) extraData; + + view.setPadding( + (int) update.getPaddingLeft(), + (int) update.getPaddingTop(), + (int) update.getPaddingRight(), + (int) update.getPaddingBottom()); + } + } + + private class AztecTextWatcher implements TextWatcher { + + private EventDispatcher mEventDispatcher; + private ReactAztecText mEditText; + private String mPreviousText; + + public AztecTextWatcher(final ReactContext reactContext, final ReactAztecText aztecText) { + mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + mEditText = aztecText; + mPreviousText = null; + } + + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + // Incoming charSequence gets mutated before onTextChanged() is invoked + mPreviousText = s.toString(); + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + // Rearranging the text (i.e. changing between singleline and multiline attributes) can + // also trigger onTextChanged, call the event in JS only when the text actually changed + if (count == 0 && before == 0) { + return; + } + + Assertions.assertNotNull(mPreviousText); + String newText = s.toString().substring(start, start + count); + String oldText = mPreviousText.substring(start, start + before); + // Don't send same text changes + if (count == before && newText.equals(oldText)) { + return; + } + + // if the "Enter" handling is underway, don't sent text change events. The ReactAztecEnterEvent will have + // the text (minus the Enter char itself). + if (!mEditText.isEnterPressedUnderway()) { + int currentEventCount = mEditText.incrementAndGetEventCounter(); + // The event that contains the event counter and updates it must be sent first. + // TODO: t7936714 merge these events + mEventDispatcher.dispatchEvent( + new ReactTextChangedEvent( + mEditText.getId(), + mEditText.toHtml(mEditText.getText(), false), + currentEventCount)); + + mEventDispatcher.dispatchEvent( + new ReactTextInputEvent( + mEditText.getId(), + newText, + oldText, + start, + start + before)); + } + + + if (mPreviousText.length() == 0 + && !TextUtils.isEmpty(newText) + && !TextUtils.isEmpty(mEditText.getTagName()) + && mEditText.getSelectedStyles().isEmpty()) { + + // Some block types (e.g. header block ) need to be created with default style (e.g. h2) + // In order to achieve that, we need to toggle formatting with proper style, + // otherwise header block won't be created with style, it will be presented as plain text + ReactAztecTextFormatEnum reactAztecTextFormat = ReactAztecTextFormatEnum.get(mEditText.getTagName()); + if (reactAztecTextFormat != null) { + mEditText.toggleFormatting(reactAztecTextFormat.getAztecTextFormat()); + } + } + } + + @Override + public void afterTextChanged(Editable s) { + } + } + + private class AztecContentSizeWatcher implements com.facebook.react.views.textinput.ContentSizeWatcher { + private ReactAztecText mReactAztecText; + private EventDispatcher mEventDispatcher; + private int mPreviousContentWidth = 0; + private int mPreviousContentHeight = 0; + + public AztecContentSizeWatcher(ReactAztecText view) { + mReactAztecText = view; + ReactContext reactContext = (ReactContext) mReactAztecText.getContext(); + mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + } + + @Override + public void onLayout() { + int contentWidth = mReactAztecText.getWidth(); + int contentHeight = mReactAztecText.getHeight(); + + // Use instead size of text content within EditText when available + if (mReactAztecText.getLayout() != null) { + contentWidth = mReactAztecText.getCompoundPaddingLeft() + mReactAztecText.getLayout().getWidth() + + mReactAztecText.getCompoundPaddingRight(); + contentHeight = mReactAztecText.getCompoundPaddingTop() + mReactAztecText.getLayout().getHeight() + + mReactAztecText.getCompoundPaddingBottom(); + } + + if (contentWidth != mPreviousContentWidth || contentHeight != mPreviousContentHeight) { + mPreviousContentHeight = contentHeight; + mPreviousContentWidth = contentWidth; + + // FIXME: Note the 2 hacks here + mEventDispatcher.dispatchEvent( + new ReactContentSizeChangedEvent( + mReactAztecText.getId(), + PixelUtil.toDIPFromPixel(contentWidth), + PixelUtil.toDIPFromPixel(contentHeight))); + } + } + } + + private class AztecScrollWatcher implements ScrollWatcher { + + private ReactAztecText mReactAztecText; + private EventDispatcher mEventDispatcher; + private int mPreviousHoriz; + private int mPreviousVert; + + public AztecScrollWatcher(ReactAztecText editText) { + mReactAztecText = editText; + ReactContext reactContext = (ReactContext) editText.getContext(); + mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + } + + @Override + public void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { + if (mPreviousHoriz != horiz || mPreviousVert != vert) { + ScrollEvent event = ScrollEvent.obtain( + mReactAztecText.getId(), + ScrollEventType.SCROLL, + horiz, + vert, + 0f, // can't get x velocity + 0f, // can't get y velocity + 0, // can't get content width + 0, // can't get content height + mReactAztecText.getWidth(), + mReactAztecText.getHeight()); + + mEventDispatcher.dispatchEvent(event); + + mPreviousHoriz = horiz; + mPreviousVert = vert; + } + } + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPackage.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPackage.java new file mode 100644 index 00000000000000..a970a68d2315bf --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPackage.java @@ -0,0 +1,36 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import androidx.core.util.Consumer; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class ReactAztecPackage implements ReactPackage { + + private final Consumer exceptionLogger; + private final Consumer breadcrumbLogger; + + public ReactAztecPackage(Consumer exceptionLogger, Consumer breadcrumbLogger) { + this.exceptionLogger = exceptionLogger; + this.breadcrumbLogger = breadcrumbLogger; + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + List views = new ArrayList<>(); + views.add(new ReactAztecManager(exceptionLogger, breadcrumbLogger)); + return views; + } + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } + +} \ No newline at end of file diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPasteEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPasteEvent.java new file mode 100644 index 00000000000000..0b6557ba9aaa7f --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecPasteEvent.java @@ -0,0 +1,56 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when paste is detected. + */ +class ReactAztecPasteEvent extends Event { + + private static final String EVENT_NAME = "topTextInputPaste"; + + private String mCurrentContent; + private int mSelectionStart; + private int mSelectionEnd; + private String mPastedText; + private String mPastedHtml; + + public ReactAztecPasteEvent(int viewId, String currentContent, int selectionStart, + int selectionEnd, String pastedText, String pastedHtml) { + super(viewId); + mCurrentContent = currentContent; + mSelectionStart = selectionStart; + mSelectionEnd = selectionEnd; + mPastedText = pastedText; + mPastedHtml = pastedHtml; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + eventData.putString("currentContent", mCurrentContent); + eventData.putInt("selectionStart", mSelectionStart); + eventData.putInt("selectionEnd", mSelectionEnd); + eventData.putString("pastedText", mPastedText); + eventData.putString("pastedHtml", mPastedHtml); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecSelectionChangeEvent.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecSelectionChangeEvent.java new file mode 100644 index 00000000000000..bb553b9daf334f --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecSelectionChangeEvent.java @@ -0,0 +1,53 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.RCTEventEmitter; + +/** + * Event emitted by Aztec native view when selection changes. + */ +class ReactAztecSelectionChangeEvent extends Event { + + private static final String EVENT_NAME = "topSelectionChange"; + + private String mText; + private int mSelectionStart; + private int mSelectionEnd; + private int mEventCount; + + public ReactAztecSelectionChangeEvent(int viewId, String text, int selectionStart, int selectionEnd, int eventCount) { + super(viewId); + mText = text; + mSelectionStart = selectionStart; + mSelectionEnd = selectionEnd; + mEventCount = eventCount; + } + + @Override + public String getEventName() { + return EVENT_NAME; + } + + @Override + public boolean canCoalesce() { + return false; + } + + @Override + public void dispatch(RCTEventEmitter rctEventEmitter) { + rctEventEmitter.receiveEvent(getViewTag(), getEventName(), serializeEventData()); + } + + private WritableMap serializeEventData() { + WritableMap eventData = Arguments.createMap(); + eventData.putInt("target", getViewTag()); + eventData.putString("text", mText); + eventData.putInt("selectionStart", mSelectionStart); + eventData.putInt("selectionEnd", mSelectionEnd); + eventData.putInt("eventCount", mEventCount); + return eventData; + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecText.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecText.java new file mode 100644 index 00000000000000..4089b8d87d9d9a --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecText.java @@ -0,0 +1,640 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import android.content.ClipData; +import android.content.ClipboardManager; +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.graphics.PorterDuff; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import android.text.Editable; +import android.text.InputType; +import android.text.Spannable; +import android.text.TextUtils; +import android.text.TextWatcher; +import android.view.inputmethod.InputMethodManager; +import android.widget.TextView; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIManagerModule; +import com.facebook.react.uimanager.events.EventDispatcher; +import com.facebook.react.views.textinput.ContentSizeWatcher; +import com.facebook.react.views.textinput.ReactTextInputLocalData; +import com.facebook.react.views.textinput.ScrollWatcher; + +import org.wordpress.android.util.AppLog; +import org.wordpress.aztec.AlignmentRendering; +import org.wordpress.aztec.AztecText; +import org.wordpress.aztec.AztecTextFormat; +import org.wordpress.aztec.ITextFormat; +import org.wordpress.aztec.plugins.IAztecPlugin; +import org.wordpress.aztec.plugins.IToolbarButton; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Set; +import java.util.HashSet; +import java.util.HashMap; + +import static android.content.ClipData.*; + +public class ReactAztecText extends AztecText { + + private static final String PRE_TAG = "pre"; + + private final InputMethodManager mInputMethodManager; + // This flag is set to true when we set the text of the EditText explicitly. In that case, no + // *TextChanged events should be triggered. This is less expensive than removing the text + // listeners and adding them back again after the text change is completed. + private boolean mIsSettingTextFromJS = false; + // This component is controlled, so we want it to get focused only when JS ask it to do so. + // Whenever android requests focus (which it does for random reasons), it will be ignored. + private boolean mIsJSSettingFocus = false; + private @Nullable ArrayList mListeners; + private @Nullable TextWatcherDelegator mTextWatcherDelegator; + private @Nullable ContentSizeWatcher mContentSizeWatcher; + private @Nullable ScrollWatcher mScrollWatcher; + + // FIXME: Used in `incrementAndGetEventCounter` but never read. I guess we can get rid of it, but before this + // check when it's used in EditText in RN. (maybe tests?) + int mNativeEventCount = 0; + + String lastSentFormattingOptionsEventString = ""; + boolean shouldHandleOnEnter = false; + boolean shouldHandleOnBackspace = false; + boolean shouldHandleOnPaste = false; + boolean shouldHandleOnSelectionChange = false; + boolean shouldHandleActiveFormatsChange = false; + + boolean shouldDeleteEnter = false; + + // This optional variable holds the outer HTML tag that will be added to the text when the user start typing in it + // This is required to keep placeholder text working, and start typing with styled text. + // Ref: https://github.com/wordpress-mobile/gutenberg-mobile/issues/707 + private String mTagName = ""; + private String mEmptyTagHTML = ""; + + private static final HashMap typingFormatsMap = new HashMap() { + { + put(AztecTextFormat.FORMAT_BOLD, "bold"); + put(AztecTextFormat.FORMAT_STRONG, "bold"); + put(AztecTextFormat.FORMAT_EMPHASIS, "italic"); + put(AztecTextFormat.FORMAT_ITALIC, "italic"); + put(AztecTextFormat.FORMAT_CITE, "italic"); + put(AztecTextFormat.FORMAT_STRIKETHROUGH, "strikethrough"); + put(AztecTextFormat.FORMAT_UNDERLINE, "underline"); + } + }; + + public ReactAztecText(ThemedReactContext reactContext) { + super(reactContext, AlignmentRendering.VIEW_LEVEL); + + setGutenbergMode(true); + + // don't auto-focus when Aztec becomes visible. + // Needed on rotation and multiple Aztec instances to avoid losing the exact care position. + setFocusOnVisible(false); + + forceCaretAtStartOnTakeFocus(); + + this.setAztecKeyListener(new ReactAztecText.OnAztecKeyListener() { + @Override + public boolean onEnterKey(Spannable text, boolean firedAfterTextChanged, int selStart, int selEnd) { + if (shouldHandleOnEnter && !isTextChangedListenerDisabled()) { + return onEnter(text, firedAfterTextChanged, selStart, selEnd); + } + return false; + } + @Override + public boolean onBackspaceKey() { + if (shouldHandleOnBackspace && !isTextChangedListenerDisabled()) { + String content = toHtml(getText(), false); + if (TextUtils.isEmpty(content)) { + return onBackspace(); + } + else { + if (!content.equals(mEmptyTagHTML)) { + return onBackspace(); + } + } + } + return false; + } + }); + + mInputMethodManager = (InputMethodManager) + Assertions.assertNotNull(getContext().getSystemService(Context.INPUT_METHOD_SERVICE)); + this.setOnSelectionChangedListener(new OnSelectionChangedListener() { + @Override + public void onSelectionChanged(int selStart, int selEnd) { + ReactAztecText.this.updateToolbarButtons(selStart, selEnd); + ReactAztecText.this.propagateSelectionChanges(selStart, selEnd); + } + }); + this.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | InputType.TYPE_TEXT_FLAG_MULTI_LINE); + } + + private void forceCaretAtStartOnTakeFocus() { + // set a custom ArrowKeyMovementMethod: sets caret to the start of the text instead of the default (end of text) + // Fixes https://github.com/wordpress-mobile/gutenberg-mobile/issues/602 + // onTakeFocus adapted from the Android source code at: + // https://android.googlesource.com/platform/frameworks/base/+/refs/heads/pie-release/core/java/android/text/method/ArrowKeyMovementMethod.java#316 + setMovementMethod(new ReactAztecArrowKeyMovementMethod()); + } + + @Override + public void refreshText() { + super.refreshText(); + onContentSizeChange(); + } + + void addPlugin(IAztecPlugin plugin) { + super.getPlugins().add(plugin); + if (plugin instanceof IToolbarButton && getToolbar() != null ) { + getToolbar().addButton((IToolbarButton)plugin); + } + } + + @Override + public boolean onTextContextMenuItem(int id) { + if (shouldHandleOnPaste) { + switch (id) { + case android.R.id.paste: + return onPaste(false); + case android.R.id.pasteAsPlainText: + return onPaste(true); + } + } + + return super.onTextContextMenuItem(id); + } + + @Override + public float getPreformatBackgroundAlpha(@NonNull TypedArray styles) { + return 0; + } + + @Override + public boolean shouldSkipTidying() { + return isPreTag(); + } + + @Override + public boolean shouldIgnoreWhitespace() { + return false; + } + + // VisibleForTesting from {@link TextInputEventsTestCase}. + public void requestFocusFromJS() { + mIsJSSettingFocus = true; + requestFocus(); + new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { + @Override + public void run() { + // let's pinpoint the caret line to ask the system to bring that line into the viewport + // we need to make sure that getLayout() isn't null + // because it will cause the NPE: https://github.com/wordpress-mobile/WordPress-Android/issues/11821 + if (getLayout() == null) { + AppLog.w(AppLog.T.EDITOR, + "Layout is null while trying to scroll inside a ReactAztecText block. Canceling the scroll."); + return; + } + + int lineNumber = getLayout().getLineForOffset(getSelectionStart()); + + Rect caretLineRect = new Rect(); + getLineBounds(lineNumber, caretLineRect); + requestRectangleOnScreen(caretLineRect); + } + }, 100); + mIsJSSettingFocus = false; + } + + void clearFocusFromJS() { + clearFocus(); + } + + @Override + public void clearFocus() { + setFocusableInTouchMode(false); + setFocusable(false); + super.clearFocus(); + hideSoftKeyboard(); + } + + @Override + public boolean requestFocus(int direction, Rect previouslyFocusedRect) { + // Always return true if we are already focused. This is used by android in certain places, + // such as text selection. + if (isFocused()) { + return true; + } + //TODO check why it's needed - doesn't seem to work fine with this in it, since each focus call + // from the Android FW is skipped here. + /*if (!mIsJSSettingFocus) { + return false; + }*/ + setFocusableInTouchMode(true); + setFocusable(true); + boolean focused = super.requestFocus(direction, previouslyFocusedRect); + showSoftKeyboard(); + return focused; + } + + private void showSoftKeyboard() { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + if (mInputMethodManager != null) { + mInputMethodManager.showSoftInput(ReactAztecText.this, 0); + } + } + }); + } + + private void hideSoftKeyboard() { + mInputMethodManager.hideSoftInputFromWindow(getWindowToken(), 0); + } + + public void setScrollWatcher(ScrollWatcher scrollWatcher) { + mScrollWatcher = scrollWatcher; + } + + @Override + protected void onScrollChanged(int horiz, int vert, int oldHoriz, int oldVert) { + super.onScrollChanged(horiz, vert, oldHoriz, oldVert); + + if (mScrollWatcher != null) { + mScrollWatcher.onScrollChanged(horiz, vert, oldHoriz, oldVert); + } + } + + public void setContentSizeWatcher(ContentSizeWatcher contentSizeWatcher) { + mContentSizeWatcher = contentSizeWatcher; + } + + private void onContentSizeChange() { + if (mContentSizeWatcher != null) { + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + if (mContentSizeWatcher != null) { + mContentSizeWatcher.onLayout(); + } + } + }); + } + setIntrinsicContentSize(); + } + + public void setTagName(@Nullable String tagName) { + mTagName = tagName; + mEmptyTagHTML = "<" + mTagName + ">"; + } + + public String getTagName() { + return mTagName; + } + + + private void updateToolbarButtons(int selStart, int selEnd) { + ArrayList appliedStyles = getAppliedStyles(selStart, selEnd); + updateToolbarButtons(appliedStyles); + } + + private void updateToolbarButtons(ArrayList appliedStyles) { + // Read the applied styles and get the String list of formatting options + LinkedList formattingOptions = new LinkedList<>(); + for (ITextFormat currentStyle : appliedStyles) { + if ((currentStyle == AztecTextFormat.FORMAT_STRONG || currentStyle == AztecTextFormat.FORMAT_BOLD) + && !formattingOptions.contains("bold")) { + formattingOptions.add("bold"); + } + if ((currentStyle == AztecTextFormat.FORMAT_ITALIC || currentStyle == AztecTextFormat.FORMAT_CITE) + && !formattingOptions.contains("italic")) { + formattingOptions.add("italic"); + } + if (currentStyle == AztecTextFormat.FORMAT_STRIKETHROUGH) { + formattingOptions.add("strikethrough"); + } + } + + // Check if the same formatting event was already sent + String newOptionsAsString = ""; + for (String currentFormatting: formattingOptions) { + newOptionsAsString += currentFormatting; + } + if (newOptionsAsString.equals(lastSentFormattingOptionsEventString)) { + // no need to send any event now + return; + } + lastSentFormattingOptionsEventString = newOptionsAsString; + + if (shouldHandleActiveFormatsChange) { + ReactContext reactContext = (ReactContext) getContext(); + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + eventDispatcher.dispatchEvent( + new ReactAztecFormattingChangeEvent( + getId(), + formattingOptions.toArray(new String[formattingOptions.size()]) + ) + ); + } + } + + private void propagateSelectionChanges(int selStart, int selEnd) { + if (!shouldHandleOnSelectionChange) { + return; + } + String content = toHtml(getText(), false); + ReactContext reactContext = (ReactContext) getContext(); + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + eventDispatcher.dispatchEvent( + new ReactAztecSelectionChangeEvent(getId(), content, selStart, selEnd, incrementAndGetEventCounter()) + ); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + onContentSizeChange(); + } + + private void setIntrinsicContentSize() { + ReactContext reactContext = (ReactContext) getContext(); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + final ReactTextInputLocalData localData = new ReactTextInputLocalData(this); + uiManager.setViewLocalData(getId(), localData); + } + + //// Text changed events + + public int incrementAndGetEventCounter() { + return ++mNativeEventCount; + } + + @Override + public void addTextChangedListener(TextWatcher watcher) { + if (mListeners == null) { + mListeners = new ArrayList<>(); + super.addTextChangedListener(getTextWatcherDelegator()); + + // Keep the enter pressed watcher at the beginning of the watchers list. + // We want to intercept Enter.key as soon as possible, and before other listeners start modifying the text. + // Also note that this Watchers, when the AztecKeyListener is set, keep hold a copy of the content in the editor. + mListeners.add(new EnterPressedWatcher(this, new EnterDeleter() { + @Override + public boolean shouldDeleteEnter() { + return shouldDeleteEnter; + } + })); + } + + mListeners.add(watcher); + } + + @Override + public void removeTextChangedListener(TextWatcher watcher) { + if (mListeners != null) { + mListeners.remove(watcher); + + if (mListeners.isEmpty()) { + mListeners = null; + super.removeTextChangedListener(getTextWatcherDelegator()); + } + } + } + + private TextWatcherDelegator getTextWatcherDelegator() { + if (mTextWatcherDelegator == null) { + mTextWatcherDelegator = new TextWatcherDelegator(); + } + return mTextWatcherDelegator; + } + + public void setIsSettingTextFromJS(boolean mIsSettingTextFromJS) { + this.mIsSettingTextFromJS = mIsSettingTextFromJS; + } + + private boolean onEnter(Spannable text, boolean firedAfterTextChanged, int selStart, int selEnd) { + disableTextChangedListener(); + String content = toHtml(text, false); + int cursorPositionStart = firedAfterTextChanged ? selStart : getSelectionStart(); + int cursorPositionEnd = firedAfterTextChanged ? selEnd : getSelectionEnd(); + enableTextChangedListener(); + ReactContext reactContext = (ReactContext) getContext(); + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + eventDispatcher.dispatchEvent( + new ReactAztecEnterEvent(getId(), content, cursorPositionStart, cursorPositionEnd, + firedAfterTextChanged, incrementAndGetEventCounter()) + ); + return true; + } + + private boolean onBackspace() { + int cursorPositionStart = getSelectionStart(); + int cursorPositionEnd = getSelectionEnd(); + // Make sure to report backspace at the beginning only, with no selection. + if (cursorPositionStart != 0 || cursorPositionEnd != 0) { + return false; + } + + disableTextChangedListener(); + String content = toHtml(getText(), false); + enableTextChangedListener(); + ReactContext reactContext = (ReactContext) getContext(); + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + // TODO: isRTL? Should be passed here? + eventDispatcher.dispatchEvent( + new ReactAztecBackspaceEvent(getId(), content, cursorPositionStart, cursorPositionEnd) + ); + return true; + } + + /** + * Handle paste action by retrieving clipboard contents and dispatching a + * {@link ReactAztecPasteEvent} with the data + * + * @param isPastedAsPlainText boolean indicating whether the paste action chosen was + * "PASTE AS PLAIN TEXT" + * + * @return boolean to indicate that the action was handled (always true) + */ + private boolean onPaste(boolean isPastedAsPlainText) { + ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService( + Context.CLIPBOARD_SERVICE); + + StringBuilder text = new StringBuilder(); + StringBuilder html = new StringBuilder(); + + if (clipboardManager != null && clipboardManager.hasPrimaryClip()) { + ClipData clipData = clipboardManager.getPrimaryClip(); + int itemCount = clipData.getItemCount(); + + for (int i = 0; i < itemCount; i++) { + Item item = clipData.getItemAt(i); + text.append(item.coerceToText(getContext())); + if (!isPastedAsPlainText) { + html.append(item.coerceToHtmlText(getContext())); + } + } + } + + // temporarily disable listener during call to toHtml() + disableTextChangedListener(); + String content = toHtml(getText(), false); + int cursorPositionStart = getSelectionStart(); + int cursorPositionEnd = getSelectionEnd(); + enableTextChangedListener(); + ReactContext reactContext = (ReactContext) getContext(); + EventDispatcher eventDispatcher = reactContext.getNativeModule(UIManagerModule.class) + .getEventDispatcher(); + eventDispatcher.dispatchEvent(new ReactAztecPasteEvent(getId(), content, + cursorPositionStart, cursorPositionEnd, text.toString(), html.toString()) + ); + return true; + } + + public void setActiveFormats(Iterable newFormats) { + Set selectedStylesSet = new HashSet<>(getSelectedStyles()); + Set newFormatsSet = new HashSet<>(); + for (String newFormat : newFormats) { + switch (newFormat) { + case "bold": + newFormatsSet.add(AztecTextFormat.FORMAT_STRONG); + break; + case "italic": + newFormatsSet.add(AztecTextFormat.FORMAT_EMPHASIS); + break; + case "strikethrough": + newFormatsSet.add(AztecTextFormat.FORMAT_STRIKETHROUGH); + break; + case "underline": + newFormatsSet.add(AztecTextFormat.FORMAT_UNDERLINE); + break; + } + } + selectedStylesSet.removeAll(typingFormatsMap.keySet()); + selectedStylesSet.addAll(newFormatsSet); + ArrayList newStylesList = new ArrayList<>(selectedStylesSet); + setSelectedStyles(newStylesList); + updateToolbarButtons(newStylesList); + } + + protected boolean isEnterPressedUnderway() { + return EnterPressedWatcher.Companion.isEnterPressedUnderway(getText()); + } + + /** + * This class will redirect *TextChanged calls to the listeners only in the case where the text + * is changed by the user, and not explicitly set by JS. + * + * Update: + * There is a special case when block is preformatted. + * In that case we want to propagate TextWatcher method calls even if text is set from JS. + * Otherwise, couple of bugs will be introduced + * bug 1# https://github.com/wordpress-mobile/AztecEditor-Android/pull/869#issuecomment-552864686 + * bug 2# https://github.com/wordpress-mobile/gutenberg-mobile/pull/1615#pullrequestreview-323274540 + */ + private class TextWatcherDelegator implements TextWatcher { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + if (shouldDelegateTextChangeCalls()) { + for (TextWatcher listener : mListeners) { + listener.beforeTextChanged(s, start, count, after); + } + } + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + if (shouldDelegateTextChangeCalls()) { + for (TextWatcher listener : mListeners) { + listener.onTextChanged(s, start, before, count); + } + } + + onContentSizeChange(); + } + + @Override + public void afterTextChanged(Editable s) { + if (shouldDelegateTextChangeCalls()) { + for (TextWatcher listener : mListeners) { + listener.afterTextChanged(s); + } + } + } + } + + private boolean shouldDelegateTextChangeCalls() { + if (mListeners == null) { + // No listeners so, no one to delegate the calls to + return false; + } + + if (isPreTag()) { + // If tag is pre tag we want to delegate calls in every case + return true; + } + + return !mIsSettingTextFromJS; + } + + private boolean isPreTag() { + return PRE_TAG.equals(mTagName); + } + + public void setCursorColor(@NonNull Integer color) { + // This is combination of the patterns taken in: + // - https://github.com/facebook/react-native/blob/233fdfc014bb4b919c7624c90e5dac614479076f/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java#L422-L457 + // - https://stackoverflow.com/a/44333069/1350218 + // Note: This only works in API 27 and below as it uses reflection to look up the drawable fields. + // API 29 supports setTextCursorDrawable which would be a cleaner way to handle this when + // an upgrade to that API level occurs. + + try { + Resources res = getContext().getResources(); + + Field field = TextView.class.getDeclaredField("mEditor"); + field.setAccessible(true); + Object editor = field.get(this); + + String[] resFieldNames = {"mCursorDrawableRes", "mTextSelectHandleLeftRes", "mTextSelectHandleRightRes", "mTextSelectHandleRes"}; + String[] drawableFieldNames = {"mCursorDrawable", "mSelectHandleLeft", "mSelectHandleRight", "mSelectHandleCenter"}; + + for (int i = 0; i < resFieldNames.length; i++) { + + String resFieldName = resFieldNames[i]; + String drawableFieldName = drawableFieldNames[i]; + + Field resField = TextView.class.getDeclaredField(resFieldName); + resField.setAccessible(true); + int drawableResId = resField.getInt(this); + + Drawable cursorDrawable = res.getDrawable(drawableResId).mutate(); + cursorDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN); + + Field drawableField = editor.getClass().getDeclaredField(drawableFieldName); + drawableField.setAccessible(true); + + if ( drawableFieldName.equals("mCursorDrawable")) { + Drawable[] drawables = {cursorDrawable, cursorDrawable}; + drawableField.set(editor, drawables); + } else { + drawableField.set(editor, cursorDrawable); + } + } + } catch (NoSuchFieldException | IllegalAccessException e) { + // Ignore errors to avoid crashing if these private fields don't exist on modified or future android versions. + } + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextFormatEnum.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextFormatEnum.java new file mode 100644 index 00000000000000..6d44852e64fc01 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextFormatEnum.java @@ -0,0 +1,42 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import org.wordpress.aztec.AztecTextFormat; + +import java.util.HashMap; +import java.util.Map; + +public enum ReactAztecTextFormatEnum { + + P("p", AztecTextFormat.FORMAT_PARAGRAPH), + H1("h1", AztecTextFormat.FORMAT_HEADING_1), + H2("h2", AztecTextFormat.FORMAT_HEADING_2), + H3("h3", AztecTextFormat.FORMAT_HEADING_3), + H4("h4", AztecTextFormat.FORMAT_HEADING_4), + H5("h5", AztecTextFormat.FORMAT_HEADING_5), + H6("h6", AztecTextFormat.FORMAT_HEADING_6), + PRE("pre", AztecTextFormat.FORMAT_PREFORMAT); + + private final String mTag; + private final AztecTextFormat mAztecTextFormat; + + private static final Map lookup = new HashMap<>(); + + static { + for (ReactAztecTextFormatEnum value : ReactAztecTextFormatEnum.values()) { + lookup.put(value.mTag, value); + } + } + + ReactAztecTextFormatEnum(String tag, AztecTextFormat aztecTextFormat) { + mTag = tag; + mAztecTextFormat = aztecTextFormat; + } + + public AztecTextFormat getAztecTextFormat() { + return mAztecTextFormat; + } + + static ReactAztecTextFormatEnum get(String tag) { + return lookup.get(tag); + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java new file mode 100644 index 00000000000000..c2e217363a2fad --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactAztecTextShadowNode.java @@ -0,0 +1,27 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import android.widget.EditText; + +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.annotations.ReactProp; + +public class ReactAztecTextShadowNode extends ReactTextInputShadowNodeFork { + + @Override + protected EditText createDummyEditText(ThemedReactContext themedContext) { + return new EditText(themedContext, null, 0); + } + + @ReactProp(name = PROP_TEXT) + public void setText(@Nullable ReadableMap inputMap) { + markUpdated(); + } + + @ReactProp(name = "color", customType = "Color") + public void setColor(@Nullable Integer color) { + markUpdated(); + } +} diff --git a/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java new file mode 100644 index 00000000000000..4ec32e6beded04 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/java/org/wordpress/mobile/ReactNativeAztec/ReactTextInputShadowNodeFork.java @@ -0,0 +1,240 @@ +package org.wordpress.mobile.ReactNativeAztec; + +import android.os.Build; +import android.text.Layout; +import android.util.TypedValue; +import android.view.ViewGroup; +import android.widget.EditText; + +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; +import androidx.core.view.ViewCompat; + +import com.facebook.infer.annotation.Assertions; +import com.facebook.react.bridge.JSApplicationIllegalArgumentException; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.uimanager.Spacing; +import com.facebook.react.uimanager.ThemedReactContext; +import com.facebook.react.uimanager.UIViewOperationQueue; +import com.facebook.react.uimanager.annotations.ReactProp; +import com.facebook.react.views.text.ReactBaseTextShadowNode; +import com.facebook.react.views.text.ReactTextUpdate; +import com.facebook.react.views.textinput.ReactTextInputLocalData; +import com.facebook.react.views.view.MeasureUtil; +import com.facebook.yoga.YogaMeasureFunction; +import com.facebook.yoga.YogaMeasureMode; +import com.facebook.yoga.YogaMeasureOutput; +import com.facebook.yoga.YogaNode; + +/** + * This is a fork from {@link com.facebook.react.views.textinput.ReactTextInputShadowNode} for the purpose + * of customizing that class so that the construction of the dummy {@link EditText} instance + * can be overridden (see {@link ReactTextInputShadowNodeFork#createDummyEditText(ThemedReactContext)}). + */ +public class ReactTextInputShadowNodeFork extends ReactBaseTextShadowNode + implements YogaMeasureFunction { + + private int mMostRecentEventCount = UNSET; + private @Nullable EditText mDummyEditText; + private @Nullable ReactTextInputLocalData mLocalData; + + @VisibleForTesting public static final String PROP_TEXT = "text"; + @VisibleForTesting public static final String PROP_PLACEHOLDER = "placeholder"; + @VisibleForTesting public static final String PROP_SELECTION = "selection"; + + // Represents the {@code text} property only, not possible nested content. + private @Nullable String mText = null; + private @Nullable String mPlaceholder = null; + private int mSelectionStart = UNSET; + private int mSelectionEnd = UNSET; + + public ReactTextInputShadowNodeFork() { + mTextBreakStrategy = (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) ? + Layout.BREAK_STRATEGY_SIMPLE : Layout.BREAK_STRATEGY_HIGH_QUALITY; + + initMeasureFunction(); + } + + private void initMeasureFunction() { + setMeasureFunction(this); + } + + @Override + public void setThemedContext(ThemedReactContext themedContext) { + super.setThemedContext(themedContext); + + // {@code EditText} has by default a border at the bottom of its view + // called "underline". To have a native look and feel of the TextEdit + // we have to preserve it at least by default. + // The border (underline) has its padding set by the background image + // provided by the system (which vary a lot among versions and vendors + // of Android), and it cannot be changed. + // So, we have to enforce it as a default padding. + // TODO #7120264: Cache this stuff better. + EditText editText = createDummyEditText(getThemedContext()); + setDefaultPadding(Spacing.START, ViewCompat.getPaddingStart(editText)); + setDefaultPadding(Spacing.TOP, editText.getPaddingTop()); + setDefaultPadding(Spacing.END, ViewCompat.getPaddingEnd(editText)); + setDefaultPadding(Spacing.BOTTOM, editText.getPaddingBottom()); + + mDummyEditText = editText; + + // We must measure the EditText without paddings, so we have to reset them. + mDummyEditText.setPadding(0, 0, 0, 0); + + // This is needed to fix an android bug since 4.4.3 which will throw an NPE in measure, + // setting the layoutParams fixes it: https://code.google.com/p/android/issues/detail?id=75877 + mDummyEditText.setLayoutParams( + new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + } + + protected EditText createDummyEditText(ThemedReactContext themedContext) { + return new EditText(themedContext); + } + + @Override + public long measure( + YogaNode node, + float width, + YogaMeasureMode widthMode, + float height, + YogaMeasureMode heightMode) { + // measure() should never be called before setThemedContext() + EditText editText = Assertions.assertNotNull(mDummyEditText); + + if (mLocalData != null) { + mLocalData.apply(editText); + } else { + editText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextAttributes.getEffectiveFontSize()); + + if (mNumberOfLines != UNSET) { + editText.setLines(mNumberOfLines); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && + editText.getBreakStrategy() != mTextBreakStrategy) { + editText.setBreakStrategy(mTextBreakStrategy); + } + } + + // make sure the placeholder content is also being measured + editText.setHint(getPlaceholder()); + editText.measure( + MeasureUtil.getMeasureSpec(width, widthMode), + MeasureUtil.getMeasureSpec(height, heightMode)); + + return YogaMeasureOutput.make(editText.getMeasuredWidth(), editText.getMeasuredHeight()); + } + + @Override + public boolean isVirtualAnchor() { + return true; + } + + @Override + public boolean isYogaLeafNode() { + return true; + } + + @Override + public void setLocalData(Object data) { + Assertions.assertCondition(data instanceof ReactTextInputLocalData); + mLocalData = (ReactTextInputLocalData) data; + + // Telling to Yoga that the node should be remeasured on next layout pass. + dirty(); + + // Note: We should NOT mark the node updated (by calling {@code markUpdated}) here + // because the state remains the same. + } + + @ReactProp(name = "mostRecentEventCount") + public void setMostRecentEventCount(int mostRecentEventCount) { + mMostRecentEventCount = mostRecentEventCount; + } + + @ReactProp(name = PROP_TEXT) + public void setText(@Nullable String text) { + mText = text; + markUpdated(); + } + + public @Nullable String getText() { + return mText; + } + + @ReactProp(name = PROP_PLACEHOLDER) + public void setPlaceholder(@Nullable String placeholder) { + mPlaceholder = placeholder; + markUpdated(); + } + + public @Nullable String getPlaceholder() { + return mPlaceholder; + } + + @ReactProp(name = PROP_SELECTION) + public void setSelection(@Nullable ReadableMap selection) { + mSelectionStart = mSelectionEnd = UNSET; + if (selection == null) + return; + + if (selection.hasKey("start") && selection.hasKey("end")) { + mSelectionStart = selection.getInt("start"); + mSelectionEnd = selection.getInt("end"); + markUpdated(); + } + } + + @Override + public void setTextBreakStrategy(@Nullable String textBreakStrategy) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + return; + } + + if (textBreakStrategy == null || "simple".equals(textBreakStrategy)) { + mTextBreakStrategy = Layout.BREAK_STRATEGY_SIMPLE; + } else if ("highQuality".equals(textBreakStrategy)) { + mTextBreakStrategy = Layout.BREAK_STRATEGY_HIGH_QUALITY; + } else if ("balanced".equals(textBreakStrategy)) { + mTextBreakStrategy = Layout.BREAK_STRATEGY_BALANCED; + } else { + throw new JSApplicationIllegalArgumentException("Invalid textBreakStrategy: " + textBreakStrategy); + } + } + + @Override + public void onCollectExtraUpdates(UIViewOperationQueue uiViewOperationQueue) { + super.onCollectExtraUpdates(uiViewOperationQueue); + + if (mMostRecentEventCount != UNSET) { + ReactTextUpdate reactTextUpdate = + new ReactTextUpdate( + spannedFromShadowNode( + this, + getText(), + /* supportsInlineViews: */ false, + /* nativeViewHierarchyOptimizer: */ null // only needed to support inline views + ), + mMostRecentEventCount, + mContainsImages, + getPadding(Spacing.LEFT), + getPadding(Spacing.TOP), + getPadding(Spacing.RIGHT), + getPadding(Spacing.BOTTOM), + mTextAlign, + mTextBreakStrategy, + mJustificationMode, + mSelectionStart, + mSelectionEnd); + uiViewOperationQueue.enqueueUpdateExtraData(getReactTag(), reactTextUpdate); + } + } + + @Override + public void setPadding(int spacingType, float padding) { + super.setPadding(spacingType, padding); + markUpdated(); + } +} diff --git a/packages/react-native-aztec/android/src/main/kotlin/org/wordpress/mobile/ReactNativeAztec/EnterPressedWatcher.kt b/packages/react-native-aztec/android/src/main/kotlin/org/wordpress/mobile/ReactNativeAztec/EnterPressedWatcher.kt new file mode 100644 index 00000000000000..cc68aac2e17fd4 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/kotlin/org/wordpress/mobile/ReactNativeAztec/EnterPressedWatcher.kt @@ -0,0 +1,76 @@ +package org.wordpress.mobile.ReactNativeAztec + +import android.text.Editable +import android.text.SpannableStringBuilder +import android.text.Spanned +import android.text.TextWatcher +import org.wordpress.aztec.AztecText +import org.wordpress.aztec.Constants +import java.lang.ref.WeakReference + +// Class to be used as a span to temporarily denote that Enter was detected +class EnterPressedUnderway + +interface EnterDeleter { + fun shouldDeleteEnter(): Boolean +} + +class EnterPressedWatcher(aztecText: AztecText, var enterDeleter: EnterDeleter) : TextWatcher { + + private val aztecTextRef: WeakReference = WeakReference(aztecText) + private lateinit var textBefore: SpannableStringBuilder + private var start: Int = -1 + private var selStart: Int = 0 + private var selEnd: Int = 0 + var done = false + + override fun beforeTextChanged(text: CharSequence, start: Int, count: Int, after: Int) { + val aztecText = aztecTextRef.get() + if (aztecText?.getAztecKeyListener() != null && !aztecText.isTextChangedListenerDisabled()) { + // we need to make a copy to preserve the contents as they were before the change + textBefore = SpannableStringBuilder(text) + this.start = start + this.selStart = aztecText.selectionStart + this.selEnd = aztecText.selectionEnd + } + } + + override fun onTextChanged(text: CharSequence, start: Int, before: Int, count: Int) { + val aztecText = aztecTextRef.get() + val aztecKeyListener = aztecText?.getAztecKeyListener() + if (aztecText != null && !aztecText.isTextChangedListenerDisabled() && aztecKeyListener != null) { + val newTextCopy = SpannableStringBuilder(text) + // if new text length is longer than original text by 1 + if (textBefore?.length == newTextCopy.length - 1) { + // now check that the inserted character is actually a NEWLINE + if (newTextCopy[this.start] == Constants.NEWLINE) { + done = false + aztecText.editableText.setSpan(EnterPressedUnderway(), 0, 0, Spanned.SPAN_USER) + aztecKeyListener.onEnterKey( + newTextCopy.replace(this.start, this.start + 1, ""), + true, + selStart, + selEnd + ) + } + } + } + } + + override fun afterTextChanged(text: Editable) { + aztecTextRef.get()?.editableText?.getSpans(0, 0, EnterPressedUnderway::class.java)?.forEach { + if (!done) { + done = true + if (enterDeleter.shouldDeleteEnter()) + text.replace(start, start + 1, "") + } + aztecTextRef.get()?.editableText?.removeSpan(it) + } + } + + companion object { + fun isEnterPressedUnderway(spanned: Spanned?): Boolean { + return spanned?.getSpans(0, 0, EnterPressedUnderway::class.java)?.isNotEmpty() ?: false + } + } +} diff --git a/packages/react-native-aztec/android/src/main/res/drawable-hdpi/ic_launcher.png b/packages/react-native-aztec/android/src/main/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 00000000000000..bcb72b12f55111 Binary files /dev/null and b/packages/react-native-aztec/android/src/main/res/drawable-hdpi/ic_launcher.png differ diff --git a/packages/react-native-aztec/android/src/main/res/drawable-mdpi/ic_launcher.png b/packages/react-native-aztec/android/src/main/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 00000000000000..37e5bce60f0951 Binary files /dev/null and b/packages/react-native-aztec/android/src/main/res/drawable-mdpi/ic_launcher.png differ diff --git a/packages/react-native-aztec/android/src/main/res/drawable-xhdpi/ic_launcher.png b/packages/react-native-aztec/android/src/main/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 00000000000000..1c4a85a0204f3e Binary files /dev/null and b/packages/react-native-aztec/android/src/main/res/drawable-xhdpi/ic_launcher.png differ diff --git a/packages/react-native-aztec/android/src/main/res/drawable-xxhdpi/ic_launcher.png b/packages/react-native-aztec/android/src/main/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 00000000000000..b26545c36b837e Binary files /dev/null and b/packages/react-native-aztec/android/src/main/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/packages/react-native-aztec/android/src/main/res/values/bools.xml b/packages/react-native-aztec/android/src/main/res/values/bools.xml new file mode 100644 index 00000000000000..2df1159d1838ab --- /dev/null +++ b/packages/react-native-aztec/android/src/main/res/values/bools.xml @@ -0,0 +1,7 @@ + + + + + false + + diff --git a/packages/react-native-aztec/android/src/main/res/values/integers.xml b/packages/react-native-aztec/android/src/main/res/values/integers.xml new file mode 100644 index 00000000000000..59c2c0c389fbb8 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/res/values/integers.xml @@ -0,0 +1,7 @@ + + + + + 0 + + diff --git a/packages/react-native-aztec/android/src/main/res/values/strings.xml b/packages/react-native-aztec/android/src/main/res/values/strings.xml new file mode 100644 index 00000000000000..5b3c79dd838556 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/res/values/strings.xml @@ -0,0 +1,20 @@ + + + + + Aztec React Native example + \ No newline at end of file diff --git a/packages/react-native-aztec/android/src/main/res/values/template-dimens.xml b/packages/react-native-aztec/android/src/main/res/values/template-dimens.xml new file mode 100644 index 00000000000000..b6d7bbbf6f5de7 --- /dev/null +++ b/packages/react-native-aztec/android/src/main/res/values/template-dimens.xml @@ -0,0 +1,26 @@ + + + + + + + 8dp + 16dp + 32dp + + 0dp + diff --git a/packages/react-native-aztec/index.js b/packages/react-native-aztec/index.js new file mode 100644 index 00000000000000..7b1734d819013b --- /dev/null +++ b/packages/react-native-aztec/index.js @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import RCTAztecView from './src/AztecView'; + +export default RCTAztecView; diff --git a/packages/react-native-aztec/ios/Cartfile b/packages/react-native-aztec/ios/Cartfile new file mode 100644 index 00000000000000..73ff95b59ac754 --- /dev/null +++ b/packages/react-native-aztec/ios/Cartfile @@ -0,0 +1 @@ +github "wordpress-mobile/AztecEditor-iOS" "1.15.0" diff --git a/packages/react-native-aztec/ios/Cartfile.resolved b/packages/react-native-aztec/ios/Cartfile.resolved new file mode 100644 index 00000000000000..73ff95b59ac754 --- /dev/null +++ b/packages/react-native-aztec/ios/Cartfile.resolved @@ -0,0 +1 @@ +github "wordpress-mobile/AztecEditor-iOS" "1.15.0" diff --git a/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.pbxproj b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.pbxproj new file mode 100644 index 00000000000000..78b15d29bf13e5 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.pbxproj @@ -0,0 +1,428 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 7ECFA93C21C39B5000FC131B /* HeadingBlockFormatHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECFA93B21C39B5000FC131B /* HeadingBlockFormatHandler.swift */; }; + 7ECFA94021C39BA000FC131B /* BlockFormatHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECFA93F21C39BA000FC131B /* BlockFormatHandler.swift */; }; + 7ECFA94221C39BBB00FC131B /* BlockModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ECFA94121C39BBB00FC131B /* BlockModel.swift */; }; + F121467D20ED2F81003DD17B /* RCTAztecViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F121467C20ED2F81003DD17B /* RCTAztecViewManager.m */; }; + F13BF4A020ECF5450047D3F9 /* RCTAztecViewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F13BF49F20ECF5450047D3F9 /* RCTAztecViewManager.swift */; }; + F1A879D020EE90C000FABD31 /* RCTAztecView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A879CF20EE90C000FABD31 /* RCTAztecView.swift */; }; + FF0DC1C523CDD21D0060074D /* Aztec.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F166A37B20EE6DD7008E7C9F /* Aztec.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F166A37A20EE6DD7008E7C9F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 5951CB8E1D8BC93600E1866F; + remoteInfo = Aztec; + }; + F166A37C20EE6DD7008E7C9F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 5951CB971D8BC93600E1866F; + remoteInfo = AztecTests; + }; + F166A37E20EE6DEE008E7C9F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 5951CB8D1D8BC93600E1866F; + remoteInfo = Aztec; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + F145CFC42087D16A006C159A /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 7ECFA93B21C39B5000FC131B /* HeadingBlockFormatHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadingBlockFormatHandler.swift; sourceTree = ""; }; + 7ECFA93F21C39BA000FC131B /* BlockFormatHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockFormatHandler.swift; sourceTree = ""; }; + 7ECFA94121C39BBB00FC131B /* BlockModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockModel.swift; sourceTree = ""; }; + F1017BCE20ED1B1A002B1024 /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; + F121467C20ED2F81003DD17B /* RCTAztecViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RCTAztecViewManager.m; sourceTree = ""; }; + F13BF49E20ECF5440047D3F9 /* RCTAztecView-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RCTAztecView-Bridging-Header.h"; sourceTree = ""; }; + F13BF49F20ECF5450047D3F9 /* RCTAztecViewManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCTAztecViewManager.swift; sourceTree = ""; }; + F145CFC62087D16A006C159A /* libRNTAztecView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNTAztecView.a; sourceTree = BUILT_PRODUCTS_DIR; }; + F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Aztec.xcodeproj; path = "Carthage/Checkouts/AztecEditor-iOS/Aztec.xcodeproj"; sourceTree = SOURCE_ROOT; }; + F1A879CF20EE90C000FABD31 /* RCTAztecView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RCTAztecView.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F145CFC32087D16A006C159A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FF0DC1C523CDD21D0060074D /* Aztec.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + F145CFBD2087D169006C159A = { + isa = PBXGroup; + children = ( + F145CFC82087D16A006C159A /* RNTAztecView */, + F166A37320EE6DC7008E7C9F /* Dependencies */, + F145CFF92087D497006C159A /* Frameworks */, + F145CFC72087D16A006C159A /* Products */, + ); + sourceTree = ""; + }; + F145CFC72087D16A006C159A /* Products */ = { + isa = PBXGroup; + children = ( + F145CFC62087D16A006C159A /* libRNTAztecView.a */, + ); + name = Products; + sourceTree = ""; + }; + F145CFC82087D16A006C159A /* RNTAztecView */ = { + isa = PBXGroup; + children = ( + F13BF49E20ECF5440047D3F9 /* RCTAztecView-Bridging-Header.h */, + F121467C20ED2F81003DD17B /* RCTAztecViewManager.m */, + F13BF49F20ECF5450047D3F9 /* RCTAztecViewManager.swift */, + F1A879CF20EE90C000FABD31 /* RCTAztecView.swift */, + 7ECFA94121C39BBB00FC131B /* BlockModel.swift */, + 7ECFA93B21C39B5000FC131B /* HeadingBlockFormatHandler.swift */, + 7ECFA93F21C39BA000FC131B /* BlockFormatHandler.swift */, + ); + path = RNTAztecView; + sourceTree = ""; + }; + F145CFF92087D497006C159A /* Frameworks */ = { + isa = PBXGroup; + children = ( + F1017BCE20ED1B1A002B1024 /* libReact.a */, + ); + path = Frameworks; + sourceTree = ""; + }; + F166A37320EE6DC7008E7C9F /* Dependencies */ = { + isa = PBXGroup; + children = ( + F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */, + ); + path = Dependencies; + sourceTree = ""; + }; + F166A37520EE6DD7008E7C9F /* Products */ = { + isa = PBXGroup; + children = ( + F166A37B20EE6DD7008E7C9F /* Aztec.framework */, + F166A37D20EE6DD7008E7C9F /* AztecTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F145CFC52087D16A006C159A /* RNTAztecView */ = { + isa = PBXNativeTarget; + buildConfigurationList = F145CFCD2087D16A006C159A /* Build configuration list for PBXNativeTarget "RNTAztecView" */; + buildPhases = ( + F145CFC22087D16A006C159A /* Sources */, + F145CFC32087D16A006C159A /* Frameworks */, + F145CFC42087D16A006C159A /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + F166A37F20EE6DEE008E7C9F /* PBXTargetDependency */, + ); + name = RNTAztecView; + productName = RNTAztecView; + productReference = F145CFC62087D16A006C159A /* libRNTAztecView.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F145CFBE2087D169006C159A /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = "Automattic Inc."; + TargetAttributes = { + F145CFC52087D16A006C159A = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 1110; + }; + }; + }; + buildConfigurationList = F145CFC12087D169006C159A /* Build configuration list for PBXProject "RNTAztecView" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = F145CFBD2087D169006C159A; + productRefGroup = F145CFC72087D16A006C159A /* Products */; + projectDirPath = ""; + projectReferences = ( + { + ProductGroup = F166A37520EE6DD7008E7C9F /* Products */; + ProjectRef = F166A37420EE6DD7008E7C9F /* Aztec.xcodeproj */; + }, + ); + projectRoot = ""; + targets = ( + F145CFC52087D16A006C159A /* RNTAztecView */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXReferenceProxy section */ + F166A37B20EE6DD7008E7C9F /* Aztec.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = Aztec.framework; + remoteRef = F166A37A20EE6DD7008E7C9F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + F166A37D20EE6DD7008E7C9F /* AztecTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = AztecTests.xctest; + remoteRef = F166A37C20EE6DD7008E7C9F /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + +/* Begin PBXSourcesBuildPhase section */ + F145CFC22087D16A006C159A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7ECFA94021C39BA000FC131B /* BlockFormatHandler.swift in Sources */, + 7ECFA93C21C39B5000FC131B /* HeadingBlockFormatHandler.swift in Sources */, + F13BF4A020ECF5450047D3F9 /* RCTAztecViewManager.swift in Sources */, + F1A879D020EE90C000FABD31 /* RCTAztecView.swift in Sources */, + F121467D20ED2F81003DD17B /* RCTAztecViewManager.m in Sources */, + 7ECFA94221C39BBB00FC131B /* BlockModel.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F166A37F20EE6DEE008E7C9F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = Aztec; + targetProxy = F166A37E20EE6DEE008E7C9F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + F145CFCB2087D16A006C159A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + F145CFCC2087D16A006C159A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F145CFCE2087D16A006C159A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = PZYM8XX95Q; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + HEADER_SEARCH_PATHS = /usr/include/libxml2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = "RNTAztecView/RCTAztecView-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F145CFCF2087D16A006C159A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = PZYM8XX95Q; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); + HEADER_SEARCH_PATHS = /usr/include/libxml2; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = "RNTAztecView/RCTAztecView-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F145CFC12087D169006C159A /* Build configuration list for PBXProject "RNTAztecView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F145CFCB2087D16A006C159A /* Debug */, + F145CFCC2087D16A006C159A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F145CFCD2087D16A006C159A /* Build configuration list for PBXNativeTarget "RNTAztecView" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F145CFCE2087D16A006C159A /* Debug */, + F145CFCF2087D16A006C159A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = F145CFBE2087D169006C159A /* Project object */; +} diff --git a/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000000..6beac76536bac3 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000000..18d981003d68d0 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/react-native-aztec/ios/RNTAztecView/BlockFormatHandler.swift b/packages/react-native-aztec/ios/RNTAztecView/BlockFormatHandler.swift new file mode 100644 index 00000000000000..4a096e28405703 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/BlockFormatHandler.swift @@ -0,0 +1,15 @@ + +/// Classes conforming this protocol are meant to do formatting work over an specific block. +/// It is useful when we need to force an specific typing format that Aztec is not showing by default. +/// +protocol BlockFormatHandler { + + /// Create an instance of a block formatter handler for the given block. + /// If the given block is not compatible, the init will fail. + /// + init?(block: BlockModel) + + /// Set the typing format to an specific one. + /// + func forceTypingFormat(on textView: RCTAztecView) +} diff --git a/packages/react-native-aztec/ios/RNTAztecView/BlockModel.swift b/packages/react-native-aztec/ios/RNTAztecView/BlockModel.swift new file mode 100644 index 00000000000000..7a8c410149a8d5 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/BlockModel.swift @@ -0,0 +1,3 @@ +struct BlockModel { + let tag: String +} diff --git a/packages/react-native-aztec/ios/RNTAztecView/HeadingBlockFormatHandler.swift b/packages/react-native-aztec/ios/RNTAztecView/HeadingBlockFormatHandler.swift new file mode 100644 index 00000000000000..44223934b11b0d --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/HeadingBlockFormatHandler.swift @@ -0,0 +1,40 @@ +import Aztec + +struct HeadingBlockFormatHandler: BlockFormatHandler { + private let level: Header.HeaderType + private let paragraphFormatter = HTMLParagraphFormatter(placeholderAttributes: nil) + private let headerFormatter: HeaderFormatter + + init?(block: BlockModel) { + guard let level = HeadingBlockFormatHandler.headerLevel(from: block.tag) else { + return nil + } + self.level = level + headerFormatter = HeaderFormatter(headerLevel: level) + } + + func forceTypingFormat(on textView: RCTAztecView) { + var attributes = textView.typingAttributes + + attributes = paragraphFormatter.remove(from: textView.typingAttributes) + attributes = headerFormatter.apply(to: textView.typingAttributes, andStore: nil) + + textView.typingAttributes = attributes + if let font = attributes[.font] as? UIFont { + textView.placeholderLabel.font = font + } + } + + private static func headerLevel(from levelString: String) -> Header.HeaderType? { + switch levelString { + case "h2": + return .h2 + case "h3": + return .h3 + case "h4": + return .h4 + default: + return nil + } + } +} diff --git a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView-Bridging-Header.h b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView-Bridging-Header.h new file mode 100644 index 00000000000000..38296e9f8a6f67 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView-Bridging-Header.h @@ -0,0 +1,7 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import +#import diff --git a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift new file mode 100644 index 00000000000000..31910f5ff8f980 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecView.swift @@ -0,0 +1,676 @@ +import Aztec +import CoreServices +import Foundation +import UIKit + +class RCTAztecView: Aztec.TextView { + @objc var onBackspace: RCTBubblingEventBlock? = nil + @objc var onChange: RCTBubblingEventBlock? = nil + @objc var onEnter: RCTBubblingEventBlock? = nil + @objc var onFocus: RCTBubblingEventBlock? = nil + @objc var onBlur: RCTBubblingEventBlock? = nil + @objc var onPaste: RCTBubblingEventBlock? = nil + @objc var onContentSizeChange: RCTBubblingEventBlock? = nil + @objc var onSelectionChange: RCTBubblingEventBlock? = nil + @objc var minWidth: CGFloat = 0 + @objc var maxWidth: CGFloat = 0 + + @objc var activeFormats: NSSet? = nil { + didSet { + let currentTypingAttributes = formattingIdentifiersForTypingAttributes() + for (key, value) in formatStringMap where currentTypingAttributes.contains(key) != activeFormats?.contains(value) { + toggleFormat(format: value) + } + } + } + @objc var disableEditingMenu: Bool = false { + didSet { + allowsEditingTextAttributes = !disableEditingMenu + } + } + + override var textAlignment: NSTextAlignment { + set { + super.textAlignment = newValue + defaultParagraphStyle.alignment = newValue + placeholderLabel.textAlignment = newValue + } + + get { + return super.textAlignment + } + } + + private var previousContentSize: CGSize = .zero + + var leftTextInset: CGFloat { + return contentInset.left + textContainerInset.left + textContainer.lineFragmentPadding + } + + var leftTextInsetInRTLLayout: CGFloat { + return bounds.width - leftTextInset + } + + var hasRTLLayout: Bool { + return reactLayoutDirection == .rightToLeft + } + + private(set) lazy var placeholderLabel: UILabel = { + let label = UILabel(frame: .zero) + label.translatesAutoresizingMaskIntoConstraints = false + label.textAlignment = .natural + label.font = font + + return label + }() + + // RCTScrollViews are flipped horizontally on RTL. This messes up competelly horizontal layout contraints + // on views inserted after the transformation. + var placeholderPreferedHorizontalAnchor: NSLayoutXAxisAnchor { + return hasRTLLayout ? placeholderLabel.rightAnchor : placeholderLabel.leftAnchor + } + + // This constraint is created from the prefered horizontal anchor (analog to "leading") + // but appending it always to left of its super view (Aztec). + // This partially fixes the position issue originated from fliping the scroll view. + // fixLabelPositionForRTLLayout() fixes the rest. + private lazy var placeholderHorizontalConstraint: NSLayoutConstraint = { + return placeholderPreferedHorizontalAnchor.constraint( + equalTo: leftAnchor, + constant: leftTextInset + ) + }() + + private lazy var placeholderWidthConstraint: NSLayoutConstraint = { + // width needs to be shrunk on both the left and the right by the textInset in order for + // the placeholder to be appropriately positioned with right alignment. + let placeholderWidthInset = 2 * leftTextInset + return placeholderLabel.widthAnchor.constraint(equalTo: widthAnchor, constant: -placeholderWidthInset) + }() + + /// If a dictation start with an empty UITextView, + /// the dictation engine refreshes the TextView with an empty string when the dictation finishes. + /// This helps to avoid propagating that unwanted empty string to RN. (Solving #606) + /// on `textViewDidChange` and `textViewDidChangeSelection` + private var isInsertingDictationResult = false + + // MARK: - Font + + /// Font family for all contents Once this is set, it will always override the font family for all of its + /// contents, regardless of what HTML is provided to Aztec. + private var fontFamily: String? = nil + + /// Font size for all contents. Once this is set, it will always override the font size for all of its + /// contents, regardless of what HTML is provided to Aztec. + private var fontSize: CGFloat? = nil + + /// Font weight for all contents. Once this is set, it will always override the font weight for all of its + /// contents, regardless of what HTML is provided to Aztec. + private var fontWeight: String? = nil + + // MARK: - Formats + + private let formatStringMap: [FormattingIdentifier: String] = [ + .bold: "bold", + .italic: "italic", + .strikethrough: "strikethrough", + .link: "link", + ] + + override init(defaultFont: UIFont, defaultParagraphStyle: ParagraphStyle, defaultMissingImage: UIImage) { + super.init(defaultFont: defaultFont, defaultParagraphStyle: defaultParagraphStyle, defaultMissingImage: defaultMissingImage) + commonInit() + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + commonInit() + } + + func commonInit() { + Configuration.headersWithBoldTrait = true + delegate = self + textContainerInset = .zero + contentInset = .zero + textContainer.lineFragmentPadding = 0 + addPlaceholder() + textDragInteraction?.isEnabled = false + storage.htmlConverter.characterToReplaceLastEmptyLine = Character(.zeroWidthSpace) + storage.htmlConverter.shouldCollapseSpaces = false + shouldNotifyOfNonUserChanges = false + disableLinkTapRecognizer() + preBackgroundColor = .clear + } + + func addPlaceholder() { + addSubview(placeholderLabel) + let topConstant = contentInset.top + textContainerInset.top + NSLayoutConstraint.activate([ + placeholderHorizontalConstraint, + placeholderWidthConstraint, + placeholderLabel.topAnchor.constraint(equalTo: topAnchor, constant: topConstant) + ]) + } + + /** + This handles a bug introduced by iOS 13.0 (tested up to 13.2) where link interactions don't respect what the documentation says. + + The documenatation for textView(_:shouldInteractWith:in:interaction:) says: + + > Links in text views are interactive only if the text view is selectable but noneditable. + + Our Aztec Text views are selectable and editable, and yet iOS was opening links on Safari when tapped. + */ + func disableLinkTapRecognizer() { + guard let recognizer = gestureRecognizers?.first(where: { $0.name == "UITextInteractionNameLinkTap" }) else { + return + } + recognizer.isEnabled = false + } + + // MARK: - View height and width: Match to the content + + override func layoutSubviews() { + super.layoutSubviews() + adjustWidth() + fixLabelPositionForRTLLayout() + updateContentSizeInRN() + } + + private func adjustWidth() { + if (maxWidth > 0 && minWidth > 0) { + let maxSize = CGSize(width: maxWidth, height: CGFloat.greatestFiniteMagnitude) + let newWidth = sizeThatFits(maxSize).width + if (newWidth != frame.size.width) { + frame.size.width = max(newWidth, minWidth) + } + } + } + + private func fixLabelPositionForRTLLayout() { + if hasRTLLayout { + // RCTScrollViews are flipped horizontally on RTL layout. + // This fixes the position of the label after "fixing" (partially) the constraints. + placeholderHorizontalConstraint.constant = leftTextInsetInRTLLayout + } + } + + func updateContentSizeInRN() { + let newSize = sizeThatFits(frame.size) + + guard previousContentSize != newSize, + let onContentSizeChange = onContentSizeChange else { + return + } + + previousContentSize = newSize + + let body = packForRN(newSize, withName: "contentSize") + onContentSizeChange(body) + } + + // MARK: - Paste handling + private func read(from pasteboard: UIPasteboard, uti: CFString, documentType: DocumentType) -> String? { + guard let data = pasteboard.data(forPasteboardType: uti as String), + let attributedString = try? NSAttributedString(data: data, options: [.documentType: documentType], documentAttributes: nil), + let storage = self.textStorage as? TextStorage else { + return nil + } + return storage.getHTML(from: attributedString) + } + + private func readHTML(from pasteboard: UIPasteboard) -> String? { + + if let data = pasteboard.data(forPasteboardType: kUTTypeHTML as String), let html = String(data: data, encoding: .utf8) { + // Make sure we are not getting a full HTML DOC. We only want inner content + if !html.hasPrefix(" String? { + var text = pasteboard.string + // Text that comes from Aztec will have paragraphSeparator instead of line feed AKA as \n. The paste methods in GB are expecting \n so this line will fix that. + text = text?.replacingOccurrences(of: String(.paragraphSeparator), with: String(.lineFeed)) + return text + } + + func saveToDisk(image: UIImage) -> URL? { + let fileName = "\(ProcessInfo.processInfo.globallyUniqueString)_file.jpg" + + guard let data = image.jpegData(compressionQuality: 0.9) else { + return nil + } + + let fileURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent(fileName) + + guard (try? data.write(to: fileURL, options: [.atomic])) != nil else { + return nil + } + + return fileURL + } + + private func readImages(from pasteboard: UIPasteboard) -> [String] { + guard let images = pasteboard.images else { + return [] + } + let imagesURLs = images.compactMap({ saveToDisk(image: $0)?.absoluteString }) + return imagesURLs + } + + override func paste(_ sender: Any?) { + let pasteboard = UIPasteboard.general + let text = readText(from: pasteboard) ?? "" + let html = readHTML(from: pasteboard) ?? "" + let imagesURLs = readImages(from: pasteboard) + sendPasteCallback(text: text, html: html, imagesURLs: imagesURLs); + } + + override func pasteWithoutFormatting(_ sender: Any?) { + let pasteboard = UIPasteboard.general + let text = readText(from: pasteboard) ?? "" + let imagesURLs = readImages(from: pasteboard) + sendPasteCallback(text: text, html: "", imagesURLs: imagesURLs); + } + + private func sendPasteCallback(text: String, html: String, imagesURLs: [String]) { + let start = selectedRange.location + let end = selectedRange.location + selectedRange.length + onPaste?([ + "currentContent": cleanHTML(), + "selectionStart": start, + "selectionEnd": end, + "pastedText": text, + "pastedHtml": html, + "files": imagesURLs] ) + } + + // MARK: - Edits + + open override func insertText(_ text: String) { + guard !interceptEnter(text) else { + return + } + + super.insertText(text) + updatePlaceholderVisibility() + } + + open override func deleteBackward() { + guard !interceptBackspace() else { + return + } + + super.deleteBackward() + updatePlaceholderVisibility() + } + + // MARK: - Dictation + + override func dictationRecordingDidEnd() { + isInsertingDictationResult = true + } + + public override func insertDictationResult(_ dictationResult: [UIDictationPhrase]) { + let objectPlaceholder = "\u{FFFC}" + let dictationText = dictationResult.reduce("") { $0 + $1.text } + isInsertingDictationResult = false + self.text = self.text?.replacingOccurrences(of: objectPlaceholder, with: dictationText) + } + + // MARK: - Custom Edit Intercepts + + private func interceptEnter(_ text: String) -> Bool { + if text == "\t" { + return true + } + + guard text == "\n", + let onEnter = onEnter else { + return false + } + + let caretData = packCaretDataForRN() + onEnter(caretData) + return true + } + + private func interceptBackspace() -> Bool { + guard (isNewLineBeforeSelectionAndNotEndOfContent() && selectedRange.length == 0) + || (selectedRange.location == 0 && selectedRange.length == 0) + || text.count == 1 // send backspace event when cleaning all characters + || selectedRange == NSRange(location: 0, length: textStorage.length), // send backspace event when deleting all the text + let onBackspace = onBackspace else { + return false + } + var range = selectedRange + if text.count == 1 { + range = NSRange(location: 0, length: textStorage.length) + } + let caretData = packCaretDataForRN(overrideRange: range) + onSelectionChange?(caretData) + onBackspace(caretData) + return true + } + + private func isNewLineBeforeSelectionAndNotEndOfContent() -> Bool { + guard let currentLocation = text.indexFromLocation(selectedRange.location) else { + return false + } + + return text.isStartOfParagraph(at: currentLocation) && !(text.endIndex == currentLocation) + } + override var keyCommands: [UIKeyCommand]? { + // Remove defautls Tab and Shift+Tab commands, leaving just Shift+Enter command. + return [carriageReturnKeyCommand] + } + + // MARK: - Native-to-RN Value Packing Logic + + private func cleanHTML() -> String { + let html = getHTML(prettify: false).replacingOccurrences(of: String(.paragraphSeparator), with: String(.lineFeed)).replacingOccurrences(of: String(.zeroWidthSpace), with: "") + return html + } + + func packForRN(_ text: String, withName name: String) -> [AnyHashable: Any] { + return [name: text, + "eventCount": 1] + } + + func packForRN(_ size: CGSize, withName name: String) -> [AnyHashable: Any] { + + let size = ["width": size.width, + "height": size.height] + + return [name: size] + } + + func packCaretDataForRN(overrideRange: NSRange? = nil) -> [AnyHashable: Any] { + var range = selectedRange + if let overrideRange = overrideRange { + range = overrideRange + } + var start = range.location + var end = range.location + range.length + if selectionAffinity == .backward { + (start, end) = (end, start) + } + + var result: [AnyHashable : Any] = packForRN(cleanHTML(), withName: "text") + + result["selectionStart"] = start + result["selectionEnd"] = end + + if let range = selectedTextRange { + let caretEndRect = caretRect(for: range.end) + // Sergio Estevao: Sometimes the carectRect can be invalid so we need to check before sending this to JS. + if !(caretEndRect.isInfinite || caretEndRect.isNull) { + result["selectionEndCaretX"] = caretEndRect.origin.x + result["selectionEndCaretY"] = caretEndRect.origin.y + } + } + + return result + } + + // MARK: - RN Properties + + @objc + func setContents(_ contents: NSDictionary) { + guard contents["eventCount"] == nil else { + return + } + + let html = contents["text"] as? String ?? "" + + setHTML(html) + updatePlaceholderVisibility() + refreshTypingAttributesAndPlaceholderFont() + if let selection = contents["selection"] as? NSDictionary, + let start = selection["start"] as? NSNumber, + let end = selection["end"] as? NSNumber { + setSelection(start: start, end: end) + } + // This signals the RN/JS system that the component needs to relayout + setNeedsLayout() + } + + override var textColor: UIColor? { + didSet { + typingAttributes[NSAttributedString.Key.foregroundColor] = self.textColor + self.defaultTextColor = self.textColor + } + } + + override var typingAttributes: [NSAttributedString.Key : Any] { + didSet { + // Keep placeholder attributes in sync with typing attributes. + placeholderLabel.attributedText = NSAttributedString(string: placeholderLabel.text ?? "", attributes: placeholderAttributes) + } + } + + // MARK: - Placeholder + + @objc var placeholder: String { + set { + placeholderLabel.attributedText = NSAttributedString(string: newValue, attributes: placeholderAttributes) + } + + get { + return placeholderLabel.text ?? "" + } + } + + /// Attributes to use on the placeholder. + var placeholderAttributes: [NSAttributedString.Key: Any] { + var placeholderAttributes = typingAttributes + placeholderAttributes[.foregroundColor] = placeholderTextColor + return placeholderAttributes + } + + @objc var placeholderTextColor: UIColor { + set { + placeholderLabel.textColor = newValue + } + get { + return placeholderLabel.textColor + } + } + + @objc var linkTextColor: UIColor { + set { + linkTextAttributes = [.foregroundColor: newValue, .underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)] + } + get { + return linkTextAttributes[.foregroundColor] as? UIColor ?? UIColor.blue + } + } + + func setSelection(start: NSNumber, end: NSNumber) { + if let startPosition = position(from: beginningOfDocument, offset: start.intValue), + let endPosition = position(from: beginningOfDocument, offset: end.intValue) { + selectedTextRange = textRange(from: startPosition, to: endPosition) + } + } + + func updatePlaceholderVisibility() { + placeholderLabel.isHidden = !self.text.replacingOccurrences(of: String(.zeroWidthSpace), with: "").isEmpty + } + + // MARK: - Font Setters + + @objc func setFontFamily(_ family: String) { + guard fontFamily != family else { + return + } + fontFamily = family + refreshFont() + } + + @objc func setFontSize(_ size: CGFloat) { + guard fontSize != size else { + return + } + fontSize = size + refreshFont() + } + + @objc func setFontWeight(_ weight: String) { + guard fontWeight != weight else { + return + } + fontWeight = weight + refreshFont() + } + + // MARK: - Font Refreshing + + /// Applies the family, size and weight constraints to the provided font. + /// + private func applyFontConstraints(to baseFont: UIFont) -> UIFont { + let oldDescriptor = baseFont.fontDescriptor + let newFontSize: CGFloat + + if let fontSize = fontSize { + newFontSize = fontSize + } else { + newFontSize = baseFont.pointSize + } + + var newTraits = oldDescriptor.symbolicTraits + + if let fontWeight = fontWeight { + if (fontWeight == "bold") { + newTraits.update(with: .traitBold) + } + } + + var newDescriptor: UIFontDescriptor + + if let fontFamily = fontFamily { + newDescriptor = UIFontDescriptor(name: fontFamily, size: newFontSize) + newDescriptor = newDescriptor.withSymbolicTraits(newTraits) ?? newDescriptor + } else { + newDescriptor = oldDescriptor + } + + return UIFont(descriptor: newDescriptor, size: newFontSize) + } + + /// Returns the font from the specified attributes, or the default font if no specific one is set. + /// + private func font(from attributes: [NSAttributedString.Key: Any]) -> UIFont { + return attributes[.font] as? UIFont ?? defaultFont + } + + /// This method refreshes the font for the whole view if the font-family, the font-size or the font-weight + /// were ever set. + /// + private func refreshFont() { + let newFont = applyFontConstraints(to: defaultFont) + defaultFont = newFont + } + + /// This method refreshes the font for the palceholder field and typing attributes. + /// This method should not be called directly. Call `refreshFont()` instead. + /// + private func refreshTypingAttributesAndPlaceholderFont() { + let currentFont = font(from: typingAttributes) + placeholderLabel.font = currentFont + } + + // MARK: - Formatting interface + + @objc func toggleFormat(format: String) { + let emptyRange = NSRange(location: selectedRange.location, length: 0) + switch format { + case "bold": toggleBold(range: emptyRange) + case "italic": toggleItalic(range: emptyRange) + case "strikethrough": toggleStrikethrough(range: emptyRange) + default: print("Format not recognized") + } + } + + // MARK: - Event Propagation + + func propagateContentChanges() { + if let onChange = onChange { + let text = packForRN(cleanHTML(), withName: "text") + onChange(text) + } + } + + func propagateSelectionChanges() { + guard let onSelectionChange = onSelectionChange else { + return + } + let caretData = packCaretDataForRN() + onSelectionChange(caretData) + } + + // MARK: - Selection + private func correctSelectionAfterLastEmptyLine() { + guard selectedTextRange?.start == endOfDocument, + let characterToReplaceLastEmptyLine = storage.htmlConverter.characterToReplaceLastEmptyLine, + text == String(characterToReplaceLastEmptyLine) else { + return + } + selectedTextRange = self.textRange(from: beginningOfDocument, to: beginningOfDocument) + } +} + +// MARK: UITextView Delegate Methods +extension RCTAztecView: UITextViewDelegate { + + func textViewDidChangeSelection(_ textView: UITextView) { + guard isFirstResponder, isInsertingDictationResult == false else { + return + } + + correctSelectionAfterLastEmptyLine() + propagateSelectionChanges() + } + + func textViewDidBeginEditing(_ textView: UITextView) { + correctSelectionAfterLastEmptyLine() + } + + func textViewDidChange(_ textView: UITextView) { + guard isInsertingDictationResult == false else { + return + } + + propagateContentChanges() + updatePlaceholderVisibility() + //Necessary to send height information to JS after pasting text. + textView.setNeedsLayout() + } + + override func becomeFirstResponder() -> Bool { + if !isFirstResponder && canBecomeFirstResponder { + onFocus?([:]) + } + return super.becomeFirstResponder() + } + + func textViewDidEndEditing(_ textView: UITextView) { + let text = packForRN(cleanHTML(), withName: "text") + onBlur?(text) + } +} diff --git a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.m b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.m new file mode 100644 index 00000000000000..1f9d4a6a8da1ea --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.m @@ -0,0 +1,35 @@ +#import + +@interface RCT_EXTERN_MODULE(RCTAztecViewManager, NSObject) + +RCT_REMAP_VIEW_PROPERTY(text, contents, NSDictionary) +RCT_EXPORT_VIEW_PROPERTY(onContentSizeChange, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onBackspace, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onChange, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onEnter, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onFocus, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onBlur, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onPaste, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onSelectionChange, RCTDirectEventBlock) +RCT_EXPORT_VIEW_PROPERTY(activeFormats, NSSet) + +RCT_EXPORT_VIEW_PROPERTY(onActiveFormatsChange, RCTBubblingEventBlock) +RCT_EXPORT_VIEW_PROPERTY(onActiveFormatAttributesChange, RCTBubblingEventBlock) + +RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString) +RCT_EXPORT_VIEW_PROPERTY(placeholderTextColor, UIColor) +RCT_REMAP_VIEW_PROPERTY(color, textColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(linkTextColor, UIColor) +RCT_EXPORT_VIEW_PROPERTY(minWidth, CGFloat) +RCT_EXPORT_VIEW_PROPERTY(maxWidth, CGFloat) + +RCT_EXPORT_VIEW_PROPERTY(fontFamily, NSString) +RCT_EXPORT_VIEW_PROPERTY(fontSize, CGFloat) +RCT_EXPORT_VIEW_PROPERTY(fontWeight, NSString) + +RCT_EXPORT_VIEW_PROPERTY(disableEditingMenu, BOOL) +RCT_REMAP_VIEW_PROPERTY(textAlign, textAlignment, NSTextAlignment) +RCT_REMAP_VIEW_PROPERTY(selectionColor, tintColor, UIColor) + + +@end diff --git a/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.swift b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.swift new file mode 100644 index 00000000000000..eacc94225b2661 --- /dev/null +++ b/packages/react-native-aztec/ios/RNTAztecView/RCTAztecViewManager.swift @@ -0,0 +1,69 @@ +import Aztec +import Foundation + +@objc (RCTAztecViewManager) +public class RCTAztecViewManager: RCTViewManager { + + public var attachmentDelegate: Aztec.TextViewAttachmentDelegate? + public var imageProvider: Aztec.TextViewAttachmentImageProvider? + public lazy var unsupportedHTMLImageProvider = { + Aztec.HTMLAttachmentRenderer(font: defaultFont) + }() + + public override static func requiresMainQueueSetup() -> Bool { + return true + } + + @objc + public override func view() -> UIView { + let view = RCTAztecView( + defaultFont: defaultFont, + defaultParagraphStyle: defaultParagrahStyle, + defaultMissingImage: UIImage()) + + view.isScrollEnabled = false + + view.textAttachmentDelegate = attachmentDelegate + + if let imageProvider = imageProvider { + view.registerAttachmentImageProvider(imageProvider) + } + + view.registerAttachmentImageProvider(unsupportedHTMLImageProvider) + + return view + } + + func executeBlock(_ block: @escaping (RCTAztecView) -> Void, onNode node: NSNumber) { + self.bridge.uiManager.addUIBlock { (manager, viewRegistry) in + let view = viewRegistry?[node] + guard let aztecView = view as? RCTAztecView else { + return + } + block(aztecView) + } + } + + private var defaultFont: UIFont { + if let font = UIFont(name: "NotoSerif", size: 16) { + return font + } + + let defaultFont = UIFont.systemFont(ofSize: 16) + guard let url = Bundle.main.url(forResource: "NotoSerif-Regular", withExtension: "ttf") else { + return defaultFont + } + CTFontManagerRegisterFontsForURL(url as CFURL, CTFontManagerScope.process, nil) + if let font = UIFont(name: "NotoSerif", size: 16) { + return font + } + + return defaultFont + } + private var defaultParagrahStyle: ParagraphStyle { + let defaultStyle = ParagraphStyle.default + defaultStyle.textListParagraphSpacing = 5 + defaultStyle.textListParagraphSpacingBefore = 5 + return defaultStyle + } +} diff --git a/packages/react-native-aztec/package.json b/packages/react-native-aztec/package.json new file mode 100644 index 00000000000000..09708071575ef9 --- /dev/null +++ b/packages/react-native-aztec/package.json @@ -0,0 +1,39 @@ +{ + "name": "@wordpress/react-native-aztec", + "version": "0.1.11", + "description": "Aztec view for react-native.", + "private": true, + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "react-native" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/react-native-aztec/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/react-native-aztec" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "install-aztec-ios": "cd ./ios && carthage bootstrap --platform iOS --cache-builds", + "update-aztec-ios": "cd ./ios && carthage update --platform iOS --cache-builds", + "clean": "npm run clean-watchman; npm run clean-node; npm run clean-react; npm run clean-metro; npm run clean-jest;", + "clean-jest": "rm -rf $TMPDIR/jest_*;", + "clean-metro": "rm -rf $TMPDIR/metro-cache-*; rm -rf $TMPDIR/metro-bundler-cache-*;", + "clean-node": "rm -rf node_modules/;", + "clean-react": "rm -rf $TMPDIR/react-*; rm -rf $TMPDIR/react-native-packager-cache-*;", + "clean-watchman": "command -v watchman >/dev/null 2>&1 && watchman watch-del-all;", + "clean:install": "npm run clean && npm install" + } +} diff --git a/packages/react-native-aztec/src/AztecView.js b/packages/react-native-aztec/src/AztecView.js new file mode 100644 index 00000000000000..1fec71d04c7a5e --- /dev/null +++ b/packages/react-native-aztec/src/AztecView.js @@ -0,0 +1,189 @@ +/** + * External dependencies + */ +import React from 'react'; +import ReactNative, { + requireNativeComponent, + UIManager, + TouchableWithoutFeedback, + Platform, +} from 'react-native'; +import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState'; + +const AztecManager = UIManager.getViewManagerConfig( 'RCTAztecView' ); + +class AztecView extends React.Component { + constructor() { + super( ...arguments ); + this._onContentSizeChange = this._onContentSizeChange.bind( this ); + this._onEnter = this._onEnter.bind( this ); + this._onBackspace = this._onBackspace.bind( this ); + this._onHTMLContentWithCursor = this._onHTMLContentWithCursor.bind( + this + ); + this._onFocus = this._onFocus.bind( this ); + this._onBlur = this._onBlur.bind( this ); + this._onSelectionChange = this._onSelectionChange.bind( this ); + this._onPress = this._onPress.bind( this ); + this._onAztecFocus = this._onAztecFocus.bind( this ); + this.blur = this.blur.bind( this ); + this.focus = this.focus.bind( this ); + } + + dispatch( command, params ) { + params = params || []; + UIManager.dispatchViewManagerCommand( + ReactNative.findNodeHandle( this ), + command, + params + ); + } + + requestHTMLWithCursor() { + this.dispatch( AztecManager.Commands.returnHTMLWithCursor ); + } + + _onContentSizeChange( event ) { + if ( ! this.props.onContentSizeChange ) { + return; + } + const size = event.nativeEvent.contentSize; + const { onContentSizeChange } = this.props; + onContentSizeChange( size ); + } + + _onEnter( event ) { + if ( ! this.isFocused() ) { + return; + } + + if ( ! this.props.onEnter ) { + return; + } + + const { onEnter } = this.props; + onEnter( event ); + } + + _onBackspace( event ) { + if ( ! this.props.onBackspace ) { + return; + } + + const { onBackspace } = this.props; + onBackspace( event ); + } + + _onHTMLContentWithCursor( event ) { + if ( ! this.props.onHTMLContentWithCursor ) { + return; + } + + const text = event.nativeEvent.text; + const selectionStart = event.nativeEvent.selectionStart; + const selectionEnd = event.nativeEvent.selectionEnd; + const { onHTMLContentWithCursor } = this.props; + onHTMLContentWithCursor( text, selectionStart, selectionEnd ); + } + + _onFocus( event ) { + if ( ! this.props.onFocus ) { + return; + } + + const { onFocus } = this.props; + onFocus( event ); + } + + _onBlur( event ) { + this.selectionEndCaretY = null; + TextInputState.blurTextInput( ReactNative.findNodeHandle( this ) ); + + if ( ! this.props.onBlur ) { + return; + } + + const { onBlur } = this.props; + onBlur( event ); + } + + _onSelectionChange( event ) { + if ( this.props.onSelectionChange ) { + const { selectionStart, selectionEnd, text } = event.nativeEvent; + const { onSelectionChange } = this.props; + onSelectionChange( selectionStart, selectionEnd, text, event ); + } + + if ( + this.props.onCaretVerticalPositionChange && + this.selectionEndCaretY !== event.nativeEvent.selectionEndCaretY + ) { + const caretY = event.nativeEvent.selectionEndCaretY; + this.props.onCaretVerticalPositionChange( + event.target, + caretY, + this.selectionEndCaretY + ); + this.selectionEndCaretY = caretY; + } + } + + blur() { + TextInputState.blurTextInput( ReactNative.findNodeHandle( this ) ); + } + + focus() { + TextInputState.focusTextInput( ReactNative.findNodeHandle( this ) ); + } + + isFocused() { + const focusedField = TextInputState.currentlyFocusedField(); + return ( + focusedField && focusedField === ReactNative.findNodeHandle( this ) + ); + } + + _onPress( event ) { + if ( ! this.isFocused() ) { + this.focus(); // Call to move the focus in RN way (TextInputState) + this._onFocus( event ); // Check if there are listeners set on the focus event + } + } + + _onAztecFocus( event ) { + // IMPORTANT: the onFocus events from Aztec are thrown away on Android as these are handled by onPress() in the upper level. + // It's necessary to do this otherwise onFocus may be set by `{...otherProps}` and thus the onPress + onFocus + // combination generate an infinite loop as described in https://github.com/wordpress-mobile/gutenberg-mobile/issues/302 + // For iOS, this is necessary to let the system know when Aztec was focused programatically. + if ( Platform.OS === 'ios' ) { + this._onPress( event ); + } + } + + render() { + // eslint-disable-next-line no-unused-vars + const { onActiveFormatsChange, onFocus, ...otherProps } = this.props; + return ( + + + + ); + } +} + +const RCTAztecView = requireNativeComponent( 'RCTAztecView', AztecView ); + +export default AztecView; diff --git a/packages/react-native-bridge/.gitattributes b/packages/react-native-bridge/.gitattributes new file mode 100644 index 00000000000000..eb3959108e823d --- /dev/null +++ b/packages/react-native-bridge/.gitattributes @@ -0,0 +1 @@ +*.pbxproj -text \ No newline at end of file diff --git a/packages/react-native-bridge/.gitignore b/packages/react-native-bridge/.gitignore new file mode 100644 index 00000000000000..3cd0782ffa6bef --- /dev/null +++ b/packages/react-native-bridge/.gitignore @@ -0,0 +1,45 @@ + +# OSX +# +.DS_Store + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + + +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate +project.xcworkspace + + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# BUCK +buck-out/ +\.buckd/ +*.keystore diff --git a/packages/react-native-bridge/.npmrc b/packages/react-native-bridge/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/react-native-bridge/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/react-native-bridge/Gutenberg.podspec b/packages/react-native-bridge/Gutenberg.podspec new file mode 100644 index 00000000000000..5a8166c50102ca --- /dev/null +++ b/packages/react-native-bridge/Gutenberg.podspec @@ -0,0 +1,27 @@ +package = JSON.parse(File.read(File.join(File.expand_path('../..'), 'package.json'))) +# Use the same RN version that the JS tools use +react_native_version = package['devDependencies']['react-native'] +# Extract the tagged version if package.json points to a tag +react_native_version = react_native_version.split("#v").last if react_native_version.include? "#v" + +Pod::Spec.new do |s| + s.name = 'Gutenberg' + s.version = package['version'] + s.summary = 'Printing since 1440' + s.homepage = package['homepage'] + s.license = package['license'] + s.authors = 'Automattic' + s.platform = :ios, '11.0' + s.source = { :git => 'https://github.com/WordPress/gutenberg.git' } + s.source_files = 'ios/**/*.{h,m,swift}' + s.requires_arc = true + s.preserve_paths = 'bundle/ios/*' + s.swift_version = '5.0' + s.resources = 'common/**/*.{js,css,json}' + + s.dependency 'React', react_native_version + s.dependency 'React-CoreModules', react_native_version + s.dependency 'React-RCTImage', react_native_version + + s.dependency 'RNTAztecView' +end diff --git a/packages/react-native-bridge/README.md b/packages/react-native-bridge/README.md new file mode 100644 index 00000000000000..8c1a7a3d0cdbfa --- /dev/null +++ b/packages/react-native-bridge/README.md @@ -0,0 +1,46 @@ + +# react-native-gutenberg-bridge + +## Getting started + +This package is not yet published to npm. You can use it locally: + +`$ npm install ./gutenberg/packages/react-native-bridge --save` + +### Mostly automatic installation + +`$ react-native link @wordpress/react-native-bridge` + +### Manual installation + + +#### iOS + +1. In XCode, in the project navigator, right click `Libraries` ➜ `Add Files to [your project's name]` +2. Go to `node_modules` ➜ `react-native-bridge` and add `RNReactNativeGutenbergBridge.xcodeproj` +3. In XCode, in the project navigator, select your project. Add `libRNReactNativeGutenbergBridge.a` to your project's `Build Phases` ➜ `Link Binary With Libraries` +4. Run your project (`Cmd+R`)< + +#### Android + +1. Open up `android/app/src/main/java/[...]/MainActivity.java` + - Add `import com.reactlibrary.RNReactNativeGutenbergBridgePackage;` to the imports at the top of the file + - Add `new RNReactNativeGutenbergBridgePackage()` to the list returned by the `getPackages()` method +2. Append the following lines to `android/settings.gradle`: + ``` + include ':@wordpress_react-native-bridge' + project(':@wordpress_react-native-bridge').projectDir = new File(rootProject.projectDir, './gutenberg/packages/react-native-bridge/android') + ``` +3. Insert the following lines inside the dependencies block in `android/app/build.gradle`: + ``` + implementation project(':@wordpress_react-native-bridge') + ``` + +## Usage +```javascript +import RNReactNativeGutenbergBridge from '@wordpress/react-native-bridge'; + +// TODO: What to do with the module? +RNReactNativeGutenbergBridge; +``` + diff --git a/packages/react-native-bridge/android/build.gradle b/packages/react-native-bridge/android/build.gradle new file mode 100644 index 00000000000000..9eb117f9d27542 --- /dev/null +++ b/packages/react-native-bridge/android/build.gradle @@ -0,0 +1,330 @@ +buildscript { + def buildGutenbergMobileJSBundle = + System.getenv('SUPPRESS_GUTENBERG_MOBILE_JS_BUNDLE_BUILD').asBoolean() + ? false : (rootProject.ext.has("buildGutenbergMobileJSBundle") + && rootProject.ext.buildGutenbergMobileJSBundle) + + ext.kotlinVersion = '1.3.61' + + repositories { + jcenter() + google() + + if (buildGutenbergMobileJSBundle) { + maven { + url "https://plugins.gradle.org/m2/" + } + } + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + classpath 'com.android.tools.build:gradle:3.4.2' + classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' + + if (buildGutenbergMobileJSBundle) { + classpath "com.moowork.gradle:gradle-node-plugin:1.3.1" + } + } +} + +apply plugin: 'com.android.library' +apply plugin: 'com.github.dcendents.android-maven' +apply plugin: 'kotlin-android' + +def buildGutenbergMobileJSBundle = + System.getenv('SUPPRESS_GUTENBERG_MOBILE_JS_BUNDLE_BUILD').asBoolean() + ? false : (rootProject.ext.has("buildGutenbergMobileJSBundle") + && rootProject.ext.buildGutenbergMobileJSBundle) + +def tempFolder = "${System.getenv('TMPDIR')}/jsbundle/${System.getenv('VERSION')}" +def nodeFolder = file("${tempFolder}/nodejs") +def npmFolder = file("${tempFolder}/npm") + +if (buildGutenbergMobileJSBundle) { + println 'Building the Gutenberg Mobile JS bundle' + + apply plugin: 'com.moowork.node' + + node { + // Version of node to use. + version = '12.18.1' + + // Version of npm to use. + npmVersion = '6.14.5' + + // Base URL for fetching node distributions (change if you have a mirror). + distBaseUrl = 'https://nodejs.org/dist' + + // If true, it will download node using above parameters. + // If false, it will try to use globally installed node. + download = true + + // Set the work directory for unpacking node + workDir = file(nodeFolder) + + // Set the work directory for NPM + npmWorkDir = file(npmFolder) + + // Set the work directory where node_modules should be located + nodeModulesDir = file("${project.projectDir}/../../../../") + } + + npm_install { + args = ['--prefer-offline'] + } +} + +// import the `readReactNativeVersion()` function +apply from: 'https://gist.githubusercontent.com/hypest/742448b9588b3a0aa580a5e80ae95bdf/raw/8eb62d40ee7a5104d2fcaeff21ce6f29bd93b054/readReactNativeVersion.gradle' + +// import the `readHashedVersion()` function +apply from: 'https://gist.githubusercontent.com/hypest/ceaf20a8e7d9b8404e4a5ff2e6c36650/raw/e1460a128e4b9863963410d719c7d44c3adefd02/readHashedVersion.gradle' + +// import the `waitJitpack()` function +apply from: 'https://gist.githubusercontent.com/hypest/f526fe0775dedce0ce0133f1400d22a4/raw/0008b271a0d28fc79957fd3c2a027f57e98f796a/wait-jitpack.gradle' + +group='com.github.wordpress-mobile.gutenberg-mobile' + +// fallback flag value for when lib is compiled individually (e.g. via jitpack) +project.ext.buildGutenbergFromSource = false + +def hermesOriginalPath = "../../../node_modules/hermes-engine/android/"; +def hermesPath = hermesOriginalPath; +def buildAssetsFolder = 'build/assets' + +android { + compileSdkVersion 28 + + defaultConfig { + minSdkVersion 21 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + } + lintOptions { + abortOnError false + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + sourceSets { + main { + assets.srcDirs += buildAssetsFolder + } + } +} + +repositories { + google() + jcenter() + + maven { url "https://jitpack.io" } + + if (rootProject.ext.buildGutenbergFromSource) { + // If building from source, use the local sources from node_modules + def nodeModulesPath = "${project.buildDir}/../../../node_modules/" + maven { url "${nodeModulesPath}/react-native/android" } + } else { + // If not building from source (e.g. Jitpack), use the bintray repo so a local RN setup is not needed + def reactNativeRepo = 'https://dl.bintray.com/wordpress-mobile/react-native-mirror/' + println "Will use the RN maven repo at ${reactNativeRepo}" + maven { url reactNativeRepo } + } +} + +dependencies { + implementation project(':@wordpress_react-native-aztec') + + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" + + implementation "org.wordpress:utils:1.22" + + // For animated GIF support + implementation 'com.facebook.fresco:animated-gif:2.0.0' + + implementation 'com.google.android.material:material:1.1.0' + + if (rootProject.ext.buildGutenbergFromSource) { + println "using gutenberg from source" + implementation project(':react-native-linear-gradient') + implementation project(':react-native-svg') + implementation project(':react-native-video') + implementation project(':@react-native-community_slider') + implementation project(':react-native-get-random-values') + + implementation 'com.facebook.react:react-native:+' + } else { + hermesPath = "./vendor/hermes-engine/"; + + implementation (waitJitpack('com.github.wordpress-mobile', 'react-native-svg', readHashedVersion('../../react-native-editor/package.json', 'react-native-svg', 'dependencies'))) + implementation (waitJitpack('com.github.wordpress-mobile', 'react-native-video', readHashedVersion('../../react-native-editor/package.json', 'react-native-video', 'dependencies'))) + implementation (waitJitpack('com.github.wordpress-mobile', 'react-native-linear-gradient', readHashedVersion('../../react-native-editor/package.json', 'react-native-linear-gradient', 'dependencies'))) + implementation (waitJitpack('com.github.wordpress-mobile', 'react-native-slider', readHashedVersion('../../react-native-editor/package.json', '@react-native-community/slider', 'dependencies'))) + implementation (waitJitpack('com.github.wordpress-mobile', 'react-native-get-random-values', readHashedVersion('../../react-native-editor/package.json', 'react-native-get-random-values', 'dependencies'))) + + // FIXME Temporary fix to get Jitpack builds to green while I work on a solution without hardcoded values. + //def rnVersion = readReactNativeVersion('../package.json', 'peerDependencies') + def rnVersion = '0.61.5' + implementation "com.facebook.react:react-native:${rnVersion}" + } + + debugImplementation files(hermesPath + "hermes-debug.aar") + releaseImplementation files(hermesPath + "hermes-release.aar") +} + +boolean isBundleUpToDate() { + return project.hasProperty('isBundleUpToDate') && isBundleUpToDate +} + +if (buildGutenbergMobileJSBundle) { + def bundleName = 'index.android.bundle' + def mobileGutenbergRootDir = '../../../..' + + task bundleUpToDateCheck { + description("Checks if the inputs to the javascript bundle and the bundle itself are unchanged. \ +If they are changed, the isBundleUpToDate flag is switched to false. That flag is used by other tasks.") + + def dirs = [mobileGutenbergRootDir] + def bundlePath = file("$mobileGutenbergRootDir/bundle").absolutePath + file(mobileGutenbergRootDir).eachDirRecurse { dir -> + def isRelevantDir = !['react-native-bridge/android/build/intermediates', + bundlePath, + 'node_modules'].any { dir.absolutePath.contains(it) } && + !dir.name.startsWith('symlinked') + if (isRelevantDir) { + dirs << dir + } + } + + def isRelevantFile = { it.name.endsWithAny('.js', '.css', '.scss') || it.name == 'package.json' } + def inputFiles = [] + dirs.forEach { dir -> + file(dir).eachFile { + if (isRelevantFile(it)) { + inputFiles << it + } + } + } + + inputs.files(inputFiles) + + // We cannot use the bundle file itself as an output because it does not yet exist when this + // task finishes. Nevertheless, we have to declare something as an output because only tasks + // with outputs are run incrementally, so we're declaring a file that does not exist as the + // output. Since that file never exists, that "output" will always be considered "up-to-date". + outputs.file("nonexistentfile") + + // Using onlyIf here as a hack to run this check at the time of execution even if the task + // is otherwise up to date. For example, even if the task is up to date the isBundleUpToDate value + // should be false if the bundle file does not exist at the time this task runs. This must be run + // at execution time to catch the case where the clean task is also running and would remove the + // bundle file between the configuration phase and the execution of this task. + onlyIf { + project.ext.isBundleUpToDate = file("$buildAssetsFolder/$bundleName").exists() + true + } + + // If this task runs, that means some of the inputs have changed, and the isBundleUpToDate + // flag needs should be false so that the bundle is rebuilt. + doLast { + project.ext.isBundleUpToDate = false + } + } + + npm_install.dependsOn bundleUpToDateCheck + npm_install.onlyIf { !isBundleUpToDate() } + + task buildJSBundle(type: NpmTask) { + dependsOn bundleUpToDateCheck + onlyIf { !isBundleUpToDate() } + + args = ['run', 'bundle:android'] + } + + task backupHermesDebugAAR(type: Copy) { + dependsOn bundleUpToDateCheck + onlyIf { !isBundleUpToDate() } + + def origFileName = 'hermes-debug.aar' + def origWithPath = hermesOriginalPath + origFileName + from origWithPath + into hermesPath + doLast { + println "Done backing up Hermes debug AARs" + } + } + + task backupHermesReleaseAAR(type: Copy) { + dependsOn bundleUpToDateCheck + onlyIf { !isBundleUpToDate() } + + def origFileName = 'hermes-release.aar' + def origWithPath = hermesOriginalPath + origFileName + from origWithPath + into hermesPath + doLast { + println "Done backing up Hermes release AARs" + } + } + + task copyJSBundle(type: Copy) { + dependsOn bundleUpToDateCheck + onlyIf { !isBundleUpToDate() } + + def origFileName = 'App.js' + def origWithPath = "$mobileGutenbergRootDir/bundle/android/${origFileName}" + from origWithPath + into buildAssetsFolder + rename origFileName, bundleName + + // Prevent this task from silently failing + // Using onlyIf as a bit of a hack to perform this check at the time of execution + onlyIf { + if (inputs.sourceFiles.empty) { + throw new StopExecutionException("ERROR: Could not find bundle file to copy.") + } + true + } + + doLast { + println "Done copying the Android JS bundle to assets folder" + } + } + + def nodeModulesFolders = ["$mobileGutenbergRootDir/node_modules", "$mobileGutenbergRootDir/gutenberg/node_modules"] as String[] + task cleanupNodeModulesFolders(type: Delete) { + doFirst { + println "Deleting node_modules folders" + } + dependsOn bundleUpToDateCheck + onlyIf { !isBundleUpToDate() } + + delete nodeModulesFolders + } + + task resetExtractedRNTools(type: Delete) { + doFirst { + println "Deleting temporary folders with extracted RN tools" + } + delete nodeFolder, npmFolder + } + + preBuild.dependsOn(cleanupNodeModulesFolders) + cleanupNodeModulesFolders.dependsOn(backupHermesDebugAAR) + backupHermesDebugAAR.dependsOn(backupHermesReleaseAAR) + backupHermesReleaseAAR.dependsOn(copyJSBundle) + copyJSBundle.dependsOn(buildJSBundle) + buildJSBundle.dependsOn(npm_install) + nodeSetup.dependsOn(resetExtractedRNTools) + + clean { + doFirst { + println "Executing extended clean task that also deletes node_modules folders" + } + delete nodeModulesFolders + } +} diff --git a/packages/react-native-bridge/android/gradle.properties b/packages/react-native-bridge/android/gradle.properties new file mode 100644 index 00000000000000..938b16188c39d1 --- /dev/null +++ b/packages/react-native-bridge/android/gradle.properties @@ -0,0 +1,3 @@ +android.useAndroidX=true +android.enableJetifier=true + diff --git a/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.jar b/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000000..01b8bf6b1f99ca Binary files /dev/null and b/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.properties b/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000000..a0a439e0193425 --- /dev/null +++ b/packages/react-native-bridge/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip diff --git a/packages/react-native-bridge/android/gradlew b/packages/react-native-bridge/android/gradlew new file mode 100755 index 00000000000000..cccdd3d517fc52 --- /dev/null +++ b/packages/react-native-bridge/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/packages/react-native-bridge/android/gradlew.bat b/packages/react-native-bridge/android/gradlew.bat new file mode 100644 index 00000000000000..e95643d6a2ca62 --- /dev/null +++ b/packages/react-native-bridge/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/react-native-bridge/android/settings.gradle b/packages/react-native-bridge/android/settings.gradle new file mode 100644 index 00000000000000..004f79b37fcb5d --- /dev/null +++ b/packages/react-native-bridge/android/settings.gradle @@ -0,0 +1,5 @@ +rootProject.name = '@wordpress/react-native-bridge' + +include ':@wordpress_react-native-aztec' +project(':@wordpress_react-native-aztec').projectDir = new File(rootProject.projectDir, '../../react-native-aztec/android') + diff --git a/packages/react-native-bridge/android/src/debug/AndroidManifest.xml b/packages/react-native-bridge/android/src/debug/AndroidManifest.xml new file mode 100644 index 00000000000000..49ddd2f355c40e --- /dev/null +++ b/packages/react-native-bridge/android/src/debug/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/packages/react-native-bridge/android/src/main/AndroidManifest.xml b/packages/react-native-bridge/android/src/main/AndroidManifest.xml new file mode 100644 index 00000000000000..cf6c1d05ddbe11 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/AndroidManifest.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/packages/react-native-bridge/android/src/main/assets/gutenberg-web-single-block b/packages/react-native-bridge/android/src/main/assets/gutenberg-web-single-block new file mode 120000 index 00000000000000..705d9aaab8f96f --- /dev/null +++ b/packages/react-native-bridge/android/src/main/assets/gutenberg-web-single-block @@ -0,0 +1 @@ +../../../../common/gutenberg-web-single-block \ No newline at end of file diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/FileUtils.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/FileUtils.java new file mode 100644 index 00000000000000..35b4e4980be219 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/FileUtils.java @@ -0,0 +1,38 @@ +package org.wordpress.mobile; + +import android.app.Activity; +import android.content.res.AssetManager; + +import org.wordpress.android.util.AppLog; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +public class FileUtils { + + public static String getHtmlFromFile(Activity activity, String filename) { + try { + AssetManager assetManager = activity.getAssets(); + InputStream in = assetManager.open(filename); + return getStringFromInputStream(in); + } catch (IOException e) { + AppLog.e(AppLog.T.EDITOR, "Unable to load editor HTML (is the assets symlink working?): " + e.getMessage()); + return null; + } + } + + public static String getStringFromInputStream(InputStream inputStream) throws IOException { + InputStreamReader is = new InputStreamReader(inputStream); + StringBuilder sb = new StringBuilder(); + BufferedReader br = new BufferedReader(is); + String read = br.readLine(); + while (read != null) { + sb.append(read); + sb.append('\n'); + read = br.readLine(); + } + return sb.toString(); + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeInterface.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeInterface.java new file mode 100644 index 00000000000000..5e9a4c09fafd83 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeInterface.java @@ -0,0 +1,7 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge; + +public interface GutenbergBridgeInterface { + + void saveContent(String content, String blockId); + +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java new file mode 100644 index 00000000000000..77cbff91227199 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergBridgeJS2Parent.java @@ -0,0 +1,155 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge; + +import androidx.core.util.Consumer; + +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; + +import org.wordpress.mobile.WPAndroidGlue.MediaOption; +import org.wordpress.mobile.WPAndroidGlue.RequestExecutor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public interface GutenbergBridgeJS2Parent extends RequestExecutor { + + void responseHtml(String title, String html, boolean changed, ReadableMap contentInfo); + + void editorDidMount(ReadableArray unsupportedBlockNames); + + interface OtherMediaOptionsReceivedCallback { + void onOtherMediaOptionsReceived(ArrayList mediaList); + } + + interface MediaSelectedCallback { + void onMediaFileSelected(List mediaList); + } + + interface MediaUploadEventEmitter { + void onUploadMediaFileClear(int mediaId); + void onMediaFileUploadProgress(int mediaId, float progress); + void onMediaFileUploadSucceeded(int mediaId, String mediaUrl, int serverId); + void onMediaFileUploadFailed(int mediaId); + } + + interface ReplaceUnsupportedBlockCallback { + void replaceUnsupportedBlock(String content, String blockId); + } + + interface StarterPageTemplatesTooltipShownCallback { + void onRequestStarterPageTemplatesTooltipShown(boolean tooltipShown); + } + + // Ref: https://github.com/facebook/react-native/blob/master/Libraries/polyfills/console.js#L376 + enum LogLevel { + TRACE(0), + INFO(1), + WARN(2), + ERROR(3); + + private final int id; + + LogLevel(int id) { + this.id = id; + } + + public static LogLevel valueOf(int id) { + for (LogLevel num : values()) { + if (num.id == id) { + return num; + } + } + return null; + } + } + + enum MediaType { + IMAGE("image"), + VIDEO("video"), + MEDIA("media"), + AUDIO("audio"), + OTHER("other"); + + String name; + + MediaType(String name) { + this.name = name; + } + + public static MediaType getEnum(String value) { + for (MediaType mediaType : values()) { + if (mediaType.name.equals(value)) { + return mediaType; + } + } + + return OTHER; + } + } + + enum GutenbergUserEvent { + EDITOR_SESSION_TEMPLATE_APPLY("editor_session_template_apply"), + EDITOR_SESSION_TEMPLATE_PREVIEW("editor_session_template_preview"); + + private static final Map MAP = new HashMap<>(); + + static { + for (GutenbergUserEvent event : values()) { + MAP.put(event.name, event); + } + } + + String name; + + GutenbergUserEvent(String name) { + this.name = name; + } + + public static GutenbergUserEvent getEnum(String eventName) { + return MAP.get(eventName); + } + } + + void requestMediaPickFromMediaLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType); + + void requestMediaPickFromDeviceLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType); + + void requestMediaPickerFromDeviceCamera(MediaSelectedCallback mediaSelectedCallback, MediaType mediaType); + + void requestMediaImport(String url, MediaSelectedCallback mediaSelectedCallback); + + void mediaUploadSync(MediaSelectedCallback mediaSelectedCallback); + + void requestImageFailedRetryDialog(int mediaId); + + void requestImageUploadCancelDialog(int mediaId); + + void requestImageUploadCancel(int mediaId); + + void editorDidEmitLog(String message, LogLevel logLevel); + + void editorDidAutosave(); + + void getOtherMediaPickerOptions(OtherMediaOptionsReceivedCallback otherMediaOptionsReceivedCallback, MediaType mediaType); + + void requestMediaPickFrom(String mediaSource, MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection); + + void requestImageFullscreenPreview(String mediaUrl); + + void requestMediaEditor(MediaSelectedCallback mediaSelectedCallback, String mediaUrl); + + void logUserEvent(GutenbergUserEvent gutenbergUserEvent, ReadableMap eventProperties); + + void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback replaceUnsupportedBlockCallback, + String content, + String blockId, + String blockName); + + void onAddMention(Consumer onSuccess); + + void setStarterPageTemplatesTooltipShown(boolean tooltipShown); + + void requestStarterPageTemplatesTooltipShown(StarterPageTemplatesTooltipShownCallback starterPageTemplatesTooltipShownCallback); +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java new file mode 100644 index 00000000000000..6548329bcabb83 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/GutenbergWebViewActivity.java @@ -0,0 +1,259 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge; + +import android.annotation.SuppressLint; +import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.webkit.CookieManager; +import android.webkit.JavascriptInterface; +import android.webkit.WebSettings; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import androidx.annotation.Nullable; +import androidx.appcompat.app.ActionBar; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; + +import org.wordpress.android.util.AppLog; +import org.wordpress.android.util.helpers.WPWebChromeClient; +import org.wordpress.mobile.FileUtils; + +import java.util.Locale; + +public class GutenbergWebViewActivity extends AppCompatActivity { + + public static final String ARG_USER_ID = "authenticated_user_id"; + + public static final String ARG_BLOCK_ID = "block_id"; + public static final String ARG_BLOCK_NAME = "block_name"; + public static final String ARG_BLOCK_CONTENT = "block_content"; + + private static final String INJECT_LOCAL_STORAGE_SCRIPT_TEMPLATE = "localStorage.setItem('WP_DATA_USER_%d','%s')"; + private static final String INJECT_CSS_SCRIPT_TEMPLATE = "window.injectCss('%s')"; + private static final String INJECT_GET_HTML_POST_CONTENT_SCRIPT = "window.getHTMLPostContent();"; + private static final String JAVA_SCRIPT_INTERFACE_NAME = "wpwebkit"; + + protected WebView mWebView; + + @SuppressLint("SetJavaScriptEnabled") + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_gutenberg_web_view); + + setupToolbar(); + + mWebView = findViewById(R.id.gutenberg_web_view); + + // Set settings + WebSettings settings = mWebView.getSettings(); + settings.setJavaScriptEnabled(true); + settings.setDomStorageEnabled(true); + CookieManager cookieManager = CookieManager.getInstance(); + cookieManager.setAcceptThirdPartyCookies(mWebView, true); + + // Add javascript interface + mWebView.addJavascriptInterface(new WPWebKit(), JAVA_SCRIPT_INTERFACE_NAME); + + // Setup WebView client + setupWebViewClient(); + mWebView.setWebChromeClient(new WPWebChromeClient(null, findViewById(R.id.progress_bar))); + + loadUrl(); + } + + protected void loadUrl() { + mWebView.loadUrl("https://wordpress.org/gutenberg/"); + } + + private void setupToolbar() { + setTitle(""); + + Toolbar toolbar = findViewById(R.id.toolbar); + if (toolbar != null) { + setSupportActionBar(toolbar); + + ActionBar actionBar = getSupportActionBar(); + if (actionBar != null) { + actionBar.setDisplayShowTitleEnabled(true); + actionBar.setDisplayHomeAsUpEnabled(true); + actionBar.setHomeAsUpIndicator(R.drawable.ic_close_24px); + actionBar.setSubtitle(""); + actionBar.setTitle(getToolbarTitle()); + } + } + } + + protected String getToolbarTitle() { + String blockName = getIntent().getExtras().getString(ARG_BLOCK_NAME); + if (blockName != null) { + return String.format("Edit %s block", blockName); + } + return ""; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + super.onCreateOptionsMenu(menu); + + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_gutenberg_webview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(final MenuItem item) { + if (mWebView == null) { + return false; + } + + int itemID = item.getItemId(); + + if (itemID == android.R.id.home) { + finish(); + } else if (itemID == R.id.menu_save) { + saveAction(); + return true; + } + + return super.onOptionsItemSelected(item); + } + + private void saveAction() { + mWebView.clearFocus(); + mWebView.evaluateJavascript(INJECT_GET_HTML_POST_CONTENT_SCRIPT, + value -> AppLog.e(AppLog.T.EDITOR, value)); + } + + protected void saveContent(String content) { + String blockId = getIntent().getExtras().getString(ARG_BLOCK_ID); + AppLog.i(AppLog.T.EDITOR, String.format(Locale.US, "Save block id %s, with content %s", blockId, content)); + ((GutenbergBridgeInterface)getApplication()).saveContent(content, blockId); + finish(); + } + + private String getFileContentFromAssets(String assetsFileName) { + return FileUtils.getHtmlFromFile(this, assetsFileName); + } + + private String removeNewLines(String content) { + return content.replace("\r\n", " ").replace("\n", " "); + } + + private String removeWhiteSpace(String content) { + return content.replaceAll("\\s+", ""); + } + + private void setupWebViewClient() { + mWebView.setWebViewClient(new WebViewClient() { + private boolean mIsRedirected; + + @Override + public boolean shouldOverrideUrlLoading(WebView view, String url) { + // Set if page is redirected + if (!mIsRedirected) { + mIsRedirected = true; + } + + return super.shouldOverrideUrlLoading(view, url); + } + + @Override + public void onPageCommitVisible(WebView view, String url) { + + String injectCssScript = getFileContentFromAssets("gutenberg-web-single-block/inject-css.js"); + evaluateJavaScript(injectCssScript); + + long userId = getIntent().getExtras().getLong(ARG_USER_ID, 0); + if (userId != 0) { + String injectLocalStorageScript = getFileContentFromAssets("gutenberg-web-single-block/local-storage-overrides.json"); + injectLocalStorageScript = removeWhiteSpace(removeNewLines(injectLocalStorageScript)); + + evaluateJavaScript( + String.format( + Locale.US, + INJECT_LOCAL_STORAGE_SCRIPT_TEMPLATE, + userId, + injectLocalStorageScript) + ); + } + + super.onPageCommitVisible(view, url); + } + + @Override + public void onPageFinished(WebView view, String url) { + super.onPageFinished(view, url); + + if (mIsRedirected) { + mIsRedirected = false; + return; + } + + String contentFunctions = getFileContentFromAssets("gutenberg-web-single-block/content-functions.js"); + evaluateJavaScript(contentFunctions); + + String editorStyle = getFileContentFromAssets("gutenberg-web-single-block/editor-style-overrides.css"); + editorStyle = removeWhiteSpace(removeNewLines(editorStyle)); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, editorStyle)); + + String injectWPBarsCssScript = getFileContentFromAssets("gutenberg-web-single-block/wp-bar-override.css"); + injectWPBarsCssScript = removeWhiteSpace(removeNewLines(injectWPBarsCssScript)); + evaluateJavaScript(String.format(INJECT_CSS_SCRIPT_TEMPLATE, injectWPBarsCssScript)); + + final Handler handler = new Handler(); + handler.postDelayed(() -> { + String preventAutosaves = getFileContentFromAssets("gutenberg-web-single-block/prevent-autosaves.js"); + evaluateJavaScript(preventAutosaves); + + String insertBlock = getFileContentFromAssets("gutenberg-web-single-block/insert-block.js").replace("%@","%s"); + String blockContent = getIntent().getExtras().getString(ARG_BLOCK_CONTENT); + insertBlock = String.format(insertBlock, blockContent); + evaluateJavaScript(removeNewLines(insertBlock)); + + view.setVisibility(View.VISIBLE); + }, 2000); + } + + private void evaluateJavaScript(String script) { + mWebView.evaluateJavascript(script, value -> + AppLog.e(AppLog.T.EDITOR, value)); + } + }); + } + + @Override + public void onBackPressed() { + if (mWebView.canGoBack()) { + mWebView.goBack(); + } else { + super.onBackPressed(); + } + } + + @Override + public void finish() { + runOnUiThread(new Runnable() { + @Override public void run() { + mWebView.removeJavascriptInterface(JAVA_SCRIPT_INTERFACE_NAME); + mWebView.clearHistory(); + mWebView.clearFormData(); + mWebView.clearCache(true); + } + }); + + super.finish(); + } + + public class WPWebKit { + @JavascriptInterface + public void postMessage(String content) { + if (content != null && content.length() > 0) { + saveContent(content); + } + } + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNMedia.kt b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNMedia.kt new file mode 100644 index 00000000000000..ae614d41e2cfef --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNMedia.kt @@ -0,0 +1,11 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge + +import com.facebook.react.bridge.WritableMap + +interface RNMedia { + val url: String + val id: Int + val type: String + val caption: String + fun toMap(): WritableMap +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java new file mode 100644 index 00000000000000..db1aabb82fc021 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgeModule.java @@ -0,0 +1,339 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge; + +import android.os.Bundle; + +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.Callback; +import com.facebook.react.bridge.Promise; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.ReactContextBaseJavaModule; +import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.WritableArray; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeArray; +import com.facebook.react.bridge.WritableNativeMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.GutenbergUserEvent; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaType; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.OtherMediaOptionsReceivedCallback; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.StarterPageTemplatesTooltipShownCallback; +import org.wordpress.mobile.WPAndroidGlue.DeferredEventEmitter; +import org.wordpress.mobile.WPAndroidGlue.MediaOption; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class RNReactNativeGutenbergBridgeModule extends ReactContextBaseJavaModule implements + DeferredEventEmitter.JSEventEmitter { + private final ReactApplicationContext mReactContext; + private final GutenbergBridgeJS2Parent mGutenbergBridgeJS2Parent; + + private static final String EVENT_NAME_REQUEST_GET_HTML = "requestGetHtml"; + private static final String EVENT_NAME_UPDATE_HTML = "updateHtml"; + private static final String EVENT_NAME_UPDATE_TITLE = "setTitle"; + private static final String EVENT_NAME_FOCUS_TITLE = "setFocusOnTitle"; + private static final String EVENT_NAME_MEDIA_APPEND = "mediaAppend"; + private static final String EVENT_NAME_TOGGLE_HTML_MODE = "toggleHTMLMode"; + private static final String EVENT_NAME_NOTIFY_MODAL_CLOSED = "notifyModalClosed"; + private static final String EVENT_NAME_PREFERRED_COLOR_SCHEME = "preferredColorScheme"; + private static final String EVENT_NAME_MEDIA_REPLACE_BLOCK = "replaceBlock"; + private static final String EVENT_NAME_UPDATE_THEME = "updateTheme"; + + private static final String MAP_KEY_UPDATE_HTML = "html"; + private static final String MAP_KEY_UPDATE_TITLE = "title"; + public static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID = "mediaId"; + public static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL = "mediaUrl"; + public static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_TYPE = "mediaType"; + private static final String MAP_KEY_THEME_UPDATE_COLORS = "colors"; + private static final String MAP_KEY_THEME_UPDATE_GRADIENTS = "gradients"; + + private static final String MAP_KEY_IS_PREFERRED_COLOR_SCHEME_DARK = "isPreferredColorSchemeDark"; + + private static final String MEDIA_SOURCE_MEDIA_LIBRARY = "SITE_MEDIA_LIBRARY"; + private static final String MEDIA_SOURCE_DEVICE_LIBRARY = "DEVICE_MEDIA_LIBRARY"; + private static final String MEDIA_SOURCE_DEVICE_CAMERA = "DEVICE_CAMERA"; + + private static final String MAP_KEY_REPLACE_BLOCK_HTML = "html"; + private static final String MAP_KEY_REPLACE_BLOCK_BLOCK_ID = "clientId"; + + private boolean mIsDarkMode; + + public RNReactNativeGutenbergBridgeModule(ReactApplicationContext reactContext, + GutenbergBridgeJS2Parent gutenbergBridgeJS2Parent, boolean isDarkMode) { + super(reactContext); + mIsDarkMode = isDarkMode; + mReactContext = reactContext; + mGutenbergBridgeJS2Parent = gutenbergBridgeJS2Parent; + } + + @Override + public String getName() { + return "RNReactNativeGutenbergBridge"; + } + + @Override + public Map getConstants() { + final HashMap constants = new HashMap<>(); + constants.put("isInitialColorSchemeDark", mIsDarkMode); + return constants; + } + + @Override + public void emitToJS(String eventName, @Nullable WritableMap data) { + mReactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, data); + } + + public void getHtmlFromJS() { + emitToJS(EVENT_NAME_REQUEST_GET_HTML, null); + } + + public void setHtmlInJS(String html) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putString(MAP_KEY_UPDATE_HTML, html); + emitToJS(EVENT_NAME_UPDATE_HTML, writableMap); + } + + public void setTitleInJS(String title) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putString(MAP_KEY_UPDATE_TITLE, title); + emitToJS(EVENT_NAME_UPDATE_TITLE, writableMap); + } + + public void setFocusOnTitleInJS() { + WritableMap writableMap = new WritableNativeMap(); + emitToJS(EVENT_NAME_FOCUS_TITLE, writableMap); + } + + public void appendNewMediaBlock(int mediaId, String mediaUri, String mediaType) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_TYPE, mediaType); + writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL, mediaUri); + writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId); + emitToJS(EVENT_NAME_MEDIA_APPEND, writableMap); + } + + public void setPreferredColorScheme(boolean isDarkMode) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putBoolean(MAP_KEY_IS_PREFERRED_COLOR_SCHEME_DARK, isDarkMode); + emitToJS(EVENT_NAME_PREFERRED_COLOR_SCHEME, writableMap); + } + + public void updateTheme(@Nullable Bundle editorTheme) { + if (editorTheme == null) return; + + WritableMap writableMap = new WritableNativeMap(); + Serializable colors = editorTheme.getSerializable(MAP_KEY_THEME_UPDATE_COLORS); + Serializable gradients = editorTheme.getSerializable(MAP_KEY_THEME_UPDATE_GRADIENTS); + + if (colors != null) { + writableMap.putArray(MAP_KEY_THEME_UPDATE_COLORS, Arguments.fromList((ArrayList)colors)); + } + + if (gradients != null) { + writableMap.putArray(MAP_KEY_THEME_UPDATE_GRADIENTS, Arguments.fromList((ArrayList)gradients)); + } + + emitToJS(EVENT_NAME_UPDATE_THEME, writableMap); + } + + @ReactMethod + public void provideToNative_Html(String html, String title, boolean changed, ReadableMap contentInfo) { + mGutenbergBridgeJS2Parent.responseHtml(title, html, changed, contentInfo); + } + + @ReactMethod + public void editorDidMount(ReadableArray unsupportedBlockNames) { + mGutenbergBridgeJS2Parent.editorDidMount(unsupportedBlockNames); + } + + @ReactMethod + public void requestMediaPickFrom(String mediaSource, ReadableArray filter, Boolean allowMultipleSelection, final Callback onMediaSelected) { + MediaType mediaType = getMediaTypeFromFilter(filter); + if (mediaSource.equals(MEDIA_SOURCE_MEDIA_LIBRARY)) { + mGutenbergBridgeJS2Parent.requestMediaPickFromMediaLibrary(getNewMediaSelectedCallback(allowMultipleSelection, onMediaSelected), allowMultipleSelection, mediaType); + } else if (mediaSource.equals(MEDIA_SOURCE_DEVICE_LIBRARY)) { + mGutenbergBridgeJS2Parent.requestMediaPickFromDeviceLibrary(getNewMediaSelectedCallback(allowMultipleSelection, onMediaSelected), allowMultipleSelection, mediaType); + } else if (mediaSource.equals(MEDIA_SOURCE_DEVICE_CAMERA)) { + mGutenbergBridgeJS2Parent.requestMediaPickerFromDeviceCamera(getNewMediaSelectedCallback(allowMultipleSelection, onMediaSelected), mediaType); + } else { + mGutenbergBridgeJS2Parent.requestMediaPickFrom(mediaSource, getNewMediaSelectedCallback(allowMultipleSelection, onMediaSelected), allowMultipleSelection); + } + } + + private MediaType getMediaTypeFromFilter(ReadableArray filter) { + switch (filter.size()) { + case 1: + return MediaType.getEnum(filter.getString(0)); + case 2: + MediaType filter0 = MediaType.getEnum(filter.getString(0)); + MediaType filter1 = MediaType.getEnum(filter.getString(1)); + + if ((filter0.equals(MediaType.VIDEO) && filter1.equals(MediaType.IMAGE)) + || (filter0.equals(MediaType.IMAGE) && filter1.equals(MediaType.VIDEO))) { + return MediaType.MEDIA; + } + default: + return MediaType.OTHER; + } + } + + @ReactMethod + public void requestMediaImport(String url, final Callback onUploadMediaSelected) { + mGutenbergBridgeJS2Parent.requestMediaImport(url, getNewMediaSelectedCallback(false, onUploadMediaSelected)); + } + + @ReactMethod + public void mediaUploadSync() { + mGutenbergBridgeJS2Parent.mediaUploadSync(getNewMediaSelectedCallback(false,null)); + } + + @ReactMethod + public void requestImageFailedRetryDialog(final int mediaId) { + mGutenbergBridgeJS2Parent.requestImageFailedRetryDialog(mediaId); + } + + @ReactMethod + public void requestImageUploadCancelDialog(final int mediaId) { + mGutenbergBridgeJS2Parent.requestImageUploadCancelDialog(mediaId); + } + + @ReactMethod + public void requestImageUploadCancel(final int mediaId) { + mGutenbergBridgeJS2Parent.requestImageUploadCancel(mediaId); + } + + @ReactMethod + public void requestImageFullscreenPreview(String mediaUrl) { + mGutenbergBridgeJS2Parent.requestImageFullscreenPreview(mediaUrl); + } + + @ReactMethod + public void requestMediaEditor(String mediaUrl, final Callback onUploadMediaSelected) { + mGutenbergBridgeJS2Parent.requestMediaEditor(getNewMediaSelectedCallback(false, onUploadMediaSelected), mediaUrl); + } + + @ReactMethod + public void editorDidEmitLog(String message, int logLevel) { + mGutenbergBridgeJS2Parent.editorDidEmitLog(message, GutenbergBridgeJS2Parent.LogLevel.valueOf(logLevel)); + } + + @ReactMethod + public void editorDidAutosave() { + mGutenbergBridgeJS2Parent.editorDidAutosave(); + } + + @ReactMethod + public void getOtherMediaOptions(ReadableArray filter, final Callback jsCallback) { + OtherMediaOptionsReceivedCallback otherMediaOptionsReceivedCallback = getNewOtherMediaReceivedCallback(jsCallback); + MediaType mediaType = getMediaTypeFromFilter(filter); + mGutenbergBridgeJS2Parent.getOtherMediaPickerOptions(otherMediaOptionsReceivedCallback, mediaType); + } + + @ReactMethod + public void fetchRequest(String path, Promise promise) { + mGutenbergBridgeJS2Parent.performRequest(path, + promise::resolve, + errorBundle -> { + WritableMap writableMap = Arguments.makeNativeMap(errorBundle); + if (writableMap.hasKey("code")) { + String code = String.valueOf(writableMap.getInt("code")); + promise.reject(code, new Error(), writableMap); + } else { + promise.reject(new Error(), writableMap); + } + }); + } + + @ReactMethod + public void logUserEvent(String eventName, ReadableMap eventProperties) { + mGutenbergBridgeJS2Parent.logUserEvent(GutenbergUserEvent.getEnum(eventName), eventProperties); + } + + @ReactMethod + public void requestUnsupportedBlockFallback(String content, String blockId, String blockName) { + mGutenbergBridgeJS2Parent.gutenbergDidRequestUnsupportedBlockFallback((savedContent, savedBlockId) -> + replaceBlock(savedContent, savedBlockId), content, blockId, blockName); + } + + private void replaceBlock(String content, String blockId) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putString(MAP_KEY_REPLACE_BLOCK_HTML, content); + writableMap.putString(MAP_KEY_REPLACE_BLOCK_BLOCK_ID, blockId); + emitToJS(EVENT_NAME_MEDIA_REPLACE_BLOCK, writableMap); + } + + private OtherMediaOptionsReceivedCallback getNewOtherMediaReceivedCallback(final Callback jsCallback) { + return new OtherMediaOptionsReceivedCallback() { + @Override public void onOtherMediaOptionsReceived(ArrayList mediaOptions) { + WritableArray writableArray = new WritableNativeArray(); + for (MediaOption mediaOption : mediaOptions) { + writableArray.pushMap(mediaOption.toMap()); + } + jsCallback.invoke(writableArray); + } + }; + } + + @ReactMethod + public void addMention(Promise promise) { + mGutenbergBridgeJS2Parent.onAddMention(promise::resolve); + } + + @ReactMethod + public void setStarterPageTemplatesTooltipShown(boolean tooltipShown) { + mGutenbergBridgeJS2Parent.setStarterPageTemplatesTooltipShown(tooltipShown); + } + + @ReactMethod + public void requestStarterPageTemplatesTooltipShown(final Callback jsCallback) { + StarterPageTemplatesTooltipShownCallback starterPageTemplatesTooltipShownCallback = requestStarterPageTemplatesTooltipShownCallback(jsCallback); + mGutenbergBridgeJS2Parent.requestStarterPageTemplatesTooltipShown(starterPageTemplatesTooltipShownCallback); + } + + private StarterPageTemplatesTooltipShownCallback requestStarterPageTemplatesTooltipShownCallback(final Callback jsCallback) { + return new StarterPageTemplatesTooltipShownCallback() { + @Override public void onRequestStarterPageTemplatesTooltipShown(boolean tooltipShown) { + jsCallback.invoke(tooltipShown); + } + }; + } + + private GutenbergBridgeJS2Parent.MediaSelectedCallback getNewMediaSelectedCallback(final Boolean allowMultipleSelection, final Callback jsCallback) { + return new GutenbergBridgeJS2Parent.MediaSelectedCallback() { + @Override + public void onMediaFileSelected(List mediaList) { + if (allowMultipleSelection) { + WritableArray writableArray = new WritableNativeArray(); + for (RNMedia media : mediaList) { + writableArray.pushMap(media.toMap()); + } + jsCallback.invoke(writableArray); + } else if (!mediaList.isEmpty()) { + jsCallback.invoke(mediaList.get(0).toMap()); + } else { + // if we have no media (e.g. when a content provider throws an exception during file copy), invoke + // the js callback with no arguments + jsCallback.invoke(); + } + } + + }; + } + + + public void toggleEditorMode() { + emitToJS(EVENT_NAME_TOGGLE_HTML_MODE, null); + } + + public void notifyModalClosed() { + emitToJS(EVENT_NAME_NOTIFY_MODAL_CLOSED, null); + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgePackage.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgePackage.java new file mode 100644 index 00000000000000..6dfc782dd8583f --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/ReactNativeGutenbergBridge/RNReactNativeGutenbergBridgePackage.java @@ -0,0 +1,40 @@ +package org.wordpress.mobile.ReactNativeGutenbergBridge; + +import com.facebook.react.ReactPackage; +import com.facebook.react.bridge.NativeModule; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.uimanager.ViewManager; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class RNReactNativeGutenbergBridgePackage implements ReactPackage { + private final GutenbergBridgeJS2Parent mGutenbergBridgeJS2Parent; + private final boolean mIsDarkMode; + + private RNReactNativeGutenbergBridgeModule mRNReactNativeGutenbergBridgeModule; + + public RNReactNativeGutenbergBridgeModule getRNReactNativeGutenbergBridgeModule() { + return mRNReactNativeGutenbergBridgeModule; + } + + public RNReactNativeGutenbergBridgePackage(GutenbergBridgeJS2Parent gutenbergBridgeJS2Parent, + boolean isDarkMode) { + mGutenbergBridgeJS2Parent = gutenbergBridgeJS2Parent; + mIsDarkMode = isDarkMode; + } + + @Override + public List createNativeModules(ReactApplicationContext reactContext) { + mRNReactNativeGutenbergBridgeModule = new RNReactNativeGutenbergBridgeModule(reactContext, + mGutenbergBridgeJS2Parent, + mIsDarkMode); + return Arrays.asList(mRNReactNativeGutenbergBridgeModule); + } + + @Override + public List createViewManagers(ReactApplicationContext reactContext) { + return Collections.emptyList(); + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java new file mode 100644 index 00000000000000..837f10e1562835 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/AddMentionUtil.java @@ -0,0 +1,7 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import androidx.core.util.Consumer; + +public interface AddMentionUtil { + void getMention(Consumer onResult); +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java new file mode 100644 index 00000000000000..5ef2523424b9a9 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/DeferredEventEmitter.java @@ -0,0 +1,124 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import android.util.Pair; + +import androidx.annotation.Nullable; + +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeMap; + +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaUploadEventEmitter; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID; +import static org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgeModule.MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL; + +public class DeferredEventEmitter implements MediaUploadEventEmitter { + public interface JSEventEmitter { + void emitToJS(String eventName, @Nullable WritableMap data); + } + private static final int MEDIA_SERVER_ID_UNKNOWN = 0; + private static final int MEDIA_UPLOAD_STATE_UPLOADING = 1; + private static final int MEDIA_UPLOAD_STATE_SUCCEEDED = 2; + private static final int MEDIA_UPLOAD_STATE_FAILED = 3; + private static final int MEDIA_UPLOAD_STATE_RESET = 4; + + private static final String EVENT_NAME_MEDIA_UPLOAD = "mediaUpload"; + + private static final String MAP_KEY_MEDIA_FILE_UPLOAD_STATE = "state"; + private static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS = "progress"; + private static final String MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_SERVER_ID = "mediaServerId"; + + + /** + * Used for storing deferred actions prior to editor mounting + */ + private Queue> mPendingActions = new ConcurrentLinkedQueue<>(); + + private JSEventEmitter mJSEventEmitter; + + void setEmitter(JSEventEmitter emitter) { + mJSEventEmitter = emitter; + flushActionQueueToJS(); + } + + /** This will queue actions to JS when the editor has not yet mounted. When the editor mounts, the events will be + * flushed. If the editor has already mounted, this will directly call emitToJS. This is useful for critical + * messages that have required actions, such as upload completion events. + * + * @param eventName the name of the JS event + * @param data the JS event data (can be null) + */ + private void queueActionToJS(String eventName, @Nullable WritableMap data) { + if (mJSEventEmitter == null) { + mPendingActions.add(new Pair<>(eventName, data)); + } else { + mJSEventEmitter.emitToJS(eventName, data); + } + } + + /** This will optimistically emit events to JS (i.e. when the editor has mounted). If the editor has not mounted, + * this will silently drop the message. This is useful to send non-critical messages in a safe way. + * + * @param eventName the name of the JS event + * @param data the JS event data (can be null) + */ + private void emitOrDrop(String eventName, @Nullable WritableMap data) { + if (mJSEventEmitter != null) { + mJSEventEmitter.emitToJS(eventName, data); + } + } + + private void flushActionQueueToJS() { + while (0 < mPendingActions.size()) { + final Pair action = mPendingActions.remove(); + mJSEventEmitter.emitToJS(action.first, action.second); + } + } + + private void setMediaFileUploadDataInJS(int state, int mediaId, String mediaUrl, float progress) { + setMediaFileUploadDataInJS(state, mediaId, mediaUrl, progress, MEDIA_SERVER_ID_UNKNOWN); + } + + private void setMediaFileUploadDataInJS(int state, int mediaId, String mediaUrl, float progress, int mediaServerId) { + WritableMap writableMap = new WritableNativeMap(); + writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_STATE, state); + writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_ID, mediaId); + writableMap.putString(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_URL, mediaUrl); + writableMap.putDouble(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_PROGRESS, progress); + if (mediaServerId != MEDIA_SERVER_ID_UNKNOWN) { + writableMap.putInt(MAP_KEY_MEDIA_FILE_UPLOAD_MEDIA_SERVER_ID, mediaServerId); + } + if (isCriticalMessage(state)) { + queueActionToJS(EVENT_NAME_MEDIA_UPLOAD, writableMap); + } else { + emitOrDrop(EVENT_NAME_MEDIA_UPLOAD, writableMap); + } + } + + private boolean isCriticalMessage(int state) { + return state == MEDIA_UPLOAD_STATE_SUCCEEDED || state == MEDIA_UPLOAD_STATE_FAILED; + } + + @Override + public void onUploadMediaFileClear(int mediaId) { + setMediaFileUploadDataInJS(MEDIA_UPLOAD_STATE_RESET, mediaId, null, 0); + } + + @Override + public void onMediaFileUploadProgress(int mediaId, float progress) { + setMediaFileUploadDataInJS(MEDIA_UPLOAD_STATE_UPLOADING, mediaId, null, progress); + } + + @Override + public void onMediaFileUploadSucceeded(int mediaId, String mediaUrl, int mediaServerId) { + setMediaFileUploadDataInJS(MEDIA_UPLOAD_STATE_SUCCEEDED, mediaId, mediaUrl, 1, mediaServerId); + } + + @Override + public void onMediaFileUploadFailed(int mediaId) { + setMediaFileUploadDataInJS(MEDIA_UPLOAD_STATE_FAILED, mediaId, null, 0); + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/Media.kt b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/Media.kt new file mode 100644 index 00000000000000..f1a1f718fa6130 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/Media.kt @@ -0,0 +1,44 @@ +package org.wordpress.mobile.WPAndroidGlue + +import com.facebook.react.bridge.WritableMap +import com.facebook.react.bridge.WritableNativeMap +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaType +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaType.IMAGE +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaType.OTHER +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaType.VIDEO +import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia +import java.util.Locale + +data class Media( + override val id: Int, + override val url: String, + override val type: String, + override val caption: String = "" +) : RNMedia { + override fun toMap(): WritableMap = WritableNativeMap().apply { + putInt("id", id) + putString("url", url) + putString("type", type) + putString("caption", caption) + } + + companion object { + @JvmStatic + fun createRNMediaUsingMimeType( + id: Int, + url: String, + mimeType: String?, + caption: String? + ): Media { + val isMediaType = { mediaType: MediaType -> + mimeType?.startsWith(mediaType.name.toLowerCase(Locale.ROOT)) == true + } + val type = when { + isMediaType(IMAGE) -> IMAGE + isMediaType(VIDEO) -> VIDEO + else -> OTHER + }.name.toLowerCase(Locale.ROOT) + return Media(id, url, type, caption ?: "") + } + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/MediaOption.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/MediaOption.java new file mode 100644 index 00000000000000..188513dd5f9885 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/MediaOption.java @@ -0,0 +1,33 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeMap; + +public class MediaOption { + + private static final String KEY_VALUE = "value"; + private static final String KEY_LABEL = "label"; + + private String mId; + private String mName; + + public MediaOption(String id, String name) { + mId = id; + mName = name; + } + + public String getId() { + return mId; + } + + public String getName() { + return mName; + } + + public WritableMap toMap() { + WritableMap map = new WritableNativeMap(); + map.putString(KEY_VALUE, mId); + map.putString(KEY_LABEL, mName); + return map; + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/OkHttpHeaderInterceptor.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/OkHttpHeaderInterceptor.java new file mode 100644 index 00000000000000..16b8b734ef895b --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/OkHttpHeaderInterceptor.java @@ -0,0 +1,34 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode.OnAuthHeaderRequestedListener; + +import java.io.IOException; +import java.util.Map; + +import okhttp3.Interceptor; +import okhttp3.Request; +import okhttp3.Response; + +public class OkHttpHeaderInterceptor implements Interceptor { + private OnAuthHeaderRequestedListener mOnAuthHeaderRequestedListener; + + void setOnAuthHeaderRequestedListener(OnAuthHeaderRequestedListener onAuthHeaderRequestedListener) { + mOnAuthHeaderRequestedListener = onAuthHeaderRequestedListener; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request.Builder builder = chain.request().newBuilder(); + + Map authHeaders = mOnAuthHeaderRequestedListener != null + ? mOnAuthHeaderRequestedListener.onAuthHeaderRequested(chain.request().url().toString()) : null; + + if (authHeaders != null) { + for (Map.Entry entry : authHeaders.entrySet()) { + builder.addHeader(entry.getKey(), entry.getValue()); + } + } + + return chain.proceed(builder.build()); + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/RequestExecutor.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/RequestExecutor.java new file mode 100644 index 00000000000000..9a71acb904e762 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/RequestExecutor.java @@ -0,0 +1,9 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import android.os.Bundle; + +import androidx.core.util.Consumer; + +public interface RequestExecutor { + void performRequest(String path, Consumer onSuccess, Consumer onError); +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/UnsupportedBlock.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/UnsupportedBlock.java new file mode 100644 index 00000000000000..94a592a65b764d --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/UnsupportedBlock.java @@ -0,0 +1,26 @@ +package org.wordpress.mobile.WPAndroidGlue; + +public class UnsupportedBlock { + + private String mId; + private String mName; + private String mContent; + + public UnsupportedBlock(String id, String name, String content) { + mId = id; + mName = name; + mContent = content; + } + + public String getId() { + return mId; + } + + public String getName() { + return mName; + } + + public String getContent() { + return mContent; + } +} diff --git a/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java new file mode 100644 index 00000000000000..da4b680dc0c461 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/java/org/wordpress/mobile/WPAndroidGlue/WPAndroidGlueCode.java @@ -0,0 +1,889 @@ +package org.wordpress.mobile.WPAndroidGlue; + +import android.app.Activity; +import android.app.Application; +import android.content.Context; +import android.content.MutableContextWrapper; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.text.TextUtils; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout.LayoutParams; + +import androidx.annotation.Nullable; +import androidx.core.util.Consumer; +import androidx.fragment.app.Fragment; + +import com.brentvatne.react.ReactVideoPackage; +import com.facebook.hermes.reactexecutor.HermesExecutorFactory; +import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory; +import com.facebook.imagepipeline.core.ImagePipelineConfig; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactInstanceManagerBuilder; +import com.facebook.react.ReactPackage; +import com.facebook.react.ReactRootView; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.common.LifecycleState; +import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler; +import com.facebook.react.shell.MainPackageConfig; +import com.facebook.react.shell.MainReactPackage; +import com.facebook.soloader.SoLoader; +import com.horcrux.svg.SvgPackage; +import com.BV.LinearGradient.LinearGradientPackage; +import com.reactnativecommunity.slider.ReactSliderPackage; +import org.linusu.RNGetRandomValuesPackage; + +import org.wordpress.android.util.AppLog; +import org.wordpress.mobile.ReactNativeAztec.ReactAztecPackage; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.GutenbergUserEvent; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaSelectedCallback; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.MediaUploadEventEmitter; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent.ReplaceUnsupportedBlockCallback; +import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia; +import org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgePackage; + +import java.io.Serializable; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import okhttp3.OkHttpClient; + + +public class WPAndroidGlueCode { + private ReactRootView mReactRootView; + private ReactInstanceManager mReactInstanceManager; + private ReactContext mReactContext; + private RNReactNativeGutenbergBridgePackage mRnReactNativeGutenbergBridgePackage; + private MediaSelectedCallback mMediaSelectedCallback; + private DeferredEventEmitter mDeferredEventEmitter = new DeferredEventEmitter(); + private boolean mMediaPickedByUserOnBlock; + + /** + * Flag to append as siblings when allowMultipleSelection = false is not respected + */ + private boolean mAppendsMultipleSelectedToSiblingBlocks = false; + + private OnMediaLibraryButtonListener mOnMediaLibraryButtonListener; + private OnReattachQueryListener mOnReattachQueryListener; + private OnEditorMountListener mOnEditorMountListener; + private OnEditorAutosaveListener mOnEditorAutosaveListener; + private OnImageFullscreenPreviewListener mOnImageFullscreenPreviewListener; + private OnMediaEditorListener mOnMediaEditorListener; + private OnLogGutenbergUserEventListener mOnLogGutenbergUserEventListener; + private OnGutenbergDidRequestUnsupportedBlockFallbackListener mOnGutenbergDidRequestUnsupportedBlockFallbackListener; + private ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback; + private OnStarterPageTemplatesTooltipShownEventListener mOnStarterPageTemplatesTooltipShownListener; + private boolean mIsEditorMounted; + + private String mContentHtml = ""; + private boolean mContentInitialized; + private HashMap mMediaToAddAfterMounting = new HashMap<>(); + private String mTitle = ""; + private boolean mTitleInitialized; + private boolean mContentChanged; + private ReadableMap mContentInfo; + private boolean mShouldUpdateContent; + private CountDownLatch mGetContentCountDownLatch; + private WeakReference mLastFocusedView = null; + private RequestExecutor mRequestExecutor; + private AddMentionUtil mAddMentionUtil; + private @Nullable Bundle mEditorTheme = null; + + private static final String PROP_NAME_INITIAL_DATA = "initialData"; + private static final String PROP_NAME_INITIAL_TITLE = "initialTitle"; + private static final String PROP_NAME_INITIAL_HTML_MODE_ENABLED = "initialHtmlModeEnabled"; + private static final String PROP_NAME_POST_TYPE = "postType"; + private static final String PROP_NAME_LOCALE = "locale"; + private static final String PROP_NAME_TRANSLATIONS = "translations"; + public static final String PROP_NAME_CAPABILITIES = "capabilities"; + public static final String PROP_NAME_CAPABILITIES_MENTIONS = "mentions"; + private static final String PROP_NAME_COLORS = "colors"; + private static final String PROP_NAME_GRADIENTS = "gradients"; + + private static OkHttpHeaderInterceptor sAddCookiesInterceptor = new OkHttpHeaderInterceptor(); + private static OkHttpClient sOkHttpClient = new OkHttpClient.Builder().addInterceptor(sAddCookiesInterceptor).build(); + private boolean mIsDarkMode; + private Consumer mExceptionLogger; + private Consumer mBreadcrumbLogger; + + public void onCreate(Context context) { + SoLoader.init(context, /* native exopackage */ false); + } + + public boolean hasReactRootView() { + return mReactRootView != null; + } + + public boolean hasReactContext() { + return mReactContext != null; + } + + public boolean isContentChanged() { + return mContentChanged; + } + + public interface OnMediaLibraryButtonListener { + void onMediaLibraryImageButtonClicked(boolean allowMultipleSelection); + void onMediaLibraryVideoButtonClicked(boolean allowMultipleSelection); + void onMediaLibraryMediaButtonClicked(boolean allowMultipleSelection); + void onUploadPhotoButtonClicked(boolean allowMultipleSelection); + void onCapturePhotoButtonClicked(); + void onUploadVideoButtonClicked(boolean allowMultipleSelection); + void onUploadMediaButtonClicked(boolean allowMultipleSelection); + void onCaptureVideoButtonClicked(); + void onRetryUploadForMediaClicked(int mediaId); + void onCancelUploadForMediaClicked(int mediaId); + void onCancelUploadForMediaDueToDeletedBlock(int mediaId); + ArrayList onGetOtherMediaImageOptions(); + void onOtherMediaButtonClicked(String mediaSource, boolean allowMultipleSelection); + } + + public interface OnImageFullscreenPreviewListener { + void onImageFullscreenPreviewClicked(String mediaUrl); + } + + public interface OnReattachQueryListener { + void onQueryCurrentProgressForUploadingMedia(); + } + + public interface OnEditorMountListener { + void onEditorDidMount(ArrayList unsupportedBlockNames); + } + + public interface OnAuthHeaderRequestedListener { + Map onAuthHeaderRequested(String url); + } + + public interface OnEditorAutosaveListener { + void onEditorAutosave(); + } + + public interface OnMediaEditorListener { + void onMediaEditorClicked(String mediaUrl); + } + + public interface OnLogGutenbergUserEventListener { + void onGutenbergUserEvent(GutenbergUserEvent event, Map properties); + } + + public interface OnGutenbergDidRequestUnsupportedBlockFallbackListener { + void gutenbergDidRequestUnsupportedBlockFallback(UnsupportedBlock unsupportedBlock); + } + + public interface OnStarterPageTemplatesTooltipShownEventListener { + void onSetStarterPageTemplatesTooltipShown(boolean tooltipShown); + boolean onRequestStarterPageTemplatesTooltipShown(); + } + + public interface OnContentInfoReceivedListener { + void onContentInfoFailed(); + void onEditorNotReady(); + void onContentInfoReceived(HashMap contentInfo); + } + + public void mediaSelectionCancelled() { + mAppendsMultipleSelectedToSiblingBlocks = false; + } + + protected List getPackages() { + mRnReactNativeGutenbergBridgePackage = new RNReactNativeGutenbergBridgePackage(new GutenbergBridgeJS2Parent() { + @Override + public void responseHtml(String title, String html, boolean changed, ReadableMap contentInfo) { + mContentHtml = html; + mTitle = title; + // This code is called twice. When getTitle and getContent are called. + // Make sure mContentChanged has the correct value (true) if one of the call returned with changes. + mContentChanged = mContentChanged || changed; + + mContentInfo = contentInfo; + + // Gutenberg mobile sends us html response even without we asking for it so, check if the latch is there. + // This is probably an indication of a bug on the RN side of things though. + // Related: https://github.com/WordPress/gutenberg/pull/16260#issuecomment-506727286 + if (mGetContentCountDownLatch != null) { + mGetContentCountDownLatch.countDown(); + } + } + + @Override + public void requestMediaPickFromMediaLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) { + mMediaPickedByUserOnBlock = true; + mAppendsMultipleSelectedToSiblingBlocks = !allowMultipleSelection; + mMediaSelectedCallback = mediaSelectedCallback; + if (mediaType == MediaType.IMAGE) { + mOnMediaLibraryButtonListener.onMediaLibraryImageButtonClicked(allowMultipleSelection); + } else if (mediaType == MediaType.VIDEO) { + mOnMediaLibraryButtonListener.onMediaLibraryVideoButtonClicked(allowMultipleSelection); + } else if (mediaType == MediaType.MEDIA) { + mOnMediaLibraryButtonListener.onMediaLibraryMediaButtonClicked(allowMultipleSelection); + } + } + + @Override + public void requestMediaPickFromDeviceLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) { + mMediaPickedByUserOnBlock = true; + mAppendsMultipleSelectedToSiblingBlocks = false; + mMediaSelectedCallback = mediaSelectedCallback; + if (mediaType == MediaType.IMAGE) { + mOnMediaLibraryButtonListener.onUploadPhotoButtonClicked(allowMultipleSelection); + } else if (mediaType == MediaType.VIDEO) { + mOnMediaLibraryButtonListener.onUploadVideoButtonClicked(allowMultipleSelection); + } else if (mediaType == MediaType.MEDIA) { + mOnMediaLibraryButtonListener.onUploadMediaButtonClicked(allowMultipleSelection); + } + } + + @Override + public void requestMediaPickerFromDeviceCamera(MediaSelectedCallback mediaSelectedCallback, MediaType mediaType) { + mMediaPickedByUserOnBlock = true; + mAppendsMultipleSelectedToSiblingBlocks = false; + mMediaSelectedCallback = mediaSelectedCallback; + if (mediaType == MediaType.IMAGE) { + mOnMediaLibraryButtonListener.onCapturePhotoButtonClicked(); + } else if (mediaType == MediaType.VIDEO) { + mOnMediaLibraryButtonListener.onCaptureVideoButtonClicked(); + } + } + + @Override + public void requestMediaImport(String url, MediaSelectedCallback mediaSelectedCallback) { + // no op - we don't need to paste images on Android, but the method needs to exist + // to match the iOS counterpart + } + + @Override + public void mediaUploadSync(MediaSelectedCallback mediaSelectedCallback) { + mMediaSelectedCallback = mediaSelectedCallback; + mOnReattachQueryListener.onQueryCurrentProgressForUploadingMedia(); + } + + @Override + public void requestImageFailedRetryDialog(int mediaId) { + mOnMediaLibraryButtonListener.onRetryUploadForMediaClicked(mediaId); + } + + @Override + public void requestImageUploadCancelDialog(int mediaId) { + mOnMediaLibraryButtonListener.onCancelUploadForMediaClicked(mediaId); + } + + @Override + public void requestImageUploadCancel(int mediaId) { + mOnMediaLibraryButtonListener.onCancelUploadForMediaDueToDeletedBlock(mediaId); + } + + @Override + public void editorDidMount(ReadableArray unsupportedBlockNames) { + mOnEditorMountListener.onEditorDidMount(unsupportedBlockNames.toArrayList()); + mDeferredEventEmitter.setEmitter(mRnReactNativeGutenbergBridgePackage + .getRNReactNativeGutenbergBridgeModule()); + mIsEditorMounted = true; + if (TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mContentHtml)) { + setFocusOnTitle(); + // send signal to Editor to create a new image block and pass the media URL, start uploading, etc + // use mMediaUrlToAddAfterMounting + dispatchOneMediaToAddAtATimeIfAvailable(); + } + refreshEditorTheme(); + } + + @Override + public void editorDidAutosave() { + if (mOnEditorAutosaveListener != null) { + mOnEditorAutosaveListener.onEditorAutosave(); + } + } + + @Override + public void editorDidEmitLog(String message, LogLevel logLevel) { + switch (logLevel) { + case TRACE: + AppLog.d(AppLog.T.EDITOR, message); + break; + case INFO: + AppLog.i(AppLog.T.EDITOR, message); + break; + case WARN: + AppLog.w(AppLog.T.EDITOR, message); + break; + case ERROR: + AppLog.e(AppLog.T.EDITOR, message); + break; + } + } + + @Override + public void getOtherMediaPickerOptions(OtherMediaOptionsReceivedCallback otherMediaOptionsReceivedCallback, + MediaType mediaType) { + if (mediaType == MediaType.IMAGE || mediaType == MediaType.MEDIA) { + ArrayList otherMediaImageOptions = mOnMediaLibraryButtonListener.onGetOtherMediaImageOptions(); + otherMediaOptionsReceivedCallback.onOtherMediaOptionsReceived(otherMediaImageOptions); + } else { + otherMediaOptionsReceivedCallback.onOtherMediaOptionsReceived(new ArrayList()); + } + } + + @Override + public void requestMediaPickFrom(String mediaSource, + MediaSelectedCallback mediaSelectedCallback, + Boolean allowMultipleSelection) { + mMediaSelectedCallback = mediaSelectedCallback; + mMediaPickedByUserOnBlock = true; + mAppendsMultipleSelectedToSiblingBlocks = false; + mOnMediaLibraryButtonListener.onOtherMediaButtonClicked(mediaSource, allowMultipleSelection); + } + + @Override + public void performRequest(String pathFromJS, Consumer onSuccess, Consumer onError) { + mRequestExecutor.performRequest(pathFromJS, onSuccess, onError); + } + + @Override + public void requestImageFullscreenPreview(String mediaUrl) { + mOnImageFullscreenPreviewListener.onImageFullscreenPreviewClicked(mediaUrl); + } + + @Override + public void requestMediaEditor(MediaSelectedCallback mediaSelectedCallback, String mediaUrl) { + mMediaPickedByUserOnBlock = true; + mMediaSelectedCallback = mediaSelectedCallback; + mOnMediaEditorListener.onMediaEditorClicked(mediaUrl); + } + + @Override + public void logUserEvent(GutenbergUserEvent event, ReadableMap eventProperties) { + mOnLogGutenbergUserEventListener.onGutenbergUserEvent(event, eventProperties.toHashMap()); + } + + @Override + public void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback replaceUnsupportedBlockCallback, + String content, + String blockId, + String blockName) { + mReplaceUnsupportedBlockCallback = replaceUnsupportedBlockCallback; + mOnGutenbergDidRequestUnsupportedBlockFallbackListener. + gutenbergDidRequestUnsupportedBlockFallback(new UnsupportedBlock(blockId, blockName, content)); + } + + @Override + public void onAddMention(Consumer onSuccess) { + mAddMentionUtil.getMention(onSuccess); + } + + @Override + public void setStarterPageTemplatesTooltipShown(boolean showTooltip) { + mOnStarterPageTemplatesTooltipShownListener.onSetStarterPageTemplatesTooltipShown(showTooltip); + } + + @Override + public void requestStarterPageTemplatesTooltipShown(StarterPageTemplatesTooltipShownCallback starterPageTemplatesTooltipShownCallback) { + boolean tooltipShown = mOnStarterPageTemplatesTooltipShownListener.onRequestStarterPageTemplatesTooltipShown(); + starterPageTemplatesTooltipShownCallback.onRequestStarterPageTemplatesTooltipShown(tooltipShown); + } + }, mIsDarkMode); + + return Arrays.asList( + new MainReactPackage(getMainPackageConfig(getImagePipelineConfig(sOkHttpClient))), + new SvgPackage(), + new LinearGradientPackage(), + new ReactAztecPackage(mExceptionLogger, mBreadcrumbLogger), + new ReactVideoPackage(), + new ReactSliderPackage(), + new RNGetRandomValuesPackage(), + mRnReactNativeGutenbergBridgePackage); + } + + private MainPackageConfig getMainPackageConfig(ImagePipelineConfig imagePipelineConfig) { + return new MainPackageConfig.Builder().setFrescoConfig(imagePipelineConfig).build(); + } + + private ImagePipelineConfig getImagePipelineConfig(OkHttpClient client) { + return OkHttpImagePipelineConfigFactory + .newBuilder(mReactRootView.getContext(), client).build(); + } + + public void onCreateView(Context initContext, + boolean htmlModeEnabled, + Application application, + boolean isDebug, + boolean buildGutenbergFromSource, + String postType, + boolean isNewPost, + String localeString, + Bundle translations, + int colorBackground, + boolean isDarkMode, + Consumer exceptionLogger, + Consumer breadcrumbLogger, + @Nullable Boolean isSiteUsingWpComRestApi, + @Nullable Bundle editorTheme) { + mIsDarkMode = isDarkMode; + mExceptionLogger = exceptionLogger; + mBreadcrumbLogger = breadcrumbLogger; + mReactRootView = new ReactRootView(new MutableContextWrapper(initContext)); + mReactRootView.setBackgroundColor(colorBackground); + + ReactInstanceManagerBuilder builder = + ReactInstanceManager.builder() + .setApplication(application) + .setJSMainModulePath("index") + .addPackages(getPackages()) + .setUseDeveloperSupport(isDebug) + .setJavaScriptExecutorFactory(new HermesExecutorFactory()) + .setInitialLifecycleState(LifecycleState.BEFORE_CREATE); + if (!buildGutenbergFromSource) { + builder.setBundleAssetName("index.android.bundle"); + } + mReactInstanceManager = builder.build(); + mReactInstanceManager.addReactInstanceEventListener(context -> { + mReactContext = context; + }); + Bundle initialProps = mReactRootView.getAppProperties(); + if (initialProps == null) { + initialProps = new Bundle(); + } + initialProps.putString(PROP_NAME_INITIAL_DATA, ""); + initialProps.putString(PROP_NAME_INITIAL_TITLE, ""); + initialProps.putBoolean(PROP_NAME_INITIAL_HTML_MODE_ENABLED, htmlModeEnabled); + initialProps.putString(PROP_NAME_POST_TYPE, postType); + initialProps.putString(PROP_NAME_LOCALE, localeString); + initialProps.putBundle(PROP_NAME_TRANSLATIONS, translations); + + Bundle capabilities = new Bundle(); + if (isSiteUsingWpComRestApi != null) { + capabilities.putBoolean(PROP_NAME_CAPABILITIES_MENTIONS, isSiteUsingWpComRestApi); + } + initialProps.putBundle(PROP_NAME_CAPABILITIES, capabilities); + + Serializable colors = editorTheme != null ? editorTheme.getSerializable(PROP_NAME_COLORS) : null; + if (colors != null) { + initialProps.putSerializable(PROP_NAME_COLORS, colors); + } + + Serializable gradients = editorTheme != null ? editorTheme.getSerializable(PROP_NAME_GRADIENTS) : null; + if (gradients != null) { + initialProps.putSerializable(PROP_NAME_GRADIENTS, gradients); + } + + // The string here (e.g. "MyReactNativeApp") has to match + // the string in AppRegistry.registerComponent() in index.js + mReactRootView.setAppProperties(initialProps); + } + + public void attachToContainer(ViewGroup viewGroup, + OnMediaLibraryButtonListener onMediaLibraryButtonListener, + OnReattachQueryListener onReattachQueryListener, + OnEditorMountListener onEditorMountListener, + OnEditorAutosaveListener onEditorAutosaveListener, + OnAuthHeaderRequestedListener onAuthHeaderRequestedListener, + RequestExecutor fetchExecutor, + OnImageFullscreenPreviewListener onImageFullscreenPreviewListener, + OnMediaEditorListener onMediaEditorListener, + OnLogGutenbergUserEventListener onLogGutenbergUserEventListener, + OnGutenbergDidRequestUnsupportedBlockFallbackListener onGutenbergDidRequestUnsupportedBlockFallbackListener, + AddMentionUtil addMentionUtil, + OnStarterPageTemplatesTooltipShownEventListener onStarterPageTemplatesTooltipListener, + boolean isDarkMode) { + MutableContextWrapper contextWrapper = (MutableContextWrapper) mReactRootView.getContext(); + contextWrapper.setBaseContext(viewGroup.getContext()); + + mOnMediaLibraryButtonListener = onMediaLibraryButtonListener; + mOnReattachQueryListener = onReattachQueryListener; + mOnEditorMountListener = onEditorMountListener; + mOnEditorAutosaveListener = onEditorAutosaveListener; + mRequestExecutor = fetchExecutor; + mOnImageFullscreenPreviewListener = onImageFullscreenPreviewListener; + mOnMediaEditorListener = onMediaEditorListener; + mOnLogGutenbergUserEventListener = onLogGutenbergUserEventListener; + mOnGutenbergDidRequestUnsupportedBlockFallbackListener = onGutenbergDidRequestUnsupportedBlockFallbackListener; + mAddMentionUtil = addMentionUtil; + mOnStarterPageTemplatesTooltipShownListener = onStarterPageTemplatesTooltipListener; + + sAddCookiesInterceptor.setOnAuthHeaderRequestedListener(onAuthHeaderRequestedListener); + + if (mReactRootView.getParent() != null) { + ((ViewGroup) mReactRootView.getParent()).removeView(mReactRootView); + } + + viewGroup.addView(mReactRootView, 0, + new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); + + if (mReactContext != null) { + setPreferredColorScheme(isDarkMode); + } + + refocus(); + } + + private void refocus() { + if (mLastFocusedView != null) { + // schedule a request for focus + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override public void run() { + // Check if View reference is still alive and in the view hierarchy + if (mLastFocusedView != null + && mLastFocusedView.get() != null + && mLastFocusedView.get().getParent() != null) { + // request focus to the last focused child + mLastFocusedView.get().requestFocus(); + } + } + }); + } + } + + public void onPause(Activity activity) { + if (mReactInstanceManager != null) { + // get the focused view so we re-focus it later if needed. WeakReference so we don't leak it. + mLastFocusedView = new WeakReference<>(mReactRootView.findFocus()); + + mReactInstanceManager.onHostPause(activity); + } + } + + public void onResume(final Fragment fragment, final Activity activity) { + if (mReactInstanceManager != null) { + mReactInstanceManager.onHostResume(activity, + new DefaultHardwareBackBtnHandler() { + @Override + public void invokeDefaultOnBackPressed() { + if (fragment.isAdded()) { + activity.onBackPressed(); + } + } + }); + } + } + + public void onDetach(Activity activity) { + mReactInstanceManager.onHostDestroy(activity); + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().notifyModalClosed(); + } + + public void onDestroy(Activity activity) { + if (mReactRootView != null) { + mReactRootView.unmountReactApplication(); + mReactRootView = null; + sAddCookiesInterceptor.setOnAuthHeaderRequestedListener(null); + } + if (mReactInstanceManager != null) { + // onDestroy may be called on a ReactFragment after another ReactFragment has been + // created and resumed with the same React Instance Manager. Make sure we only clean up + // host's React Instance Manager if no other React Fragment is actively using it. + if (mReactInstanceManager.getLifecycleState() != LifecycleState.RESUMED) { + mReactInstanceManager.onHostDestroy(activity); + } + } + } + + public void showDevOptionsDialog() { + mReactInstanceManager.showDevOptionsDialog(); + } + + public void setFocusOnTitle() { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().setFocusOnTitleInJS(); + } + + public void appendNewMediaBlock(int mediaId, String mediaUri, String mediaType) { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule() + .appendNewMediaBlock(mediaId, mediaUri, mediaType); + } + + public void setPreferredColorScheme(boolean isDarkMode) { + if (mIsDarkMode != isDarkMode) { + mIsDarkMode = isDarkMode; + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule() + .setPreferredColorScheme(isDarkMode); + } + } + + public void updateTheme(@Nullable Bundle editorTheme) { + if (mIsEditorMounted) { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule() + .updateTheme(editorTheme); + } else { + // Editor hasn't mounted yet. Save theme and load once editor loads + AppLog.d(AppLog.T.EDITOR, "Editor theme not applied reason: Editor not mounted"); + mEditorTheme = editorTheme; + } + } + + private void refreshEditorTheme() { + if (mEditorTheme != null) { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule() + .updateTheme(mEditorTheme); + mEditorTheme = null; + } + } + + public void setTitle(String title) { + mTitleInitialized = true; + mTitle = title; + setContent(mTitle, mContentHtml); + } + + public void setContent(String postContent) { + mContentInitialized = true; + mContentHtml = postContent; + setContent(mTitle, mContentHtml); + } + + public boolean hasReceivedInitialTitleAndContent() { + return mTitleInitialized && mContentInitialized; + } + + private void setContent(String title, String postContent) { + if (mReactRootView == null) { + return; + } + + // wait for both title and content to have been set at least once. Legacy editor implementation had the two as + // separate calls but, we only want a single call to correctly boot the GB editor + if (!hasReceivedInitialTitleAndContent()) { + return; + } + + // Content can be set directly to RootView only once (per RootView instance) + // because we don't want to bootstrap the whole Gutenberg state. + // Otherwise it should be done through module interface + if (mShouldUpdateContent) { + updateContent(title, postContent); + } else { + mShouldUpdateContent = true; + initContent(title, postContent); + } + } + + private void initContent(String title, String content) { + Bundle appProps = mReactRootView.getAppProperties(); + if (appProps == null) { + appProps = new Bundle(); + } + if (content != null) { + appProps.putString(PROP_NAME_INITIAL_DATA, content); + mContentHtml = content; + } + if (title != null) { + appProps.putString(PROP_NAME_INITIAL_TITLE, title); + mTitle = title; + } + mReactRootView.startReactApplication(mReactInstanceManager, "gutenberg", appProps); + } + + private void updateContent(String title, String content) { + if (content != null) { + mContentHtml = content; + } + if (title != null) { + mTitle = title; + } + if (mReactContext != null) { + if (content != null) { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().setHtmlInJS(content); + } + if (title != null) { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().setTitleInJS(title); + } + } + } + + public interface OnGetContentTimeout { + void onGetContentTimeout(InterruptedException ie); + } + + public CharSequence getContent(CharSequence originalContent, OnGetContentTimeout onGetContentTimeout) { + if (mReactContext != null) { + mGetContentCountDownLatch = new CountDownLatch(1); + + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().getHtmlFromJS(); + + try { + mGetContentCountDownLatch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + onGetContentTimeout.onGetContentTimeout(ie); + } + + return mContentChanged ? (mContentHtml == null ? "" : mContentHtml) : originalContent; + } else { + // TODO: Add app logging here + } + + return originalContent; + } + + public CharSequence getTitle(OnGetContentTimeout onGetContentTimeout) { + if (mReactContext != null) { + mGetContentCountDownLatch = new CountDownLatch(1); + + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().getHtmlFromJS(); + + try { + mGetContentCountDownLatch.await(10, TimeUnit.SECONDS); + } catch (InterruptedException ie) { + onGetContentTimeout.onGetContentTimeout(ie); + } + + return mTitle == null ? "" : mTitle; + } else { + // TODO: Add app logging here + } + + return ""; + } + + public boolean triggerGetContentInfo(OnContentInfoReceivedListener onContentInfoReceivedListener) { + if (mReactContext != null && (mGetContentCountDownLatch == null || mGetContentCountDownLatch.getCount() == 0)) { + if (!mIsEditorMounted) { + onContentInfoReceivedListener.onEditorNotReady(); + return false; + } + + mGetContentCountDownLatch = new CountDownLatch(1); + + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().getHtmlFromJS(); + + new Thread(new Runnable() { + @Override public void run() { + try { + mGetContentCountDownLatch.await(5, TimeUnit.SECONDS); + if (mContentInfo == null) { + onContentInfoReceivedListener.onContentInfoFailed(); + } else { + onContentInfoReceivedListener.onContentInfoReceived(mContentInfo.toHashMap()); + } + } catch (InterruptedException ie) { + onContentInfoReceivedListener.onContentInfoFailed(); + } + } + }).start(); + + return true; + } + + return false; + } + + private String getMediaType(final boolean isVideo) { + return isVideo ? "video" : "image"; + } + + public void toggleEditorMode(boolean htmlModeEnabled) { + // Turn off hardware acceleration for Oreo + // see https://github.com/wordpress-mobile/gutenberg-mobile/issues/1268#issuecomment-535887390 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && Build.VERSION.SDK_INT <= Build.VERSION_CODES.O_MR1) { + if (htmlModeEnabled) { + mReactRootView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); + } else { + mReactRootView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + } + } + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().toggleEditorMode(); + } + + public void appendMediaFiles(ArrayList mediaList) { + if (isMediaSelectedCallbackRegistered() && mMediaPickedByUserOnBlock) { + mMediaPickedByUserOnBlock = false; + List rnMediaList = new ArrayList<>(); + + // We have special handling here for the image block when the user selects multiple items from the + // WordPress Media Library: We pass the first image to the callback, and the remaining images will be + // appended as blocks via sendOrDeferAppendMediaSignal + // + // All other media selection results should be passed to the callback at once (as a collection) + // + // Note: In the future, after image block <-> gallery block transforms have been implemented, this special + // handling will no longer be necessary + + if (mAppendsMultipleSelectedToSiblingBlocks && 1 < mediaList.size()) { + rnMediaList.add(mediaList.get(0)); + mMediaSelectedCallback.onMediaFileSelected(rnMediaList); + + for (Media mediaToAppend : mediaList.subList(1, mediaList.size())) { + sendOrDeferAppendMediaSignal(mediaToAppend); + } + } else { + rnMediaList.addAll(mediaList); + mMediaSelectedCallback.onMediaFileSelected(rnMediaList); + } + } else { + // This case is for media that is shared from the device + for (Media mediaToAppend : mediaList) { + sendOrDeferAppendMediaSignal(mediaToAppend); + } + } + + mAppendsMultipleSelectedToSiblingBlocks = false; + } + + private void sendOrDeferAppendMediaSignal(Media media) { + // if editor is mounted, let's append the media file + if (mIsEditorMounted) { + if (!TextUtils.isEmpty(media.getUrl()) && media.getId() > 0) { + // send signal to JS + appendNewMediaBlock(media.getId(), media.getUrl(), media.getType()); + } + } else { + // save the URL, we'll add it once Editor is mounted + synchronized (WPAndroidGlueCode.this) { + mMediaToAddAfterMounting.put(media.getId(), media); + } + } + } + + private synchronized void dispatchOneMediaToAddAtATimeIfAvailable() { + Iterator> iter = mMediaToAddAfterMounting.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + Integer mediaId = entry.getKey(); + Media media = entry.getValue(); + if (!TextUtils.isEmpty(media.getUrl()) && mediaId > 0) { + // send signal to JS + appendNewMediaBlock(mediaId, media.getUrl(), media.getType()); + iter.remove(); + } + } + } + + public void mediaFileUploadProgress(final int mediaId, final float progress) { + mDeferredEventEmitter.onMediaFileUploadProgress(mediaId, progress); + } + + public void mediaFileUploadFailed(final int mediaId) { + mDeferredEventEmitter.onMediaFileUploadFailed(mediaId); + } + + public void mediaFileUploadSucceeded(final int mediaId, final String mediaUrl, final int serverMediaId) { + mDeferredEventEmitter.onMediaFileUploadSucceeded(mediaId, mediaUrl, serverMediaId); + } + + public void clearMediaFileURL(final int mediaId) { + mDeferredEventEmitter.onUploadMediaFileClear(mediaId); + } + + public void replaceUnsupportedBlock(String content, String blockId) { + if (mReplaceUnsupportedBlockCallback != null) { + mReplaceUnsupportedBlockCallback.replaceUnsupportedBlock(content, blockId); + mReplaceUnsupportedBlockCallback = null; + } + } + + private boolean isMediaSelectedCallbackRegistered() { + return mMediaSelectedCallback != null; + } +} + diff --git a/packages/react-native-bridge/android/src/main/res/drawable/ic_check_24px.xml b/packages/react-native-bridge/android/src/main/res/drawable/ic_check_24px.xml new file mode 100644 index 00000000000000..4c1cdcec4b5162 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/drawable/ic_check_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/packages/react-native-bridge/android/src/main/res/drawable/ic_close_24px.xml b/packages/react-native-bridge/android/src/main/res/drawable/ic_close_24px.xml new file mode 100644 index 00000000000000..a922efedc06ebb --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/drawable/ic_close_24px.xml @@ -0,0 +1,9 @@ + + + diff --git a/packages/react-native-bridge/android/src/main/res/drawable/progressbar_horizontal.xml b/packages/react-native-bridge/android/src/main/res/drawable/progressbar_horizontal.xml new file mode 100644 index 00000000000000..2ac3281ad5298b --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/drawable/progressbar_horizontal.xml @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/packages/react-native-bridge/android/src/main/res/layout/activity_gutenberg_web_view.xml b/packages/react-native-bridge/android/src/main/res/layout/activity_gutenberg_web_view.xml new file mode 100644 index 00000000000000..c8bf58920ce36d --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/layout/activity_gutenberg_web_view.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/packages/react-native-bridge/android/src/main/res/menu/menu_gutenberg_webview.xml b/packages/react-native-bridge/android/src/main/res/menu/menu_gutenberg_webview.xml new file mode 100644 index 00000000000000..ce18085883bc16 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/menu/menu_gutenberg_webview.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/packages/react-native-bridge/android/src/main/res/values-night/colors.xml b/packages/react-native-bridge/android/src/main/res/values-night/colors.xml new file mode 100644 index 00000000000000..261cd641f90f2b --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/values-night/colors.xml @@ -0,0 +1,6 @@ + + + + #222222 + + \ No newline at end of file diff --git a/packages/react-native-bridge/android/src/main/res/values/colors.xml b/packages/react-native-bridge/android/src/main/res/values/colors.xml new file mode 100644 index 00000000000000..787f8fa6780c21 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/values/colors.xml @@ -0,0 +1,6 @@ + + + + #006088 + + \ No newline at end of file diff --git a/packages/react-native-bridge/android/src/main/res/values/dimens.xml b/packages/react-native-bridge/android/src/main/res/values/dimens.xml new file mode 100644 index 00000000000000..55b8f63169a804 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/values/dimens.xml @@ -0,0 +1,10 @@ + + + + 3dp + + 56dp + 72dp + 0dp + + \ No newline at end of file diff --git a/packages/react-native-bridge/android/src/main/res/values/strings.xml b/packages/react-native-bridge/android/src/main/res/values/strings.xml new file mode 100644 index 00000000000000..36c2e8cf1f93ec --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/values/strings.xml @@ -0,0 +1,6 @@ + + + + Save + + \ No newline at end of file diff --git a/packages/react-native-bridge/android/src/main/res/values/styles.xml b/packages/react-native-bridge/android/src/main/res/values/styles.xml new file mode 100644 index 00000000000000..f58a9c77ef3695 --- /dev/null +++ b/packages/react-native-bridge/android/src/main/res/values/styles.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-debug.aar b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-debug.aar new file mode 100644 index 00000000000000..3a2ad8cf05a57c Binary files /dev/null and b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-debug.aar differ diff --git a/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-release.aar b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-release.aar new file mode 100644 index 00000000000000..5256ff80d55df3 Binary files /dev/null and b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-cppruntime-release.aar differ diff --git a/packages/react-native-bridge/android/vendor/hermes-engine/hermes-debug.aar b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-debug.aar new file mode 100644 index 00000000000000..74bd4ae5cba723 Binary files /dev/null and b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-debug.aar differ diff --git a/packages/react-native-bridge/android/vendor/hermes-engine/hermes-release.aar b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-release.aar new file mode 100644 index 00000000000000..cc208310ea2d54 Binary files /dev/null and b/packages/react-native-bridge/android/vendor/hermes-engine/hermes-release.aar differ diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js b/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js new file mode 100644 index 00000000000000..fb4b14eebcf475 --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/content-functions.js @@ -0,0 +1,31 @@ +window.blockEditorSelect = + window.wp.data.select( 'core/block-editor' ) || + window.wp.data.select( 'core/editor' ); // For WP v5.0 and v5.1 + +window.blockEditorDispatch = + window.wp.data.dispatch( 'core/block-editor' ) || + window.wp.data.dispatch( 'core/editor' ); // For WP v5.0 and v5.1 + +window.getHTMLPostContent = () => { + const blocks = window.blockEditorSelect.getBlocks(); + const HTML = window.wp.blocks.serialize( blocks ); + // Check if platform is iOS + if ( window.webkit ) { + window.webkit.messageHandlers.htmlPostContent.postMessage( HTML ); + // Otherwise it\'s Android + } else { + window.wpwebkit.postMessage( HTML ); + } +}; + +window.insertBlock = ( blockHTML ) => { + // Setup the editor with the inserted block + const post = window.wp.data.select( 'core/editor' ).getCurrentPost(); + window.wp.data + .dispatch( 'core/editor' ) + .setupEditor( post, { content: blockHTML } ); + + // Select the first block + const clientId = window.blockEditorSelect.getBlocks()[ 0 ].clientId; + window.blockEditorDispatch.selectBlock( clientId ); +}; diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css new file mode 100644 index 00000000000000..42c524903c4e06 --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/editor-style-overrides.css @@ -0,0 +1,75 @@ +/* Remove Post Title */ +#post-title-0 { + display: none; +} + +/* Remove default block appender at the end of the post */ +.block-list-appender { + display: none; +} + +.edit-post-visual-editor__post-title-wrapper { + display: none; +} + +/* Remove default block appender at the end of the post (WP v5.0~v5.1) */ +.editor-default-block-appender { + display: none; +} + +/* + Hiddes the top bar header by setting its height to 0 + We can\'t remove it since the block toolbar is a child of it. + */ +.edit-post-header { + height: 0px; + padding: 0px; + overflow: hidden; +} + +/* Move the block toolbar to the top */ +.edit-post-header-toolbar__block-toolbar { + top: 0px; +} + +.interface-interface-skeleton { + top: 0px; +} + +/* + Moves the whole editor to the top. + There was an extra top margin after removing the WP Admin bar. + */ +.block-editor-editor-skeleton { + top: 0px; +} + +/* Remove metaboxes from Self-Hosted sites */ +.edit-post-layout__metaboxes { + display: none; +} + +/* Remove tabs from sidebar panel, leaving the \'x\' button */ +.edit-post-sidebar__panel-tabs { + display: none; +} + +/* Remove \'(no-title)\' string from sidebar header */ +.edit-post-sidebar-header__title { + display: none; +} + +/* Move \'x\' close button to the end on sidebar header */ +.edit-post-sidebar-header__small { + justify-content: flex-end; +} + +/* Remove all buttons from the component menu group inside \'...\' button in block toolbar */ +.components-menu-group > div > button:not(:first-child) { + display: none; +} + +/* Remove \'delete block\' button inside \'...\' button in block toolbar */ +.components-dropdown-menu__menu > div:not(:first-child) { + display: none; +} diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js b/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js new file mode 100644 index 00000000000000..4a85d1831bd051 --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/inject-css.js @@ -0,0 +1,16 @@ +const injectCss = ` +window.injectCss = (css) => { + const style = document.createElement('style'); + style.innerHTML = css; + style.type = 'text/css'; + document.head.appendChild(style); +} +`; + +const script = document.createElement( 'script' ); +script.innerText = injectCss; +script.type = 'text/javascript'; +document.head.appendChild( script ); +// We need to return a string or null, otherwise executing this script will error. +// eslint-disable-next-line no-unused-expressions +( 'CSS injection function ready' ); diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/insert-block.js b/packages/react-native-bridge/common/gutenberg-web-single-block/insert-block.js new file mode 100644 index 00000000000000..470b0b73211a5f --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/insert-block.js @@ -0,0 +1 @@ +window.insertBlock( `%@` ); diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/local-storage-overrides.json b/packages/react-native-bridge/common/gutenberg-web-single-block/local-storage-overrides.json new file mode 100644 index 00000000000000..431a973b906c36 --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/local-storage-overrides.json @@ -0,0 +1,31 @@ +{ + "core/edit-post": { + "preferences": { + "isGeneralSidebarDismissed": true, + "features": { + "fixedToolbar": false, + "showInserterHelpPanel": false, + "fullscreenMode": true, + "welcomeGuide": false + }, + "editorMode": "visual", + "pinnedPluginItems": { + + }, + "hiddenBlockTypes": [ + + ], + "preferredStyleVariations": { + + } + } + }, + "core/nux": { + "preferences": { + "areTipsEnabled": false, + "dismissedTips": { + + } + } + } +} diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/prevent-autosaves.js b/packages/react-native-bridge/common/gutenberg-web-single-block/prevent-autosaves.js new file mode 100644 index 00000000000000..6bbd0179ebaa98 --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/prevent-autosaves.js @@ -0,0 +1,6 @@ +window.setTimeout( () => { + // Delaying autosaves we avoid creating drafts to remote + const settings = window.wp.data.select( 'core/editor' ).getEditorSettings(); + settings.autosaveInterval = 60 * 60 * 24 * 7; //Let's wait a week for it to autosave. + window.wp.data.dispatch( 'core/editor' ).updateEditorSettings( settings ); +}, 0 ); diff --git a/packages/react-native-bridge/common/gutenberg-web-single-block/wp-bar-override.css b/packages/react-native-bridge/common/gutenberg-web-single-block/wp-bar-override.css new file mode 100644 index 00000000000000..13ff045184f15f --- /dev/null +++ b/packages/react-native-bridge/common/gutenberg-web-single-block/wp-bar-override.css @@ -0,0 +1,11 @@ +#wpbody { + padding-top: 0px; +} + +#wp-toolbar { + display: none; +} + +#wpadminbar { + display: none; +} diff --git a/packages/react-native-bridge/index.js b/packages/react-native-bridge/index.js new file mode 100644 index 00000000000000..58372450cde450 --- /dev/null +++ b/packages/react-native-bridge/index.js @@ -0,0 +1,223 @@ +/** + * External dependencies + */ +import { NativeModules, NativeEventEmitter, Platform } from 'react-native'; + +const { RNReactNativeGutenbergBridge } = NativeModules; +const isIOS = Platform.OS === 'ios'; +const isAndroid = Platform.OS === 'android'; + +const gutenbergBridgeEvents = new NativeEventEmitter( + RNReactNativeGutenbergBridge +); + +export const { isInitialColorSchemeDark } = RNReactNativeGutenbergBridge; + +export const mediaSources = { + deviceLibrary: 'DEVICE_MEDIA_LIBRARY', + deviceCamera: 'DEVICE_CAMERA', + siteMediaLibrary: 'SITE_MEDIA_LIBRARY', +}; + +export const userEvents = { + editorSessionTemplateApply: 'editor_session_template_apply', + editorSessionTemplatePreview: 'editor_session_template_preview', +}; + +// Console polyfill from react-native + +export function nativeLoggingHook( message, logLevel ) { + RNReactNativeGutenbergBridge.editorDidEmitLog( message, logLevel ); +} + +// Send messages + +export function sendNativeEditorDidLayout() { + // For now, this is only needed on iOS to solve layout issues with the toolbar. + // If this become necessary on Android in the future, we can try to build a registration API from Native + // to register messages it wants to receive, similar to the Native -> JS messages listener system. + if ( isIOS ) { + RNReactNativeGutenbergBridge.editorDidLayout(); + } +} + +// Register listeners + +export function subscribeParentGetHtml( callback ) { + return gutenbergBridgeEvents.addListener( 'requestGetHtml', callback ); +} + +export function subscribeParentToggleHTMLMode( callback ) { + return gutenbergBridgeEvents.addListener( 'toggleHTMLMode', callback ); +} + +export function subscribeSetFocusOnTitle( callback ) { + return gutenbergBridgeEvents.addListener( 'setFocusOnTitle', callback ); +} + +export function subscribeSetTitle( callback ) { + return gutenbergBridgeEvents.addListener( 'setTitle', callback ); +} + +export function subscribeUpdateHtml( callback ) { + return gutenbergBridgeEvents.addListener( 'updateHtml', callback ); +} + +export function subscribeMediaUpload( callback ) { + return gutenbergBridgeEvents.addListener( 'mediaUpload', callback ); +} + +export function subscribeMediaAppend( callback ) { + return gutenbergBridgeEvents.addListener( 'mediaAppend', callback ); +} + +export function subscribeAndroidModalClosed( callback ) { + return isAndroid + ? gutenbergBridgeEvents.addListener( 'notifyModalClosed', callback ) + : undefined; +} + +export function subscribeUpdateTheme( callback ) { + return gutenbergBridgeEvents.addListener( 'updateTheme', callback ); +} + +export function subscribePreferredColorScheme( callback ) { + return gutenbergBridgeEvents.addListener( + 'preferredColorScheme', + callback + ); +} + +/** + * @callback FnReplaceBlockCompletion + * @param {string} html the HTML to replace the block. + * @param {string} clientId the clientId of the block to be replaced. + */ + +/** + * Subscribe a listener to replace a single block. + * + * @param {FnReplaceBlockCompletion} callback the completion callback. + */ +export function subscribeReplaceBlock( callback ) { + return gutenbergBridgeEvents.addListener( 'replaceBlock', callback ); +} + +/** + * Request media picker for the given media source. + * + * Kinds of media source can be device library, camera, etc. + * + * @param {string} source The media source to request media from. + * @param {Array} filter Array of media types to filter the media to select. + * @param {boolean} multiple Is multiple selection allowed? + * @param {Function} callback RN Callback function to be called with the selected media objects. + */ +export function requestMediaPicker( source, filter, multiple, callback ) { + RNReactNativeGutenbergBridge.requestMediaPickFrom( + source, + filter, + multiple, + callback + ); +} + +/** + * Request to render an unsuported block. + * + * A way to show unsupported blocks to the user is to render it on a web view. + * + * @param {string} htmlContent Raw html content of the block. + * @param {string} blockClientId the clientId of the block. + * @param {string} blockName the user-facing, localized block name. + */ +export function requestUnsupportedBlockFallback( + htmlContent, + blockClientId, + blockName +) { + RNReactNativeGutenbergBridge.requestUnsupportedBlockFallback( + htmlContent, + blockClientId, + blockName + ); +} + +export function requestMediaImport( url, callback ) { + return RNReactNativeGutenbergBridge.requestMediaImport( url, callback ); +} + +export function mediaUploadSync() { + return RNReactNativeGutenbergBridge.mediaUploadSync(); +} + +export function requestImageFailedRetryDialog( mediaId ) { + return RNReactNativeGutenbergBridge.requestImageFailedRetryDialog( + mediaId + ); +} + +export function requestImageUploadCancelDialog( mediaId ) { + return RNReactNativeGutenbergBridge.requestImageUploadCancelDialog( + mediaId + ); +} + +export function requestImageUploadCancel( mediaId ) { + return RNReactNativeGutenbergBridge.requestImageUploadCancel( mediaId ); +} + +export function getOtherMediaOptions( filter, callback ) { + return RNReactNativeGutenbergBridge.getOtherMediaOptions( + filter, + callback + ); +} + +export function requestImageFullscreenPreview( + currentImageUrl, + originalImageUrl +) { + if ( isIOS ) { + return RNReactNativeGutenbergBridge.requestImageFullscreenPreview( + currentImageUrl, + originalImageUrl + ); + } + return RNReactNativeGutenbergBridge.requestImageFullscreenPreview( + originalImageUrl || currentImageUrl + ); +} + +export function requestMediaEditor( mediaUrl, callback ) { + return RNReactNativeGutenbergBridge.requestMediaEditor( + mediaUrl, + callback + ); +} + +export function fetchRequest( path ) { + return RNReactNativeGutenbergBridge.fetchRequest( path ); +} + +export function logUserEvent( event, properties ) { + return RNReactNativeGutenbergBridge.logUserEvent( event, properties ); +} + +export function addMention() { + return RNReactNativeGutenbergBridge.addMention(); +} + +export function requestStarterPageTemplatesTooltipShown( callback ) { + return RNReactNativeGutenbergBridge.requestStarterPageTemplatesTooltipShown( + callback + ); +} + +export function setStarterPageTemplatesTooltipShown( tooltipShown ) { + return RNReactNativeGutenbergBridge.setStarterPageTemplatesTooltipShown( + tooltipShown + ); +} + +export default RNReactNativeGutenbergBridge; diff --git a/packages/react-native-bridge/ios/Gutenberg.swift b/packages/react-native-bridge/ios/Gutenberg.swift new file mode 100644 index 00000000000000..7a3fa9a0fca20f --- /dev/null +++ b/packages/react-native-bridge/ios/Gutenberg.swift @@ -0,0 +1,230 @@ +import UIKit +import Aztec + +// IMPORTANT: if you're seeing a warning with this import, keep in mind it's marked as a Swift +// bug. I wasn't able to get any of the workarounds to work. +// +// Ref: https://bugs.swift.org/browse/SR-3801 +import RNTAztecView + +@objc +public class Gutenberg: NSObject { + + private var extraModules: [RCTBridgeModule]; + + public lazy var rootView: UIView = { + return RCTRootView(bridge: bridge, moduleName: "gutenberg", initialProperties: initialProps) + }() + + public var delegate: GutenbergBridgeDelegate? { + get { + return bridgeModule.delegate + } + set { + bridgeModule.delegate = newValue + } + } + + public var isLoaded: Bool { + return !bridge.isLoading + } + + public var logThreshold: LogLevel { + get { + return LogLevel(RCTGetLogThreshold()) + } + set { + RCTSetLogThreshold(RCTLogLevel(newValue)) + } + } + + private let bridgeModule = RNReactNativeGutenbergBridge() + private unowned let dataSource: GutenbergBridgeDataSource + + private lazy var bridge: RCTBridge = { + return RCTBridge(delegate: self, launchOptions: [:]) + }() + + private var initialProps: [String: Any]? { + var initialProps = [String: Any]() + + if let initialContent = dataSource.gutenbergInitialContent() { + initialProps["initialData"] = initialContent + } + + if let initialTitle = dataSource.gutenbergInitialTitle() { + initialProps["initialTitle"] = initialTitle + } + + initialProps["postType"] = dataSource.gutenbergPostType() + + if let locale = dataSource.gutenbergLocale() { + initialProps["locale"] = locale + } + + if let translations = dataSource.gutenbergTranslations() { + initialProps["translations"] = translations + } + + if let capabilities = dataSource.gutenbergCapabilities() { + initialProps["capabilities"] = capabilities + } + + let editorTheme = dataSource.gutenbergEditorTheme() + if let colors = editorTheme?.colors { + initialProps["colors"] = colors + } + + if let gradients = editorTheme?.gradients { + initialProps["gradients"] = gradients + } + + return initialProps + } + + public init(dataSource: GutenbergBridgeDataSource, extraModules: [RCTBridgeModule] = []) { + self.dataSource = dataSource + self.extraModules = extraModules + super.init() + bridgeModule.dataSource = dataSource + logThreshold = isPackagerRunning ? .trace : .error + } + + public func invalidate() { + bridge.invalidate() + } + + public func requestHTML() { + sendEvent(.requestGetHtml) + } + + public func toggleHTMLMode() { + sendEvent(.toggleHTMLMode) + } + + public func setTitle(_ title: String) { + sendEvent(.setTitle, body: ["title": title]) + } + + public func updateHtml(_ html: String) { + sendEvent(.updateHtml, body: ["html": html]) + } + + public func replace(block: Block) { + sendEvent(.replaceBlock, body: ["html": block.content, "clientId": block.id]) + } + + private func sendEvent(_ event: RNReactNativeGutenbergBridge.EventName, body: [String: Any]? = nil) { + bridgeModule.sendEvent(withName: event.rawValue, body: body) + } + + public func mediaUploadUpdate(id: Int32, state: MediaUploadState, progress: Float, url: URL?, serverID: Int32?) { + var data: [String: Any] = ["mediaId": id, "state": state.rawValue, "progress": progress]; + if let url = url { + data["mediaUrl"] = url.absoluteString + } + if let serverID = serverID { + data["mediaServerId"] = serverID + } + sendEvent(.mediaUpload, body: data) + } + + public func appendMedia(id: Int32, url: URL, type: MediaType) { + let data: [String: Any] = [ + "mediaId" : id, + "mediaUrl" : url.absoluteString, + "mediaType": type.rawValue, + ] + sendEvent(.mediaAppend, body: data) + } + + public func setFocusOnTitle() { + bridgeModule.sendEventIfNeeded(.setFocusOnTitle, body: nil) + } + + private var isPackagerRunning: Bool { + let url = sourceURL(for: bridge) + return !(url?.isFileURL ?? true) + } + + public func updateTheme(_ editorTheme: GutenbergEditorTheme?) { + + var themeUpdates = [String : Any]() + + if let colors = editorTheme?.colors { + themeUpdates["colors"] = colors + } + + if let gradients = editorTheme?.gradients { + themeUpdates["gradients"] = gradients + } + + bridgeModule.sendEventIfNeeded(.updateTheme, body:themeUpdates) + } +} + +extension Gutenberg: RCTBridgeDelegate { + public func sourceURL(for bridge: RCTBridge!) -> URL! { + return RCTBundleURLProvider.sharedSettings()?.jsBundleURL(forBundleRoot: "index", fallbackResource: "") + } + + public func extraModules(for bridge: RCTBridge!) -> [RCTBridgeModule]! { + let aztecManager = RCTAztecViewManager() + aztecManager.attachmentDelegate = dataSource.aztecAttachmentDelegate() + let baseModules:[RCTBridgeModule] = [bridgeModule, aztecManager] + return baseModules + extraModules + } +} + +extension Gutenberg { + public enum MediaUploadState: Int { + case uploading = 1 + case succeeded = 2 + case failed = 3 + case reset = 4 + } + +} + +extension Gutenberg { + public enum MediaType: String { + case image + case video + case audio + case other + } +} + +extension Gutenberg.MediaType { + init(fromJSString rawValue: String) { + self = Gutenberg.MediaType(rawValue: rawValue) ?? .other + } +} + +extension Gutenberg { + public struct MediaSource: Hashable { + /// The label string that will be shown to the user. + let label: String + + /// A unique identifier of this media source option. + let id: String + + /// The types of media this source can provide. + let types: Set + + var jsRepresentation: [String: String] { + return [ + "label": label, + "value": id, + ] + } + } +} + +public extension Gutenberg.MediaSource { + public init(id: String, label: String, types: [Gutenberg.MediaType]) { + self.id = id + self.label = label + self.types = Set(types) + } +} diff --git a/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift b/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift new file mode 100644 index 00000000000000..fb61cdc4a5084f --- /dev/null +++ b/packages/react-native-bridge/ios/GutenbergBridgeDataSource.swift @@ -0,0 +1,62 @@ +import Aztec + +public protocol GutenbergBridgeDataSource: class { + /// Asks the data source for the initial html content to be presented by the editor. + /// Return `nil` to show the example content. + /// + /// - Returns: The HTML initial content or nil. + func gutenbergInitialContent() -> String? + + /// Asks the data source for the initial title to be presented by the editor. + /// Return `nil` to show the example content. + /// + /// - Returns: The HTML initial title or nil. + func gutenbergInitialTitle() -> String? + + /// Asks the data source for the post type to be presented by the editor. + /// Return `nil` to assume a `post` type. + /// + /// - Returns: The post type or nil. + func gutenbergPostType() -> String + + /// Asks the data source for an object conforming to `TextViewAttachmentDelegate` + /// to handle media loading. + /// + /// - Returns: An object conforming to TextViewAttachmentDelegate. + func aztecAttachmentDelegate() -> TextViewAttachmentDelegate + + /// Asks the data source for the locale to be used by the editor. + /// Return `nil` to show the default one (`en`). + /// + /// - Returns: The locale slug value or nil. + func gutenbergLocale() -> String? + + /// Asks the data source for the list of localized strings to be used by the editor. + /// Return `nil` if no localization file is present for the current locale + /// + /// - Returns: Gutenberg related localization key value pairs for the current locale. + func gutenbergTranslations() -> [String : [String]]? + + /// Asks the delegate for a list of Media Sources to show on the Media Source Picker. + func gutenbergMediaSources() -> [Gutenberg.MediaSource] + + func gutenbergCapabilities() -> [String: Bool]? + + /// Asks the delegate for a list of theme colors + func gutenbergEditorTheme() -> GutenbergEditorTheme? +} + +public extension GutenbergBridgeDataSource { + func gutenbergMediaSources() -> [Gutenberg.MediaSource] { + return [] + } + + func gutenbergPostType() -> String { + return "post" + } +} + +public protocol GutenbergEditorTheme { + var colors: [[String: String]]? { get } + var gradients: [[String: String]]? { get } +} diff --git a/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift new file mode 100644 index 00000000000000..5183d835e74480 --- /dev/null +++ b/packages/react-native-bridge/ios/GutenbergBridgeDelegate.swift @@ -0,0 +1,219 @@ +public struct MediaInfo { + public let id: Int32? + public let url: String? + public let type: String? + public let caption: String? + + public init(id: Int32?, url: String?, type: String?, caption: String? = nil) { + self.id = id + self.url = url + self.type = type + self.caption = caption + } +} + +public struct Block { + public let id: String + public let name: String + public let content: String + + public func replacingContent(with newContent: String) -> Block { + Block(id: id, name: name, content: newContent) + } +} + +public struct ContentInfo { + public let characterCount: Int + public let wordCount: Int + public let paragraphCount: Int + public let blockCount: Int +} + +extension ContentInfo { + + static func decode(from dict: [String: Int]) -> ContentInfo? { + guard let characters = dict["characterCount"], + let words = dict["wordCount"], + let paragraphs = dict["paragraphCount"], + let blocks = dict["blockCount"] else { + return nil + } + return ContentInfo(characterCount: characters, wordCount: words, paragraphCount: paragraphs, blockCount: blocks) + } +} + +public typealias MediaPickerDidPickMediaCallback = (_ media: [MediaInfo]?) -> Void +public typealias MediaImportCallback = (_ media: MediaInfo?) -> Void + +/// Declare internal Media Sources. +/// Label and Type are not relevant since they are delcared on the JS side. +/// Hopefully soon, this will need to be declared on the client side. +extension Gutenberg.MediaSource { + public static let mediaLibrary = Gutenberg.MediaSource(id: "SITE_MEDIA_LIBRARY", label: "", types: [.image, .video]) + public static let deviceLibrary = Gutenberg.MediaSource(id: "DEVICE_MEDIA_LIBRARY", label: "", types: [.image, .video]) + public static let deviceCamera = Gutenberg.MediaSource(id: "DEVICE_CAMERA", label: "", types: [.image, .video]) + + static var registeredInternalSources: [Gutenberg.MediaSource] { + return [ + .deviceCamera, + .deviceLibrary, + .mediaLibrary, + ] + } +} + +/// Ref. https://github.com/facebook/react-native/blob/master/Libraries/polyfills/console.js#L376 +public enum LogLevel: Int { + case trace + case info + case warn + case error + case fatal +} + +// Avoid possible future problems due to log level int value changes. +extension LogLevel { + init (_ rnLogLevel: RCTLogLevel) { + switch rnLogLevel { + case .trace: self = .trace + case .info: self = .info + case .warning: self = .warn + case .error: self = .error + case .fatal: self = .fatal + } + } +} + +extension RCTLogLevel { + init(_ logLevel: LogLevel) { + switch logLevel { + case .trace: self = .trace + case .info: self = .info + case .warn: self = .warning + case .error: self = .error + case .fatal: self = .fatal + } + } +} + +public enum GutenbergUserEvent { + + case editorSessionTemplateApply(_ template: String) + case editorSessionTemplatePreview(_ template: String) + + init?(event: String, properties:[AnyHashable: Any]?) { + switch event { + case "editor_session_template_apply": + guard let template = properties?["template"] as? String else { return nil } + self = .editorSessionTemplateApply(template) + case "editor_session_template_preview": + guard let template = properties?["template"] as? String else { return nil } + self = .editorSessionTemplatePreview(template) + default: + return nil + } + } +} + +public protocol GutenbergBridgeDelegate: class { + /// Tells the delegate that Gutenberg had returned the requested HTML content. + /// You can request HTML content by calling `requestHTML()` on a Gutenberg bridge instance. + /// + /// - Parameters: + /// - title: the title as shown by the editor. + /// - html: The current HTML presented by the editor. + /// - changed: True if the given HTML presents changes from the last request or initial value. + /// - contentInfo: Information about the post content: characters, words, paragraphs, blocks. + func gutenbergDidProvideHTML(title: String, html: String, changed: Bool, contentInfo: ContentInfo?) + + /// Tells the delegate that an image block requested an image from the media picker. + /// + /// - Parameters: + /// - source: the source from where the picker will get the media + /// - callback: A callback block to be called with an array of upload mediaIdentifiers and a placeholder images file url, use nil on both parameters to signal that the action was canceled. + /// + func gutenbergDidRequestMedia(from source: Gutenberg.MediaSource, filter: [Gutenberg.MediaType], allowMultipleSelection: Bool, with callback: @escaping MediaPickerDidPickMediaCallback) + + /// Tells the delegate that gutenberg JS requested the import of media item based on the provided URL + /// + /// - Parameters: + /// - url: the url to import + /// - callback: A callback block to be called with an array of upload mediaIdentifiers and a placeholder images file url, use nil on both parameters to signal that the action has failed. + // + func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaImportCallback) + + /// Tells the delegate that an image block requested to reconnect with media uploads coordinator. + /// + func gutenbergDidRequestMediaUploadSync() + + /// Tells the delegate that an image block requested for the actions available for the media upload. + /// + func gutenbergDidRequestMediaUploadActionDialog(for mediaID: Int32) + + /// Tells the delegate that an image block requested for the upload cancelation. + /// + func gutenbergDidRequestMediaUploadCancelation(for mediaID: Int32) + + /// Tells the delegate that the Gutenberg module has finished loading. + /// + func gutenbergDidLoad() + + /// Tells the delegate every time the editor has finished layout. + /// + func gutenbergDidLayout() + + /// Tells the delegate that the editor view has completed the initial render. + /// - Parameters: + /// - unsupportedBlockNames: A list of loaded block names that are not supported. + /// + func gutenbergDidMount(unsupportedBlockNames: [String]) + + /// Tells the delegate that logger method is called. + /// + func gutenbergDidEmitLog(message: String, logLevel: LogLevel) + + /// Tells the delegate that the editor has sent an autosave event. + /// + func editorDidAutosave() + + /// Tells the delegate that the editor needs to perform a network request. + /// The paths given to perform the request are from the WP ORG REST API. + /// https://developer.wordpress.org/rest-api/reference/ + /// - Parameter path: The path to perform the request. + /// - Parameter completion: Completion handler to be called with the result or an error. + func gutenbergDidRequestFetch(path: String, completion: @escaping (Swift.Result) -> Void) + + /// Tells the delegate to display a fullscreen image from a given URL + /// + func gutenbergDidRequestImagePreview(with mediaUrl: URL, thumbUrl: URL?) + + /// Tells the delegate to display the media editor from a given URL + /// + func gutenbergDidRequestMediaEditor(with mediaUrl: URL, callback: @escaping MediaPickerDidPickMediaCallback) + + /// Tells the delegate that the editor needs to log a custom event + /// - Parameter event: The event key to be logged + func gutenbergDidLogUserEvent(_ event: GutenbergUserEvent) + + /// Tells the delegate that the editor needs to render an unsupported block + func gutenbergDidRequestUnsupportedBlockFallback(for block: Block) + + /// Tells the delegate that the editor requested a mention + /// - Parameter callback: Completion handler to be called with an user mention or an error + func gutenbergDidRequestMention(callback: @escaping (Swift.Result) -> Void) + + /// Tells the delegate that the editor requested to show the tooltip + func gutenbergDidRequestStarterPageTemplatesTooltipShown() -> Bool + + /// Tells the delegate that the editor requested to set the tooltip's visibility + /// - Parameter tooltipShown: Tooltip's visibility value + func gutenbergDidRequestSetStarterPageTemplatesTooltipShown(_ tooltipShown: Bool) +} + +// MARK: - Optional GutenbergBridgeDelegate methods + +public extension GutenbergBridgeDelegate { + func gutenbergDidLoad() { } + func gutenbergDidLayout() { } + func gutenbergDidRequestUnsupportedBlockFallback(for block: Block) { } +} diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift new file mode 100644 index 00000000000000..12e425005ab85b --- /dev/null +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/FallbackJavascriptInjection.swift @@ -0,0 +1,108 @@ +import WebKit + +private struct SourceFile { + enum SourceFileError: Error { + case sourceFileNotFound(String) + } + + enum Extension: String { + case css + case js + case json + } + private let name: String + private let type: Extension + private static let bundle = Bundle(for: Gutenberg.self) + + func getContent() throws -> String { + guard let path = SourceFile.bundle.path(forResource: name, ofType: type.rawValue) else { + throw SourceFileError.sourceFileNotFound("\(name).\(type)") + } + return try String(contentsOfFile: path, encoding: .utf8) + } +} + +extension SourceFile { + static let editorStyle = SourceFile(name: "editor-style-overrides", type: .css) + static let wpBarsStyle = SourceFile(name: "wp-bar-override", type: .css) + static let injectCss = SourceFile(name: "inject-css", type: .js) + static let retrieveHtml = SourceFile(name: "content-functions", type: .js) + static let insertBlock = SourceFile(name: "insert-block", type: .js) + static let localStorage = SourceFile(name: "local-storage-overrides", type: .json) + static let preventAutosaves = SourceFile(name: "prevent-autosaves", type: .js) +} + +public struct FallbackJavascriptInjection { + enum JSMessage: String, CaseIterable { + case htmlPostContent + case log + } + + private let userContentScripts: [WKUserScript] + private let injectLocalStorageScriptTemplate = "localStorage.setItem('WP_DATA_USER_%@','%@')" + private let injectCssScriptTemplate = "window.injectCss(`%@`)" + + public let insertBlockScript: WKUserScript + public let injectWPBarsCssScript: WKUserScript + public let injectEditorCssScript: WKUserScript + public let injectCssScript: WKUserScript + public let injectLocalStorageScript: WKUserScript + public let preventAutosavesScript: WKUserScript + public let getHtmlContentScript = "window.getHTMLPostContent()".toJsScript() + + /// Init an instance of GutenbergWebJavascriptInjection or throws if any of the required sources doesn't exist. + /// This helps to cach early any possible error due to missing source files. + /// - Parameter blockHTML: The block HTML code to be injected. + /// - Parameter userId: The id of the logged user. + /// - Throws: Throws an error if any required source doesn't exist. + public init(blockHTML: String, userId: String) throws { + func script(with source: SourceFile, argument: String? = nil) throws -> WKUserScript { + String(format: try source.getContent(), argument ?? []).toJsScript() + } + + func getInjectCssScript(with source: SourceFile) throws -> WKUserScript { + "window.injectCss(`\(try source.getContent())`)".toJsScript() + } + + userContentScripts = [ + try script(with: .retrieveHtml), + ] + + insertBlockScript = try script(with: .insertBlock, argument: blockHTML) + injectCssScript = try script(with: .injectCss) + injectWPBarsCssScript = try getInjectCssScript(with: .wpBarsStyle) + injectEditorCssScript = try getInjectCssScript(with: .editorStyle) + preventAutosavesScript = try script(with: .preventAutosaves) + + let localStorageJsonString = try SourceFile.localStorage.getContent().removingSpacesAndNewLines() + let scriptString = String(format: injectLocalStorageScriptTemplate, userId, localStorageJsonString) + injectLocalStorageScript = scriptString.toJsScript() + } + + func userContent(messageHandler handler: WKScriptMessageHandler, blockHTML: String) -> WKUserContentController { + let userContent = WKUserContentController() + userContent.addUserScripts(userContentScripts) + JSMessage.allCases.forEach { + userContent.add(handler, name: $0.rawValue) + } + return userContent + } +} + +private extension String { + func toJsScript() -> WKUserScript { + WKUserScript(source: self, injectionTime: .atDocumentEnd, forMainFrameOnly: false) + } + + func removingSpacesAndNewLines() -> String { + return replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: " ", with: "") + } +} + +private extension WKUserContentController { + func addUserScripts(_ scripts: [WKUserScript]) { + scripts.forEach { + addUserScript($0) + } + } +} diff --git a/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift new file mode 100644 index 00000000000000..dc2a4ab1b5e915 --- /dev/null +++ b/packages/react-native-bridge/ios/GutenbergWebFallback/GutenbergWebSingleBlockViewController.swift @@ -0,0 +1,178 @@ +import UIKit +import WebKit + +public protocol GutenbergWebDelegate: class { + func webController(controller: GutenbergWebSingleBlockViewController, didPressSave block: Block) + func webControllerDidPressClose(controller: GutenbergWebSingleBlockViewController) + func webController(controller: GutenbergWebSingleBlockViewController, didLog log: String) +} + +open class GutenbergWebSingleBlockViewController: UIViewController { + public weak var delegate: GutenbergWebDelegate? + + private let isWPOrg: Bool + private let block: Block + private let jsInjection: FallbackJavascriptInjection + private let coverView = UIView() + + public lazy var webView: WKWebView = { + let configuration = WKWebViewConfiguration() + configuration.userContentController = jsInjection.userContent(messageHandler: self, blockHTML: block.content) + configuration.suppressesIncrementalRendering = true + return WKWebView(frame: .zero, configuration: configuration) + }() + + public init(block: Block, userId: String, isWPOrg: Bool = true) throws { + self.block = block + self.isWPOrg = isWPOrg + jsInjection = try FallbackJavascriptInjection(blockHTML: block.content, userId: userId) + + super.init(nibName: nil, bundle: nil) + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + public override func loadView() { + view = webView + } + + open override func viewDidLoad() { + super.viewDidLoad() + webView.navigationDelegate = self + if #available(iOS 13.0, *) { + isModalInPresentation = true + } + addNavigationBarElements() + addCoverView() + loadWebView() + } + + open func getRequest(for webView: WKWebView, completion: @escaping (URLRequest) -> Void) { + let request = URLRequest(url: URL(string: "https://wordpress.org/gutenberg/")!) + completion(request) + } + + public func cleanUp() { + webView.configuration.userContentController.removeAllUserScripts() + FallbackJavascriptInjection.JSMessage.allCases.forEach { + webView.configuration.userContentController.removeScriptMessageHandler(forName: $0.rawValue) + } + } + + private func loadWebView() { + getRequest(for: webView) { [weak self] (request) in + self?.webView.load(request) + } + } + + @objc public func onSaveButtonPressed() { + evaluateJavascript(jsInjection.getHtmlContentScript) + } + + @objc public func onCloseButtonPressed() { + delegate?.webControllerDidPressClose(controller: self) + } + + private func addNavigationBarElements() { + let saveButton = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(onSaveButtonPressed)) + let cancelButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(onCloseButtonPressed)) + + navigationItem.rightBarButtonItem = saveButton + navigationItem.leftBarButtonItem = cancelButton + let localizedTitle = NSLocalizedString("Edit %@ block", comment: "Title of Gutenberg WEB editor running on a Web View. %@ is the localized block name.") + title = String(format: localizedTitle, block.name) + } + + func addCoverView() { + webView.addSubview(coverView) + if #available(iOS 13.0, *) { + coverView.backgroundColor = UIColor.systemBackground + } else { + coverView.backgroundColor = .white + } + coverView.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + coverView.leadingAnchor.constraint(equalTo: webView.leadingAnchor), + coverView.trailingAnchor.constraint(equalTo: webView.trailingAnchor), + coverView.topAnchor.constraint(equalTo: webView.topAnchor), + coverView.bottomAnchor.constraint(equalTo: webView.bottomAnchor), + ]) + } + + func removeCoverViewAnimated() { + UIView.animate(withDuration: 1, animations: { + self.coverView.alpha = 0 + }) { _ in + self.coverView.removeFromSuperview() + self.coverView.alpha = 1 + } + } + + private func evaluateJavascript(_ script: WKUserScript) { + webView.evaluateJavaScript(script.source) { (response, error) in + if let response = response { + print("\(response)") + } + if let error = error { + print("\(error)") + } + } + } + + private func save(_ newContent: String) { + delegate?.webController(controller: self, didPressSave: block.replacingContent(with: newContent)) + } +} + +extension GutenbergWebSingleBlockViewController: WKNavigationDelegate { + public func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { + if !isWPOrg && navigationResponse.response.url?.absoluteString.contains("/wp-admin/post-new.php") ?? false { + evaluateJavascript(jsInjection.insertBlockScript) + } + decisionHandler(.allow) + } + + public func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { + // At this point, user scripts are not loaded yet, so we need to inject the + // script that inject css manually before actually injecting the css. + evaluateJavascript(jsInjection.injectCssScript) + evaluateJavascript(jsInjection.injectEditorCssScript) + evaluateJavascript(jsInjection.injectWPBarsCssScript) + evaluateJavascript(jsInjection.injectLocalStorageScript) + } + + public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + // Sometimes the editor takes longer loading and its CSS can override what + // Injectic Editor specific CSS when everything is loaded to avoid overwritting parameters if gutenberg CSS load later. + evaluateJavascript(jsInjection.preventAutosavesScript) + evaluateJavascript(jsInjection.injectEditorCssScript) + if isWPOrg { + evaluateJavascript(jsInjection.insertBlockScript) + } + removeCoverViewAnimated() + } +} + +extension GutenbergWebSingleBlockViewController: WKScriptMessageHandler { + public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + guard + let messageType = FallbackJavascriptInjection.JSMessage(rawValue: message.name), + let body = message.body as? String + else { + return + } + + handle(messageType, body: body) + } + + private func handle(_ message: FallbackJavascriptInjection.JSMessage, body: String) { + switch message { + case .log: + delegate?.webController(controller: self, didLog: body) + case .htmlPostContent: + save(body) + } + } +} diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge-Bridging-Header.h b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge-Bridging-Header.h new file mode 100644 index 00000000000000..a11928d6bd3674 --- /dev/null +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge-Bridging-Header.h @@ -0,0 +1,9 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import +#import +#import +#import diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m new file mode 100644 index 00000000000000..b5d4cd248157ae --- /dev/null +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.m @@ -0,0 +1,27 @@ +#import +#import + +@interface RCT_EXTERN_MODULE(RNReactNativeGutenbergBridge, NSObject) + +RCT_EXTERN_METHOD(provideToNative_Html:(NSString *)html title:(NSString *)title changed:(BOOL)changed contentInfo:(NSDictionary *)info) +RCT_EXTERN_METHOD(requestMediaPickFrom:(NSString *)source filter:(NSArray *)filter allowMultipleSelection:(BOOL)allowMultipleSelection callback:(RCTResponseSenderBlock)callback) +RCT_EXTERN_METHOD(getOtherMediaOptions:(NSArray *)filter callback:(RCTResponseSenderBlock)callback) +RCT_EXTERN_METHOD(mediaUploadSync) +RCT_EXTERN_METHOD(requestImageFailedRetryDialog:(int)mediaID) +RCT_EXTERN_METHOD(requestImageUploadCancelDialog:(int)mediaID) +RCT_EXTERN_METHOD(requestImageUploadCancel:(int)mediaID) +RCT_EXTERN_METHOD(requestMediaImport:(NSString *)sourceURL callback:(RCTResponseSenderBlock)callback) +RCT_EXTERN_METHOD(editorDidLayout) +RCT_EXTERN_METHOD(editorDidMount:(NSArray *)unsupportedBlockNames) +RCT_EXTERN_METHOD(editorDidEmitLog:(NSString *)message logLevel:(int)logLevel) +RCT_EXTERN_METHOD(editorDidAutosave) +RCT_EXTERN_METHOD(fetchRequest:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) +RCT_EXTERN_METHOD(requestImageFullscreenPreview:(NSString *)currentImageUrlString originalImageUrlString:(NSString *)originalImageUrlString) +RCT_EXTERN_METHOD(requestMediaEditor:(NSString *)mediaUrl callback:(RCTResponseSenderBlock)callback) +RCT_EXTERN_METHOD(logUserEvent:(NSString *)event properties:(NSDictionary *)properties) +RCT_EXTERN_METHOD(requestUnsupportedBlockFallback:(NSString *)content blockId:(NSString *)blockId blockName:(NSString *)blockName) +RCT_EXTERN_METHOD(addMention:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)rejecter) +RCT_EXTERN_METHOD(requestStarterPageTemplatesTooltipShown:(RCTResponseSenderBlock)callback) +RCT_EXTERN_METHOD(setStarterPageTemplatesTooltipShown:(BOOL)tooltipShown) + +@end diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift new file mode 100644 index 00000000000000..aead5bf2cb4714 --- /dev/null +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.swift @@ -0,0 +1,365 @@ +struct GutenbergEvent { + let name: String + let body: Any? +} + +@objc (RNReactNativeGutenbergBridge) +public class RNReactNativeGutenbergBridge: RCTEventEmitter { + weak var delegate: GutenbergBridgeDelegate? + weak var dataSource: GutenbergBridgeDataSource? + private var isJSLoading = true + private var hasObservers = false + private var queuedEvents = [GutenbergEvent]() + + public override init() { + super.init() + NotificationCenter.default.addObserver(forName: .RCTContentDidAppear, object: nil, queue: nil) { (_) in + DispatchQueue.main.async { + self.connectionEstablished() + } + } + } + // MARK: - Messaging methods + + @objc + func provideToNative_Html(_ html: String, title: String, changed: Bool, contentInfo: [String:Int]) { + DispatchQueue.main.async { + let info = ContentInfo.decode(from: contentInfo) + self.delegate?.gutenbergDidProvideHTML(title: title, html: html, changed: changed, contentInfo: info) + } + } + + @objc + func requestMediaPickFrom(_ source: String, filter: [String]?, allowMultipleSelection: Bool, callback: @escaping RCTResponseSenderBlock) { + let mediaSource = getMediaSource(withId: source) + let mediaFilter = getMediaTypes(from: filter) + + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestMedia(from: mediaSource, filter: mediaFilter, allowMultipleSelection: allowMultipleSelection, with: { media in + guard let media = media else { + callback(nil) + return + } + let mediaToReturn: [MediaInfo] + if allowMultipleSelection { + mediaToReturn = media + } else { + mediaToReturn = Array(media.prefix(1)) + } + + let jsFormattedMedia = mediaToReturn.map { mediaInfo in + return mediaInfo.encodeForJS() + } + if allowMultipleSelection { + callback([jsFormattedMedia]) + } else { + callback(jsFormattedMedia) + } + }) + } + } + + @objc + func requestUnsupportedBlockFallback(_ content: String, blockId: String, blockName: String) { + DispatchQueue.main.async { + let block = Block(id: blockId, name: blockName, content: content) + self.delegate?.gutenbergDidRequestUnsupportedBlockFallback(for: block) + } + } + + @objc + func getOtherMediaOptions(_ filter: [String]?, callback: @escaping RCTResponseSenderBlock) { + guard let dataSource = dataSource else { + return callback([]) + } + + let mediaSources = dataSource.gutenbergMediaSources() + let allowedTypes = getMediaTypes(from: filter) + let filteredSources = mediaSources.filter { + return $0.types.intersection(allowedTypes).isEmpty == false + } + let jsMediaSources = filteredSources.map { $0.jsRepresentation } + callback([jsMediaSources]) + } + + @objc + func requestMediaImport(_ urlString: String, callback: @escaping RCTResponseSenderBlock) { + guard let url = URL(string: urlString) else { + callback(nil) + return + } + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestImport(from: url, with: { mediaInfo in + guard let mediaInfo = mediaInfo else { + callback(nil) + return + } + callback([mediaInfo.id as Any, mediaInfo.url as Any]) + }) + } + } + + @objc + func mediaUploadSync() { + DispatchQueue.main.async { + if self.hasObservers { + self.delegate?.gutenbergDidRequestMediaUploadSync() + } + } + } + + @objc + func requestImageFailedRetryDialog(_ mediaID: Int32) { + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestMediaUploadActionDialog(for: mediaID) + } + } + + @objc + func requestImageUploadCancelDialog(_ mediaID: Int32) { + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestMediaUploadActionDialog(for: mediaID) + } + } + + @objc + func requestImageUploadCancel(_ mediaID: Int32) { + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestMediaUploadCancelation(for: mediaID) + } + } + + @objc + func editorDidLayout() { + DispatchQueue.main.async { + self.delegate?.gutenbergDidLayout() + } + } + + @objc + func editorDidMount(_ unsupportedBlockNames: [AnyObject]) { + let unsupportedNames = unsupportedBlockNames.compactMap { $0 as? String } + DispatchQueue.main.async { + self.delegate?.gutenbergDidMount(unsupportedBlockNames: unsupportedNames) + } + } + + @objc + func editorDidEmitLog(_ message: String, logLevel: Int) { + guard + shouldLog(with: logLevel), + let logLevel = LogLevel(rawValue: logLevel) + else { + return + } + + delegate?.gutenbergDidEmitLog(message: message, logLevel: logLevel) + } + + @objc + func requestImageFullscreenPreview(_ currentImageUrlString: String, originalImageUrlString: String?) { + guard let currentImageUrl = URL(string: currentImageUrlString) else { + assertionFailure("Given String is not a URL") + return + } + + let originalUrl: URL + let currentUrl: URL? + + if let originalImageUrlString = originalImageUrlString, let original = URL(string: originalImageUrlString) { + originalUrl = original + currentUrl = currentImageUrl + } else { + // The current image url is the only one available. + originalUrl = currentImageUrl + currentUrl = nil + } + + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestImagePreview(with: originalUrl, thumbUrl: currentUrl) + } + } + + @objc + func requestMediaEditor(_ urlString: String, callback: @escaping RCTResponseSenderBlock) { + guard let url = URL(string: urlString) else { + assertionFailure("Given String is not a URL") + return + } + + DispatchQueue.main.async { + self.delegate?.gutenbergDidRequestMediaEditor(with: url) { media in + guard let media = media else { + callback(nil) + return + } + + let mediaToReturn = media + + let jsFormattedMedia = mediaToReturn.map { mediaInfo in + return mediaInfo.encodeForJS() + } + + callback(jsFormattedMedia) + } + } + } + + public func connectionEstablished() { + guard !hasObservers else { return } // We have an established connection no need to continue. + hasObservers = true + while (self.queuedEvents.count > 0) { + let event = self.queuedEvents.removeFirst() + super.sendEvent(withName: event.name, body: event.body) // execute this on super as we want to avoid logic in self. + } + } + + public override func sendEvent(withName name: String, body: Any?) { + DispatchQueue.main.async { + if self.hasObservers && self.queuedEvents.count == 0 { + super.sendEvent(withName: name, body: body) + } else { + let event = GutenbergEvent(name: name, body: body) + self.queuedEvents.append(event) + } + } + } + + private func shouldLog(with level: Int) -> Bool { + return level >= RCTGetLogThreshold().rawValue + } + + @objc + func editorDidAutosave() { + DispatchQueue.main.async { + self.delegate?.editorDidAutosave() + } + } + + @objc + func fetchRequest(_ path: String, resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { + self.delegate?.gutenbergDidRequestFetch(path: path, completion: { (result) in + switch result { + case .success(let response): + resolver(response) + case .failure(let error): + rejecter("\(error.code)", error.description, error) + } + }) + } + + + /// Sends events to the JS side only if there is observers listening + /// + /// - Parameters: + /// - name: name of the event + /// - body: data for the event + func sendEventIfNeeded(_ event: EventName, body: Any? = nil) { + if ( hasObservers ) { + sendEvent(withName: event.rawValue, body: body) + } + } + + @objc + func logUserEvent(_ event: String, properties: [AnyHashable: Any]?) { + guard let logEvent = GutenbergUserEvent(event: event, properties: properties) else { return } + self.delegate?.gutenbergDidLogUserEvent(logEvent) + } + + @objc + func addMention(_ resolver: @escaping RCTPromiseResolveBlock, rejecter: @escaping RCTPromiseRejectBlock) { + self.delegate?.gutenbergDidRequestMention(callback: { (result) in + switch result { + case .success(let mention): + resolver([mention]) + case .failure(let error): + rejecter(error.domain, "\(error.code)", error) + } + }) + } + + @objc + func requestStarterPageTemplatesTooltipShown(_ callback: @escaping RCTResponseSenderBlock) { + callback([self.delegate?.gutenbergDidRequestStarterPageTemplatesTooltipShown() ?? false]) + } + + @objc + func setStarterPageTemplatesTooltipShown(_ tooltipShown: Bool) { + self.delegate?.gutenbergDidRequestSetStarterPageTemplatesTooltipShown(tooltipShown) + } + +} + +// MARK: - RCTBridgeModule delegate + +extension RNReactNativeGutenbergBridge { + enum EventName: String, CaseIterable { + case requestGetHtml + case setTitle + case toggleHTMLMode + case updateHtml + case mediaUpload + case setFocusOnTitle + case mediaAppend + case updateTheme + case replaceBlock + } + + public override func supportedEvents() -> [String]! { + return EventName.allCases.compactMap { $0.rawValue } + } + + public override static func requiresMainQueueSetup() -> Bool { + return true + } + + public override func batchDidComplete() { + if isJSLoading { + isJSLoading = false + DispatchQueue.main.async { + self.delegate?.gutenbergDidLoad() + } + } + } +} + +// MARK: - Helpers + +extension RNReactNativeGutenbergBridge { + func optionalArray(from optionalString: String?) -> [String]? { + guard let string = optionalString else { + return nil + } + return [string] + } + + private func getMediaSource(withId mediaSourceID: String) -> Gutenberg.MediaSource { + let allMediaSources = Gutenberg.MediaSource.registeredInternalSources + (dataSource?.gutenbergMediaSources() ?? []) + return allMediaSources.first{ $0.id == mediaSourceID } ?? .deviceLibrary + } + + private func getMediaTypes(from jsMediaTypes: [String]?) -> [Gutenberg.MediaType] { + return (jsMediaTypes ?? []).map { Gutenberg.MediaType(fromJSString: $0) } + } +} + +extension RNReactNativeGutenbergBridge { + enum MediaKey { + static let id = "id" + static let url = "url" + static let type = "type" + static let caption = "caption" + } +} + +extension MediaInfo { + + func encodeForJS() -> [String: Any] { + return [ + RNReactNativeGutenbergBridge.MediaKey.id: id as Any, + RNReactNativeGutenbergBridge.MediaKey.url: url as Any, + RNReactNativeGutenbergBridge.MediaKey.type: type as Any, + RNReactNativeGutenbergBridge.MediaKey.caption: caption as Any + ] + } +} diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcodeproj/project.pbxproj b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcodeproj/project.pbxproj new file mode 100644 index 00000000000000..a5d6d5607aacd7 --- /dev/null +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcodeproj/project.pbxproj @@ -0,0 +1,306 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 7EA30CEF21AC8C250092F894 /* Gutenberg.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EA30CEE21AC8C250092F894 /* Gutenberg.swift */; }; + 7EA30CF321AC91E20092F894 /* RNReactNativeGutenbergBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EA30CF221AC91E20092F894 /* RNReactNativeGutenbergBridge.swift */; }; + 7EA30DA721AD7A100092F894 /* GutenbergBridgeDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EA30DA621AD7A100092F894 /* GutenbergBridgeDelegate.swift */; }; + 7EA30DA921AD7A2F0092F894 /* GutenbergBridgeDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EA30DA821AD7A2F0092F894 /* GutenbergBridgeDataSource.swift */; }; + B3E7B58A1CC2AC0600A0062D /* RNReactNativeGutenbergBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNReactNativeGutenbergBridge.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 58B511D91A9E6C8500147676 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 134814201AA4EA6300B7C361 /* libRNReactNativeGutenbergBridge.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNReactNativeGutenbergBridge.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7EA30CED21AC8C240092F894 /* RNReactNativeGutenbergBridge-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RNReactNativeGutenbergBridge-Bridging-Header.h"; sourceTree = ""; }; + 7EA30CEE21AC8C250092F894 /* Gutenberg.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Gutenberg.swift; sourceTree = ""; }; + 7EA30CF221AC91E20092F894 /* RNReactNativeGutenbergBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RNReactNativeGutenbergBridge.swift; sourceTree = ""; }; + 7EA30D8821AD60CA0092F894 /* libRNTAztecView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libRNTAztecView.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7EA30D9721AD69370092F894 /* libRNTAztecView.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libRNTAztecView.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 7EA30DA621AD7A100092F894 /* GutenbergBridgeDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergBridgeDelegate.swift; sourceTree = ""; }; + 7EA30DA821AD7A2F0092F894 /* GutenbergBridgeDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GutenbergBridgeDataSource.swift; sourceTree = ""; }; + B3E7B5891CC2AC0600A0062D /* RNReactNativeGutenbergBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNReactNativeGutenbergBridge.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 58B511D81A9E6C8500147676 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 134814211AA4EA7D00B7C361 /* Products */ = { + isa = PBXGroup; + children = ( + 134814201AA4EA6300B7C361 /* libRNReactNativeGutenbergBridge.a */, + ); + name = Products; + sourceTree = ""; + }; + 58B511D21A9E6C8500147676 = { + isa = PBXGroup; + children = ( + B3E7B5891CC2AC0600A0062D /* RNReactNativeGutenbergBridge.m */, + 7EA30CF221AC91E20092F894 /* RNReactNativeGutenbergBridge.swift */, + 7EA30DA821AD7A2F0092F894 /* GutenbergBridgeDataSource.swift */, + 7EA30DA621AD7A100092F894 /* GutenbergBridgeDelegate.swift */, + 7EA30CEE21AC8C250092F894 /* Gutenberg.swift */, + 7EA30CED21AC8C240092F894 /* RNReactNativeGutenbergBridge-Bridging-Header.h */, + 134814211AA4EA7D00B7C361 /* Products */, + 7EA30D8721AD60CA0092F894 /* Frameworks */, + ); + sourceTree = ""; + }; + 7EA30D8721AD60CA0092F894 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7EA30D9721AD69370092F894 /* libRNTAztecView.a */, + 7EA30D8821AD60CA0092F894 /* libRNTAztecView.a */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 58B511DA1A9E6C8500147676 /* RNReactNativeGutenbergBridge */ = { + isa = PBXNativeTarget; + buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNReactNativeGutenbergBridge" */; + buildPhases = ( + 58B511D71A9E6C8500147676 /* Sources */, + 58B511D81A9E6C8500147676 /* Frameworks */, + 58B511D91A9E6C8500147676 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = RNReactNativeGutenbergBridge; + productName = RCTDataManager; + productReference = 134814201AA4EA6300B7C361 /* libRNReactNativeGutenbergBridge.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 58B511D31A9E6C8500147676 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0830; + ORGANIZATIONNAME = Facebook; + TargetAttributes = { + 58B511DA1A9E6C8500147676 = { + CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 1110; + }; + }; + }; + buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNReactNativeGutenbergBridge" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + ); + mainGroup = 58B511D21A9E6C8500147676; + productRefGroup = 58B511D21A9E6C8500147676; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 58B511DA1A9E6C8500147676 /* RNReactNativeGutenbergBridge */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 58B511D71A9E6C8500147676 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7EA30DA921AD7A2F0092F894 /* GutenbergBridgeDataSource.swift in Sources */, + B3E7B58A1CC2AC0600A0062D /* RNReactNativeGutenbergBridge.m in Sources */, + 7EA30CEF21AC8C250092F894 /* Gutenberg.swift in Sources */, + 7EA30CF321AC91E20092F894 /* RNReactNativeGutenbergBridge.swift in Sources */, + 7EA30DA721AD7A100092F894 /* GutenbergBridgeDelegate.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 58B511ED1A9E6C8500147676 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 58B511EE1A9E6C8500147676 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 58B511F01A9E6C8500147676 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../../react-native-aztec/ios/**"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../../React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-aztec/example/iOS/example/**", + ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)/../../react-native-aztec/example/iOS/example/**"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = RNReactNativeGutenbergBridge; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = "RNReactNativeGutenbergBridge-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 58B511F11A9E6C8500147676 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = "$(SRCROOT)/../../react-native-aztec/ios/**"; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../../React/**", + "$(SRCROOT)/../../react-native/React/**", + "$(SRCROOT)/../../react-native-aztec/example/iOS/example/**", + ); + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(SRCROOT)/../../react-native-aztec/example/iOS/example/**"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = RNReactNativeGutenbergBridge; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = "RNReactNativeGutenbergBridge-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNReactNativeGutenbergBridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58B511ED1A9E6C8500147676 /* Debug */, + 58B511EE1A9E6C8500147676 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNReactNativeGutenbergBridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58B511F01A9E6C8500147676 /* Debug */, + 58B511F11A9E6C8500147676 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 58B511D31A9E6C8500147676 /* Project object */; +} diff --git a/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcworkspace/contents.xcworkspacedata b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000000..20563a73ca0be6 --- /dev/null +++ b/packages/react-native-bridge/ios/RNReactNativeGutenbergBridge.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,9 @@ +// !$*UTF8*$! + + + + + + \ No newline at end of file diff --git a/packages/react-native-bridge/package.json b/packages/react-native-bridge/package.json new file mode 100644 index 00000000000000..6f2cfeae682f87 --- /dev/null +++ b/packages/react-native-bridge/package.json @@ -0,0 +1,31 @@ +{ + "name": "@wordpress/react-native-bridge", + "version": "1.0.0", + "description": "Native bridge library used to integrate the block editor into a native App.", + "private": true, + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "react-native" + ], + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/react-native-bridge/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/react-native-bridge" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "main": "index.js", + "react-native": "index", + "dependencies": { + "@wordpress/react-native-aztec": "file:../react-native-aztec" + }, + "peerDependencies": { + "react-native": "*" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/packages/react-native-editor/.eslintrc.js b/packages/react-native-editor/.eslintrc.js new file mode 100644 index 00000000000000..d9065a02370921 --- /dev/null +++ b/packages/react-native-editor/.eslintrc.js @@ -0,0 +1,68 @@ +module.exports = { + parser: 'babel-eslint', + env: { + browser: true, + 'jest/globals': true, + }, + globals: { + __DEV__: true, + }, + plugins: [ 'react', 'jest' ], + extends: [ 'plugin:@wordpress/eslint-plugin/recommended' ], + settings: { + react: { + pragma: 'React', + version: 'detect', + flowVersion: '0.92.0', + }, + }, + rules: { + 'no-restricted-syntax': [ + 'error', + // NOTE: We can't include the forward slash in our regex or + // we'll get a `SyntaxError` (Invalid regular expression: \ at end of pattern) + // here. That's why we use \\u002F in the regexes below. + { + selector: + 'ImportDeclaration[source.value=/^@wordpress\\u002F.+\\u002F/]', + message: + 'Path access on WordPress dependencies is not allowed.', + }, + { + selector: + 'CallExpression[callee.name=/^(__|_x|_n|_nx)$/] Literal[value=/\\.{3}/]', + message: 'Use ellipsis character (…) in place of three dots', + }, + { + selector: + 'ImportDeclaration[source.value="lodash"] Identifier.imported[name="memoize"]', + message: 'Use memize instead of Lodash’s memoize', + }, + { + selector: + 'CallExpression[callee.object.name="page"][callee.property.name="waitFor"]', + message: 'Prefer page.waitForSelector instead.', + }, + { + selector: 'JSXAttribute[name.name="id"][value.type="Literal"]', + message: + 'Do not use string literals for IDs; use withInstanceId instead.', + }, + { + // Discourage the usage of `Math.random()` as it's a code smell + // for UUID generation, for which we already have a higher-order + // component: `withInstanceId`. + selector: + 'CallExpression[callee.object.name="Math"][callee.property.name="random"]', + message: + 'Do not use Math.random() to generate unique IDs; use withInstanceId instead. (If you’re not generating unique IDs: ignore this message.)', + }, + { + selector: + 'CallExpression[callee.name="withDispatch"] > :function > BlockStatement > :not(VariableDeclaration,ReturnStatement)', + message: + 'withDispatch must return an object with consistent keys. Avoid performing logic in `mapDispatchToProps`.', + }, + ], + }, +}; diff --git a/packages/react-native-editor/.gitattributes b/packages/react-native-editor/.gitattributes new file mode 100644 index 00000000000000..49ff260043bc41 --- /dev/null +++ b/packages/react-native-editor/.gitattributes @@ -0,0 +1 @@ +RELEASE-NOTES.txt merge=union diff --git a/packages/react-native-editor/.gitignore b/packages/react-native-editor/.gitignore new file mode 100644 index 00000000000000..5ec8884e0d751d --- /dev/null +++ b/packages/react-native-editor/.gitignore @@ -0,0 +1,120 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# expo +.expo/ + +# dependencies +/node_modules + +# misc +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# OS X +.DS_Store + +# JS Builds +bundle/ + +# Android builds +*.apk +*.ap_ +.gradle/ +android/app/src/main/assets/ +android/app/src/main/res/raw/ + +# iOS builds +*.app.zip + +# files for the dex VM +*.dex + +# Java class files +*.class + +# generated files +gen/ +build/ +build.log + +# Local configuration file (sdk path, etc) +local.properties + +# XCode +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.xcuserstatee + +# Android/IntelliJ +# +build/ +.idea +.gradle +local.properties +*.iml + +# node.js +# +node_modules/ +npm-debug.log +yarn-error.log + +# BUCK +buck-out/ +\.buckd/ +*.keystore + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/ + +*/fastlane/report.xml +*/fastlane/Preview.html +*/fastlane/screenshots + +# Bundle artifact +*.jsbundle + +# VSCode local config dir +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +*.pot + +# e2e output log +appium-out.log +ios-screen-recordings/ +android-screen-recordings/ + +bin/wp-cli.phar + +# Report generated from jest-junit +/junit.xml + +# Cocoapods + +ios/Pods +ios/vendor diff --git a/packages/react-native-editor/.npmrc b/packages/react-native-editor/.npmrc new file mode 100644 index 00000000000000..43c97e719a5a82 --- /dev/null +++ b/packages/react-native-editor/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/packages/react-native-editor/.vscode/extensions.json b/packages/react-native-editor/.vscode/extensions.json new file mode 100644 index 00000000000000..60a2e524c9eb1a --- /dev/null +++ b/packages/react-native-editor/.vscode/extensions.json @@ -0,0 +1,6 @@ +{ + "recommendations": [ + "gcazaciuc.vscode-flow-ide", + "msjsdiag.vscode-react-native" + ] +} diff --git a/packages/react-native-editor/.vscode/launch.json b/packages/react-native-editor/.vscode/launch.json new file mode 100644 index 00000000000000..27c9545b33692c --- /dev/null +++ b/packages/react-native-editor/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Attach to packager", + "cwd": "${workspaceFolder}", + "type": "reactnative", + "request": "attach" + }, + ] +} \ No newline at end of file diff --git a/packages/react-native-editor/.vscode/settings.json b/packages/react-native-editor/.vscode/settings.json new file mode 100644 index 00000000000000..acbb36e1c5d99c --- /dev/null +++ b/packages/react-native-editor/.vscode/settings.json @@ -0,0 +1,17 @@ +{ + "javascript.validate.enable": false, + + // Enable/disable default JavaScript formatter (For Prettier) + "javascript.format.enable": false, + + // Use 'prettier-eslint' instead of 'prettier'. Other settings will only be fallbacks in case they could not be inferred from eslint rules. + "prettier.eslintIntegration": true, + "search.exclude": { + "**/bundle/android/App.js": true, + "**/bundle/android/App.js.map": true, + "**/bundle/ios/App.js": true, + "**/bundle/ios/App.js.map": true, + "**/i18n-cache/data": true, + "**/symlinked-packages": true + }, +} diff --git a/packages/react-native-editor/.watchmanconfig b/packages/react-native-editor/.watchmanconfig new file mode 100644 index 00000000000000..0967ef424bce67 --- /dev/null +++ b/packages/react-native-editor/.watchmanconfig @@ -0,0 +1 @@ +{} diff --git a/packages/react-native-editor/DependencyGraph.js.patched b/packages/react-native-editor/DependencyGraph.js.patched new file mode 100644 index 00000000000000..c14fa779d0db9a --- /dev/null +++ b/packages/react-native-editor/DependencyGraph.js.patched @@ -0,0 +1,297 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * + * @format + */ +"use strict"; + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { + try { + var info = gen[key](arg); + var value = info.value; + } catch (error) { + reject(error); + return; + } + if (info.done) { + resolve(value); + } else { + Promise.resolve(value).then(_next, _throw); + } +} + +function _asyncToGenerator(fn) { + return function() { + var self = this, + args = arguments; + return new Promise(function(resolve, reject) { + var gen = fn.apply(self, args); + function _next(value) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); + } + function _throw(err) { + asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); + } + _next(undefined); + }); + }; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + return obj; +} + +const AssetResolutionCache = require("./AssetResolutionCache"); + +const DependencyGraphHelpers = require("./DependencyGraph/DependencyGraphHelpers"); + +const JestHasteMap = require("jest-haste-map"); + +const Module = require("./Module"); + +const ModuleCache = require("./ModuleCache"); + +const ResolutionRequest = require("./DependencyGraph/ResolutionRequest"); + +const fs = require("fs"); + +const path = require("path"); + +const _require = require("./DependencyGraph/ModuleResolution"), + ModuleResolver = _require.ModuleResolver; + +const _require2 = require("events"), + EventEmitter = _require2.EventEmitter; + +const _require3 = require("metro-core"), + _require3$Logger = _require3.Logger, + createActionStartEntry = _require3$Logger.createActionStartEntry, + createActionEndEntry = _require3$Logger.createActionEndEntry, + log = _require3$Logger.log; + +const JEST_HASTE_MAP_CACHE_BREAKER = 4; + +class DependencyGraph extends EventEmitter { + constructor(_ref) { + let config = _ref.config, + haste = _ref.haste, + initialHasteFS = _ref.initialHasteFS, + initialModuleMap = _ref.initialModuleMap; + super(); + + _defineProperty(this, "_doesFileExist", filePath => { + return this._hasteFS.exists(filePath); + }); + + this._config = config; + this._assetResolutionCache = new AssetResolutionCache({ + assetExtensions: new Set(config.resolver.assetExts), + getDirFiles: dirPath => fs.readdirSync(dirPath), + platforms: new Set(config.resolver.platforms) + }); + this._haste = haste; + this._hasteFS = initialHasteFS; + this._moduleMap = initialModuleMap; + this._helpers = new DependencyGraphHelpers({ + assetExts: config.resolver.assetExts, + providesModuleNodeModules: config.resolver.providesModuleNodeModules + }); + + this._haste.on("change", this._onHasteChange.bind(this)); + + this._moduleCache = this._createModuleCache(); + + this._createModuleResolver(); + } + + static _createHaste(config) { + return new JestHasteMap({ + computeDependencies: false, + computeSha1: true, + extensions: config.resolver.sourceExts.concat(config.resolver.assetExts), + forceNodeFilesystemAPI: !config.resolver.useWatchman, + hasteImplModulePath: config.resolver.hasteImplModulePath, + ignorePattern: config.resolver.blacklistRE || / ^/, + mapper: config.resolver.virtualMapper, + maxWorkers: config.maxWorkers, + mocksPattern: "", + name: "metro-" + JEST_HASTE_MAP_CACHE_BREAKER, + platforms: config.resolver.platforms, + providesModuleNodeModules: config.resolver.providesModuleNodeModules, + retainAllFiles: true, + resetCache: config.resetCache, + rootDir: config.projectRoot, + roots: config.watchFolders, + throwOnModuleCollision: true, + useWatchman: config.resolver.useWatchman, + watch: false + }); + } + + static load(config) { + return _asyncToGenerator(function*() { + const initializingMetroLogEntry = log( + createActionStartEntry("Initializing Metro") + ); + config.reporter.update({ + type: "dep_graph_loading" + }); + + const haste = DependencyGraph._createHaste(config); + + const _ref2 = yield haste.build(), + hasteFS = _ref2.hasteFS, + moduleMap = _ref2.moduleMap; + + log(createActionEndEntry(initializingMetroLogEntry)); + config.reporter.update({ + type: "dep_graph_loaded" + }); + return new DependencyGraph({ + haste, + initialHasteFS: hasteFS, + initialModuleMap: moduleMap, + config + }); + })(); + } + + _getClosestPackage(filePath) { + const parsedPath = path.parse(filePath); + const root = parsedPath.root; + let dir = parsedPath.dir; + + do { + const candidate = path.join(dir, "package.json"); + + if (this._hasteFS.exists(candidate)) { + return candidate; + } + + dir = path.dirname(dir); + } while (dir !== "." && dir !== root); + + return null; + } + + _onHasteChange(_ref3) { + let eventsQueue = _ref3.eventsQueue, + hasteFS = _ref3.hasteFS, + moduleMap = _ref3.moduleMap; + this._hasteFS = hasteFS; + + this._assetResolutionCache.clear(); + + this._moduleMap = moduleMap; + eventsQueue.forEach(_ref4 => { + let type = _ref4.type, + filePath = _ref4.filePath; + return this._moduleCache.processFileChange(type, filePath); + }); + + this._createModuleResolver(); + + this.emit("change"); + } + + _createModuleResolver() { + this._moduleResolver = new ModuleResolver({ + allowPnp: this._config.resolver.allowPnp, + dirExists: filePath => { + try { + return fs.lstatSync(filePath).isDirectory(); + } catch (e) {} + + return false; + }, + doesFileExist: this._doesFileExist, + extraNodeModules: this._config.resolver.extraNodeModules, + isAssetFile: filePath => this._helpers.isAssetFile(filePath), + mainFields: this._config.resolver.resolverMainFields, + moduleCache: this._moduleCache, + moduleMap: this._moduleMap, + preferNativePlatform: true, + resolveAsset: (dirPath, assetName, platform) => + this._assetResolutionCache.resolve(dirPath, assetName, platform), + resolveRequest: this._config.resolver.resolveRequest, + sourceExts: this._config.resolver.sourceExts + }); + } + + _createModuleCache() { + return new ModuleCache({ + getClosestPackage: this._getClosestPackage.bind(this) + }); + } + + getSha1(filename) { + // TODO If it looks like we're trying to get the sha1 from a file located + // within a Zip archive, then we instead compute the sha1 for what looks + // like the Zip archive itself. + const splitIndex = filename.indexOf(".zip/"); + const containerName = + splitIndex !== -1 ? filename.slice(0, splitIndex + 4) : filename; // TODO Calling realpath allows us to get a hash for a given path even when + // it's a symlink to a file, which prevents Metro from crashing in such a + // case. However, it doesn't allow Metro to track changes to the target file + // of the symlink. We should fix this by implementing a symlink map into + // Metro (or maybe by implementing those "extra transformation sources" we've + // been talking about for stuff like CSS or WASM). + + const resolvedPath = fs.realpathSync(containerName); + + const sha1 = this._hasteFS.getSha1(resolvedPath); + + if (!sha1) { + throw new ReferenceError( + `SHA-1 for file ${filename} (${resolvedPath}) is not computed` + ); + } + + return sha1; + } + + getWatcher() { + return this._haste; + } + + end() { + this._haste.end(); + } + + resolveDependency(from, to, platform) { + const req = new ResolutionRequest({ + moduleResolver: this._moduleResolver, + entryPath: from, + helpers: this._helpers, + platform: platform || null, + moduleCache: this._moduleCache + }); + return req.resolveDependency(this._moduleCache.getModule(from), to).path; + } + + getHasteName(filePath) { + const hasteName = this._hasteFS.getModuleName(filePath); + + if (hasteName) { + return hasteName; + } + + return path.relative(this._config.projectRoot, filePath); + } +} + +module.exports = DependencyGraph; diff --git a/packages/react-native-editor/README.md b/packages/react-native-editor/README.md new file mode 100644 index 00000000000000..0b765f5f289839 --- /dev/null +++ b/packages/react-native-editor/README.md @@ -0,0 +1,140 @@ +# Mobile Gutenberg + +This is the mobile version of [Gutenberg](https://github.com/WordPress/gutenberg), targeting Android and iOS. It's a React Native library bootstrapped by CRNA and now ejected. + +## Getting Started + +### Prerequisites + +For a developer experience closer to the one the project maintainers current have, make sure you have the following tools installed: + +* git +* [nvm](https://github.com/creationix/nvm) +* Node.js and npm (use nvm to install them) +* [AndroidStudio](https://developer.android.com/studio/) to be able to compile the Android version of the app +* [Xcode](https://developer.apple.com/xcode/) to be able to compile the iOS app +* CocoaPods(`sudo gem install cocoapods`) needed to fetch React and third-party dependencies. + +Note that the OS platform used by the maintainers is macOS but the tools and setup should be usable in other platforms too. + +### Clone the project + +* Clone the project: +``` +git clone https://github.com/WordPress/gutenberg.git +``` + +## Set up + +Before running the demo app, you need to download and install the project dependencies. This is done via the following command: + +``` +nvm install --latest-npm +npm install +``` + +## Run + +``` +npm run native start +``` + +Runs the packager (Metro) in development mode. The packager stays running to serve the app bundle to the clients that request it. + +With the packager running, open another terminal window and use the following command to compile and run the Android app: + +``` +npm run native android +``` + +The app should now open in a connected device or a running emulator and fetch the JavaScript code from the running packager. + +To compile and run the iOS variant of the app using the _default_ simulator device, use: + +``` +npm run native ios +``` + +which will attempt to open your app in the iOS Simulator if you're on a Mac and have it installed. + +### Running on Other iOS Device Simulators + +To compile and run the app using a different device simulator, use: + +``` +npm run native ios --simulator="DEVICE_NAME" +``` + +For example, if you'd like to run in an iPhone Xs Max, try: + +``` +npm run native ios --simulator="iPhone Xs Max" +``` + +To see a list of all of your available iOS devices, use `xcrun simctl list devices`. + +### Troubleshooting + +Some times, and especially when tweaking anything in the `package.json`, Babel configuration (`.babelrc`) or the Jest configuration (`jest.config.js`), your changes might seem to not take effect as expected. On those times, you might need to clean various caches before starting the packager. To do that, run the script: `npm run native start:reset`. Other times, you might want to reinstall the NPM packages from scratch and the `npm run native clean:install` script can be handy. + +## Developing with Visual Studio Code + +Although you're not required to use Visual Studio Code for developing gutenberg-mobile, it is the recommended IDE and we have some configuration for it. + +When you first open the project in Visual Studio, you will be prompted to install some recommended extensions. This will help with some things like type checking and debugging. + +![Prompt to install recommended extensions](images/recommended-extensions.png) + +One of the extensions we are using is the [React Native Tools](https://marketplace.visualstudio.com/items?itemName=vsmobile.vscode-react-native). This allows you to run the packager from VSCode or launch the application on iOS or Android. It also adds some debug configurations so you can set breakpoints and debug the application directly from VSCode. Take a look at the [extension documentation](https://marketplace.visualstudio.com/items?itemName=vsmobile.vscode-react-native) for more details. + +## Unit Tests + +Use the following command to run the test suite: + +``` +npm run native test +``` + +It will run the [jest](https://github.com/facebook/jest) test runner on your tests. The tests are running on the desktop against Node.js. + +To run the tests with debugger support, start it with the following CLI command: + +``` +npm run native test:debug +``` + +Then, open `chrome://inspect` in Chrome to attach the debugger (look into the "Remote Target" section). While testing/developing, feel free to sprinkle `debugger` statements anywhere in the code that you'd like the debugger to break. + +## Writing and Running Unit Tests + +This project is set up to use [jest](https://facebook.github.io/jest/) for tests. You can configure whatever testing strategy you like, but jest works out of the box. Create test files in directories called `__tests__` or with the `.test.js` extension to have the files loaded by jest. See an example test [here](https://github.com/WordPress/gutenberg/blob/master/packages/react-native-editor/src/test/api-fetch-setup.test.js). The [jest documentation](https://facebook.github.io/jest/docs/en/getting-started.html) is also a wonderful resource, as is the [React Native testing tutorial](https://facebook.github.io/jest/docs/en/tutorial-react-native.html). + +## UI Tests + +This repository uses Appium to run UI tests. The tests live in `__device-tests__` and are written using Appium to run tests against simulators and real devices. To run these you'll need to check off a few things: + +* When running the tests, you'll need to ensure the Metro bundler (`npm run native start`) is not running. +* [Appium CLI](https://github.com/appium/appium/blob/master/docs/en/about-appium/getting-started.md) installed and available globally. We also recommend using [appium-doctor](https://github.com/appium/appium-doctor) to ensure all of Appium's dependencies are good to go. You don't have to worry about starting the server yourself, the tests handle starting the server on port 4723, just be sure that the port is free or feel free to change the port number in the test file. +* For iOS a simulator should automatically launch but for Android you'll need to have an emulator *with at least platform version 8.0* fired up and running. + +Then, to run the UI tests on iOS: + +`npm run native test:e2e:ios:local` + +and for Android: + +`npm run native test:e2e:android:local` + +To run a single test instead of the entire suite, use `npm run native device-tests:local`. Here's an example that runs only `gutenberg-editor-paragraph.test`: + +`TEST_RN_PLATFORM=ios npm run native device-tests:local gutenberg-editor-paragraph.test` + +Note: You might experience problems that seem to be related to the tests starting the Appium server, e.g. errors that say `Connection Refused`, `Connection Reset` or `The requested environment is not available`. For now, you can manually start the Appium server via [appium desktop](https://github.com/appium/appium-desktop) or the CLI, then change the port number in the tests while (optionally) commenting out related code in the `beforeAll` and `afterAll` block. + +For a more detailed outline of the UI tests and how to get started writing one, please visit the [UI Test documentation](/packages/react-native-editor/__device-tests__/README.md) and our [contributing guide](/packages/react-native-editor/__device-tests__/CONTRIBUTING.md). + +You might want to use Visual Studio Code as an editor. The project includes the configuration needed to use the above codestyle and linting tools automatically. + +## License + +Gutenberg Mobile is an Open Source project covered by the [GNU General Public License version 2](LICENSE). diff --git a/packages/react-native-editor/RELEASE-NOTES.txt b/packages/react-native-editor/RELEASE-NOTES.txt new file mode 100644 index 00000000000000..7e4aadda743b90 --- /dev/null +++ b/packages/react-native-editor/RELEASE-NOTES.txt @@ -0,0 +1,222 @@ +1.31.0 +------ +* [**] Add support for customizing gradient type and angle in Buttons and Cover blocks. +* [*] Show content information (block, word and characters counts). +* [*] [Android] Fix handling of upload completion while re-opening the editor + +1.30.0 +------ +* [**] Adds editor support for theme defined colors and theme defined gradients on cover and button blocks. +* [*] Support for breaking out of captions/citation authors by pressing enter on the following blocks: image, video, gallery, quote, and pullquote. + +1.29.1 +------ +* Revert Creating undo levels less frequently + +1.29.0 +------ +* [**] Add support for changing overlay color settings in Cover block +* Add enter/exit animation in FloatingToolbar +* [***] New block: Verse +* [*] Fix merging of text blocks when text had active formatting (bold, italic, strike, link) +* [***] Trash icon that is used to remove blocks is moved to the new menu reachable via ellipsis button in the block toolbar +* [**] Block toolbar can now collapse when the block width is smaller than the toolbar content +* [**] Creating undo levels less frequently +* [**] Tooltip for page template selection buttons +* [*] Fix button alignment in page templates and make strings consistent +* [*] Add support for displaying radial gradients in Buttons and Cover blocks +1.28.2 +------ +* [***] Disable Pullquote Block on Android + +1.28.1 +------ +* [**] Avoid crash when editor selection state becomes invalid + +1.28.0 +------ +* [***] New block: Pullquote +* [**] Add support for changing background and text color in Buttons block +* [*] Fix the icons and buttons in Gallery, Paragraph, List and MediaText block on RTL mode +* [**] Remove Subscription Button from the Blog template since it didn't have an initial functionality and it is hard to configure for users. +* [**] [iOS] Add support for the subscript `` and superscript ``HTML elements in text blocks +* [**] Update page templates to use recently added blocks + +1.27.1 +------ +* Remove Subscription Button from the Blog template since it didn't have an initial functionality and it is hard to configure for users. + +1.27.0 +------ +* Block Editor: Add dialog for mentioning other users in your post +* Prefill caption for image blocks when available on the Media library +* New block: Buttons. From now you’ll be able to add the individual Button block only inside the Buttons block +* Fix bug where whitespaces at start of text blocks were being removed +* Add support for upload options in Cover block +* [Android] Floating toolbar, previously located above nested blocks, is now placed at the top of the screen +* [iOS] Floating toolbar, previously located above nested blocks, is now placed at the bottom of the screen +* Fix the icons in FloatingToolbar on RTL mode +* [Android] Add alignment options for heading block +* Fix Quote block so it visually reflects selected alignment +* Fix bug where buttons in page templates were not rendering correctly on web + +1.26.0 +------ +* [iOS] Disable ripple effect in all BottomSheet's controls. +* [Android] Disable ripple effect for Slider control +* New block: Columns +* New starter page template: Blog +* Make Starter Page Template picker buttons visible only when the screen height is enough +* Fix a bug which caused to show URL settings modal randomly when changing the device orientation multiple times during the time Starter Page Template Preview is open + +1.25.0 +------ +* New block: Cover +* [Android] Dark Mode +* [Android] Improve icon on the "Take a Video" media option +* Removed the dimming effect on unselected blocks +* [iOS] Add alignment options for heading block +* Implemented dropdown toolbar for alignment toolbar in Heading, Paragraph, Image, MediaText blocks +* Block Editor: When editing link settings, tapping the keyboard return button now closes the settings panel as well as closing the keyboard. +* [Android] Show an "Edit" button overlay on selected image blocks + +1.24.0 +------ +* New block: Latest Posts +* Fix Quote block's left border not being visible in Dark Mode +* Added Starter Page Templates: when you create a new page, we now show you a few templates to get started more quickly. +* Fix crash when pasting HTML content with embeded images on paragraphs + +1.23.0 +------ +* New block: Group +* Add support for upload options in Gallery block +* Add support for size options in the Image block +* New block: Button +* Add scroll support inside block picker and block settings +* [Android] Fix issue preventing correct placeholder image from displaying during image upload +* [iOS] Fix diplay of large numbers on ordered lists +* Fix issue where adding emojis to the post title add strong HTML elements to the title of the post +* [iOS] Fix issue where alignment of paragraph blocks was not always being respected when splitting the paragraph or reading the post's html content. +* We’ve introduced a new toolbar that floats above the block you’re editing, which makes navigating your blocks easier — especially complex ones. + +1.22.0 +------ +* Make inserter to show options on long-press to add before/after +* Retry displaying image when connectivity restores +* [iOS] Show an "Edit" button overlay on selected image blocks +* [Android] Fix blank post when sharing media from another app +* Add support for image size options in the gallery block +* Fix issue that sometimes prevented merging paragraph blocks + +1.21.0 +------ +* Reduced padding around text on Rich Text based blocks. +* [Android] Improved stability on very long posts. + +1.20.0 +------ +* Fix bug where image placeholders would sometimes not be shown +* Fix crash on undo +* Style fixes on the navigation UI +* [iOS] Fix focus issue +* New block: Shortcode. You can now create and edit Shortcode blocks in the editor. + +1.19.0 +------ +* Add support for changing Settings in List Block. +* [iOS] Fix crash dismissing bottom-sheet after device rotation. +* [Android] Add support for Preformatted block. +* New block: Gallery. You can now create image galleries using WordPress Media library. Upload feature is coming soon. +* Add support for Video block settings + +1.18.0 +------ +* [iOS] Added native fullscreen preview when clicking image from Image Block +* New block: Spacer + +1.17.0 +------ +* Include block title in Unsupported block's UI +* Show new-block-indicator when no blocks at all and when at the last block +* Use existing links in the clipboard to prefill url field when inserting new link. +* Media & Text block alignment options +* Add alignment controls for paragraph blocks +* [iOS] Fix issue where the keyboard would not capitalize sentences correctly on some cases. +* [iOS] Support for Pexels image library +* [Android] Added native fullscreen preview when clicking image from Image Block +* [iOS] Add support for Preformatted block. +* [Android] Fix issue when removing image/page break block crashes the app + +1.16.1 +------ +* [iOS] Fix tap on links bug that reappear on iOS 13.2 + +1.16.0 +------ +* [Android] Add support for pexels images +* Add left, center, and right image alignment controls +1.15.3 +------ +* [iOS] Fix a layout bug in RCTAztecView in iOS 13.2 + +1.15.2 +------ +* Fix issue when copy/paste photos from other apps, was not inserting an image on the post. +* Fix issue where the block inserter layout wasn't correct after device rotation. + +1.15.0 +------ +* Fix issue when multiple media selection adds only one image or video block on Android +* Fix issue when force Touch app shortcut doesn't work properly selecting "New Photo Post" on iOS +* Add Link Target (Open in new tab) to Image Block. +* [iOS] DarkMode improvements. +* [iOS] Update to iOS 11 and Swift 5 +* New block: Media & Text + +1.14.0 +------ +* Fix a bug on iOS 13.0 were tapping on a link opens Safari +* Fix a link editing issue, where trying to add a empty link at the start of another link would remove the existing link. +* Fix missing content on long posts in html mode on Android + +1.12.0 +------ +* Add rich text styling to video captions +* Prevent keyboard dismissal when switching between caption and text block on Android +* Blocks that would be replaced are now hidden when add block bottom sheet displays +* Tapping on empty editor area now always inserts new block at end of post + +1.11.0 +------ +* Toolbar scroll position now resets when its content changes. +* Dark Mode for iOS. + +1.10.0 +------ +* Adding a block from the post title now shows the add block here indicator. +* Deselect post title any time a block is added +* Fix loss of center alignment in image captions on Android + +1.9.0 +------ +* Enable video block on Android platform +* Tapping on an empty editor area will create a new paragraph block +* Fix content loss issue when loading unsupported blocks containing inner blocks. +* Adding a block from the Post Title now inserts the block at the top of the Post. + +1.8.0 +------ +* Fix pasting simple text on Post Title +* Remove editable empty line after list on the List block +* Performance improvements on rich text editing + +1.7.0 +------ +* Fixed keyboard flickering issue after pressing Enter repeatedly on the Post Title. +* New blocks are available: video/quote/more + +1.6.0 +------ +* Fixed issue with link settings where “Open in New Tab” was always OFF on open. +* Added UI to display a warning when a block has invalid content. diff --git a/packages/react-native-editor/__device-tests__/CONTRIBUTING.md b/packages/react-native-editor/__device-tests__/CONTRIBUTING.md new file mode 100644 index 00000000000000..057cbfc84a36db --- /dev/null +++ b/packages/react-native-editor/__device-tests__/CONTRIBUTING.md @@ -0,0 +1,44 @@ +Writing a UI test? Great! 😬 This guide is here to help fill in some of the blanks of how the tests are written now and how you can add a new one. + +You can find our on-device UI tests in the `__device-tests__` folder and that's where all of the code for that really lives. +The test suite follows a sort of [Page Object Pattern](https://webdriver.io/docs/pageobjects.html), the `__device-tests__/pages/editor-page.js` manages all interactions with the pages and the `__device-tests__/gutenberg-editor.test.js` actually uses the functions made available via the Page Object `EditorPage` to drive the test cases. At the time of writing this, all the tests live there but as the suite gets large it might be better to manage different classes of tests in different files. + +So what does the process for writing a test look like? Here are some steps that I hope can help make this easier, + +### First, define the scenario + +- What are the actions that need to take place here? Walk through the scenario and manually to have an idea of what the test steps will need to do, the elements you'll need to interact with and how you're going to need to interact with them. I found it helps to properly define the steps taken in the scenario and the different user interactions that are needed to accomplish it. + +You'd just add a new scenario to the test file as well that would look something like, + +```javscript +it( 'should be able to do something', async () => { + // Code to do something... +} ); +``` + +That first parameter in the block above is where you'd put a short description of the scenario while the next parameter is the code you'd like to execute. + +### Second, figure out how to find the elements + +- The UI tests rely on locator strategies to identify elements... There's a number of locator strategies available to use and [this blog post](https://saucelabs.com/blog/advanced-locator-strategies) describes in a little more detail what a few of these are and how to use them. You'll need to start thinking about what locator strategy you'll need to use to find the elements you need if it isn't already available. +- The preferred strategy is the accessibility identifier and in a lot of cases this might not be possible and you'll have to resort to other less robust alternatives such as XPath. + +There's a few tools you have available to figure out what you need. + +For Android, you can fire up the app and then within Android Studio select `Tools -> Layout Inspector` which will then open up a `.li` file which you can then use to inspect various areas of the app, here's a [screenshot](https://d.pr/free/i/anU50R) of what that looks like. + +For iOS, you can also fire up and use the accessibility inspector, which is an app that should come available on your OSX machine. From there you can choose the process running your simulator and inspect various areas of the app. + +Alternative for both of these platforms and for an interface to simulate the commands I'd recommend [Appium Desktop](https://github.com/appium/appium-desktop/releases/tag/v1.12.1). A great tool for inspecting the view hierarchy and interacting with elements on screen as your test would. Here's a [screenshot](https://d.pr/free/i/GziQ5Q) of what that would look like. + +Using one or a combination of these tools will make it much easier to identify what locator strategy you're going to use or which elements need accessibility identifiers to ease the search process without affecting VoiceOver features. + +### Finally, once you've figured out how you're going to find the elements + +- You'll write any functions needed to interact with the page in the `EditorPage` page object and then call those interactions within the test. The code you'll need to write to actually do the finding will use a combination of + +- Appium's spec http://appium.io/docs/en/about-appium/intro/ which you can find examples of a variety of functions under the commands tab +- WebDriver I/O Appium protocols https://webdriver.io/docs/api/appium.html which provides examples and descriptions of what those look like. + +It takes some getting use to but looking at the existing code should be helpful in identifying common commands that it'd help to be familiar with. diff --git a/packages/react-native-editor/__device-tests__/README.md b/packages/react-native-editor/__device-tests__/README.md new file mode 100644 index 00000000000000..28bead00f73fe3 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/README.md @@ -0,0 +1,56 @@ +# Overview + +We use [appium](http://appium.io/) combined with [SauceLabs](https://saucelabs.com/) as an on-device testing solution for covering writing flows using Gutenberg blocks. + +Appium is built on the idea that testing native apps shouldn't require including an SDK or recompiling your app. And that you should be able to use your preferred test practices, frameworks, and tools. Appium is an open source project and has made design and tool decisions to encourage a vibrant contributing community. + +SauceLabs is a cloud hosting platform that provides access to a variety of simulators, emulators and real devices. + +## Getting set up to run the tests + +### Emulators && Simulators + +iOS: Once you've already set up XCode and the simulators you should be good to go to run the tests on an iOS simulator. + +Android: You'll need to have created the emulator images and fired up the desired emulator before running the tests against an Android emulator. + +### Real Devices + +TBA + +## Running the tests locally + +TLDR; to run the tests locally ensure metro isn't running and then run `yarn test:e2e:ios:local` and `yarn test:e2e:android:local` for the desired platform. + +Those commands include the process to build a testable version of the app, if it's the case you don't want to run the +full suite and want to run a specific file or files you can use the e2e build commands that can be found in the package.json for the respective platform and then +run `TEST_RN_PLATFORM=android yarn device-tests ` where the pattern can just be the file path. + +### Starting the Appium Server + +One of the Caveats to using Appium is the need for the Appium server to be running to interact with the Simulator or Device through Webdriver, as a result the appium server will need to be started before running the tests. To make the entire process easier in the `beforeAll` block of the tests an Appium instance is fired up on a default port of 4723. If you already have something running on that port and would rather not stop that you can change the port within the code that starts that up. At the moment that port number is referenced from the config located at `__device-tests__/helpers/serverConfigs.js`. The process is killed in the `afterAll` block but at the time of writing this there's a small chance some errors might cause it not to get there so it might be best to kill the process yourself if you think something is up. The server output when running the tests are written to `appium-out.log`, this can provide useful information when debugging the issues with the tests. + +### WebDriver capabilities + +Appium uses a config object that contains `capabilities` to define how it will connect to a simulator or device, this object is currently located in `__device-tests__/helpers/caps.js` and then referenced when firing up the driver. There are two values that I think are important to know and that's + +- `platformVersion` which is the platform version of a connected adb device. e.g `9.0` for Android or `12.2` for iOS. The version used here is upper bounded by the max allowed on CI but feel free to change this value locally as needed. +- `app` which is the absolute path to the `.app` or `.apk` file or the path relative to the **Appium root**. It's important to note that that when using the relative paths it's not to the project folder but to the appium server, since by default we start up appium in the project root when running the paths appear relative to the root but if you were using another instance of the Appium server the relative path would need to come from there. + +A full spec on the capabilities can be found [here](http://appium.io/docs/en/writing-running-appium/caps/). If you'd like to change configurations like +what port appium runs on or what device or emulator the tests should be executed on that file would be where you'd like to make that update. + +## The run process + +At the moment when running locally, the app attempts to fire up an appium server and then connects to it via webdriver. Then + +* on Android, a debug version of the app is bundled, built, and used. +* on iOS a release version is bundled built and used. + +**It's important to ensure that **metro is not running.** This would cause the value of the `__DEV__` variable to be true and load up the sample blocks.** + +After the build is complete, an appium server is fired up on port 4723 and the device tests are ran on the connected device/simulator. + +----- + +To read more about writing your own tests please read the [contributing guide](https://github.com/wordpress-mobile/gutenberg-mobile/blob/develop/__device-tests__/CONTRIBUTING.md) diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js new file mode 100644 index 00000000000000..2d8ce89ffda3ef --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-block-insertion.test.js @@ -0,0 +1,155 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, + swipeDown, + clickMiddleOfElement, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests for Block insertion', () => { + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + // wait for the block editor to load + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to insert block into post', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + let paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.sendTextToParagraphBlock( 1, testData.longText ); + // Should have 3 paragraph blocks at this point + + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + await paragraphBlockElement.click(); + + await editorPage.addNewBlock( paragraphBlockName ); + + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 3 + ); + await paragraphBlockElement.click(); + await editorPage.sendTextToParagraphBlock( 3, testData.mediumText ); + + await editorPage.verifyHtmlContent( testData.blockInsertionHtml ); + + // wait for the block editor to load and for accessibility ids to update + await driver.sleep( 3000 ); + + // Workaround for now since deleting the first element causes a crash on CI for Android + if ( isAndroid() ) { + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 3, + { + autoscroll: true, + } + ); + + await paragraphBlockElement.click(); + await editorPage.removeBlockAtPosition( paragraphBlockName, 3 ); + for ( let i = 3; i > 0; i-- ) { + // wait for accessibility ids to update + await driver.sleep( 1000 ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + i, + { + autoscroll: true, + } + ); + await paragraphBlockElement.click(); + await editorPage.removeBlockAtPosition( paragraphBlockName, i ); + } + } else { + for ( let i = 4; i > 0; i-- ) { + // wait for accessibility ids to update + await driver.sleep( 1000 ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + await clickMiddleOfElement( driver, paragraphBlockElement ); + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } + } + } ); + + it( 'should be able to insert block at the beginning of post from the title', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + let paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.sendTextToParagraphBlock( 1, testData.longText ); + // Should have 3 paragraph blocks at this point + + if ( isAndroid() ) { + await editorPage.dismissKeyboard(); + } + + await swipeDown( driver ); + const titleElement = await editorPage.getTitleElement( { + autoscroll: true, + } ); + await titleElement.click(); + await titleElement.click(); + + await editorPage.addNewBlock( paragraphBlockName ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + await clickMiddleOfElement( driver, paragraphBlockElement ); + await editorPage.sendTextToParagraphBlock( 1, testData.mediumText ); + await paragraphBlockElement.click(); + await editorPage.verifyHtmlContent( + testData.blockInsertionHtmlFromTitle + ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js new file mode 100644 index 00000000000000..5872ad69803d0f --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-gallery.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Gallery Block tests', () => { + let driver; + let editorPage; + let allPassed = true; + const galleryBlockName = 'Gallery'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add a gallery block', async () => { + await editorPage.addNewBlock( galleryBlockName ); + const galleryBlock = await editorPage.getBlockAtPosition( + galleryBlockName + ); + + expect( galleryBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( galleryBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js new file mode 100644 index 00000000000000..3a40a08df918fa --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-heading.test.js @@ -0,0 +1,103 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests @canary', () => { + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + const headingBlockName = 'Heading'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to create a post with heading and paragraph blocks', async () => { + await editorPage.addNewBlock( headingBlockName ); + let headingBlockElement = await editorPage.getBlockAtPosition( + headingBlockName + ); + if ( isAndroid() ) { + await headingBlockElement.click(); + } + await editorPage.sendTextToHeadingBlock( + headingBlockElement, + testData.heading, + false + ); + + await editorPage.addNewBlock( paragraphBlockName ); + let paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.mediumText + ); + + await editorPage.addNewBlock( paragraphBlockName ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 3 + ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.mediumText + ); + + await editorPage.addNewBlock( headingBlockName ); + headingBlockElement = await editorPage.getBlockAtPosition( + headingBlockName, + 4 + ); + await editorPage.typeTextToParagraphBlock( + headingBlockElement, + testData.heading + ); + + await editorPage.addNewBlock( paragraphBlockName ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 5 + ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.mediumText + ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js new file mode 100644 index 00000000000000..a96e61a1c133e4 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-image.test.js @@ -0,0 +1,90 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, + clickMiddleOfElement, + swipeUp, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Image Block tests @canary', () => { + let driver; + let editorPage; + let allPassed = true; + const imageBlockName = 'Image'; + const paragraphBlockName = 'Paragraph'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add an image block', async () => { + await editorPage.addNewBlock( imageBlockName ); + let imageBlock = await editorPage.getBlockAtPosition( imageBlockName ); + + // Can only add image from media library on iOS + if ( ! isAndroid() ) { + await editorPage.selectEmptyImageBlock( imageBlock ); + await editorPage.chooseMediaLibrary(); + + // Workaround because of #952 + const titleElement = await editorPage.getTitleElement(); + await clickMiddleOfElement( driver, titleElement ); + await editorPage.dismissKeyboard(); + // end workaround + + imageBlock = await editorPage.getBlockAtPosition( imageBlock ); + await swipeUp( driver, imageBlock ); + await editorPage.enterCaptionToSelectedImageBlock( + testData.imageCaption, + true + ); + await editorPage.dismissKeyboard(); + } + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.sendTextToParagraphBlock( 2, testData.shortText ); + + // skip HTML check for Android since we couldn't add image from media library + if ( ! isAndroid() ) { + await editorPage.verifyHtmlContent( testData.imageShorteHtml ); + } + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js new file mode 100644 index 00000000000000..160965d1afe967 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-latest-posts.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Latest Post Block tests', () => { + let driver; + let editorPage; + let allPassed = true; + const lastPostBlockName = 'Latest Posts'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add a Latests-Posts block', async () => { + await editorPage.addNewBlock( lastPostBlockName ); + const latestPostsBlock = await editorPage.getBlockAtPosition( + lastPostBlockName + ); + + expect( latestPostsBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( lastPostBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js new file mode 100644 index 00000000000000..09fc2ce7d1d5b3 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-canary.test.js @@ -0,0 +1,97 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + isAndroid, + isLocalEnvironment, + setupDriver, + stopDriver, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests for List block @canary', () => { + let driver; + let editorPage; + let allPassed = true; + const listBlockName = 'List'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add a new List block', async () => { + await editorPage.addNewBlock( listBlockName ); + const listBlockElement = await editorPage.getBlockAtPosition( + listBlockName + ); + // Click List block on Android to force EditText focus + if ( isAndroid() ) { + await listBlockElement.click(); + } + + // Send the first list item text + await editorPage.sendTextToListBlock( + listBlockElement, + testData.listItem1 + ); + + // send an Enter + await editorPage.sendTextToListBlock( listBlockElement, '\n' ); + + // Send the second list item text + await editorPage.sendTextToListBlock( + listBlockElement, + testData.listItem2 + ); + + // switch to html and verify html + await editorPage.verifyHtmlContent( testData.listHtml ); + } ); + + // This test depends on being run immediately after 'should be able to add a new List block' + it( 'should update format to ordered list, using toolbar button', async () => { + let listBlockElement = await editorPage.getBlockAtPosition( + listBlockName + ); + + // Click List block to force EditText focus + await listBlockElement.click(); + + // Send a click on the order list format button + await editorPage.clickOrderedListToolBarButton(); + + // switch to html and verify html + await editorPage.verifyHtmlContent( testData.listHtmlOrdered ); + + // Remove list block to return editor to empty state + listBlockElement = await editorPage.getBlockAtPosition( listBlockName ); + await listBlockElement.click(); + await editorPage.removeBlockAtPosition( listBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js new file mode 100644 index 00000000000000..a39edd83c9fc29 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists-end.test.js @@ -0,0 +1,73 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests for List block (end)', () => { + let driver; + let editorPage; + let allPassed = true; + const listBlockName = 'List'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to end a List block', async () => { + await editorPage.addNewBlock( listBlockName ); + const listBlockElement = await editorPage.getBlockAtPosition( + listBlockName + ); + + // Click List block on Android to force EditText focus + if ( isAndroid() ) { + await listBlockElement.click(); + } + + // Send the first list item text + await editorPage.sendTextToListBlock( + listBlockElement, + testData.listItem1 + ); + + // send an Enter + await editorPage.sendTextToListBlock( listBlockElement, '\n' ); + + // send an Enter + await editorPage.sendTextToListBlock( listBlockElement, '\n' ); + + await editorPage.verifyHtmlContent( testData.listEndedHtml ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js new file mode 100644 index 00000000000000..3ce5a3b9fece8a --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-lists.test.js @@ -0,0 +1,78 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + backspace, + isAndroid, + isLocalEnvironment, + setupDriver, + stopDriver, +} from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests for List block', () => { + let driver; + let editorPage; + let allPassed = true; + const listBlockName = 'List'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + // Prevent regression of https://github.com/wordpress-mobile/gutenberg-mobile/issues/871 + it( 'should handle spaces in a list', async () => { + await editorPage.addNewBlock( listBlockName ); + let listBlockElement = await editorPage.getBlockAtPosition( + listBlockName + ); + // Click List block on Android to force EditText focus + if ( isAndroid() ) { + await listBlockElement.click(); + } + + // Send the list item text + await editorPage.sendTextToListBlock( listBlockElement, ' a' ); + + // send an Enter + await editorPage.sendTextToListBlock( listBlockElement, '\n' ); + + // send a backspace + await editorPage.sendTextToListBlock( listBlockElement, backspace ); + + // switch to html and verify html + await editorPage.verifyHtmlContent( ` +
  • a
+` ); + + // Remove list block to reset editor to clean state + listBlockElement = await editorPage.getBlockAtPosition( listBlockName ); + await listBlockElement.click(); + await editorPage.removeBlockAtPosition( listBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js new file mode 100644 index 00000000000000..7b6aed2b2266c3 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-more.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Spacer Block test', () => { + let driver; + let editorPage; + let allPassed = true; + const moreBlockName = 'More'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add an separator block', async () => { + await editorPage.addNewBlock( moreBlockName ); + const separatorBlock = await editorPage.getBlockAtPosition( + moreBlockName + ); + + expect( separatorBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( moreBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js new file mode 100644 index 00000000000000..798247294c815a --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paragraph.test.js @@ -0,0 +1,247 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + backspace, + setupDriver, + isLocalEnvironment, + clickMiddleOfElement, + clickBeginningOfElement, + stopDriver, + swipeUp, + isAndroid, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests for Paragraph Block', () => { + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add a new Paragraph block', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.shortText + ); + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } ); + + it( 'should be able to split one paragraph block into two', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.shortText + ); + const textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement + ); + await clickMiddleOfElement( driver, textViewElement ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + '\n', + false + ); + expect( + ( await editorPage.hasBlockAtPosition( 1, paragraphBlockName ) ) && + ( await editorPage.hasBlockAtPosition( 2, paragraphBlockName ) ) + ).toBe( true ); + + const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 ); + const text1 = await editorPage.getTextForParagraphBlockAtPosition( 2 ); + expect( text0 ).not.toBe( '' ); + expect( text1 ).not.toBe( '' ); + expect( testData.shortText ).toMatch( + new RegExp( `${ text0 + text1 }|${ text0 } ${ text1 }` ) + ); + + await editorPage.removeBlockAtPosition( paragraphBlockName, 2 ); + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } ); + + it( 'should be able to merge 2 paragraph blocks into 1', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + let paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.shortText + ); + let textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement + ); + await clickMiddleOfElement( driver, textViewElement ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + '\n' + ); + expect( + ( await editorPage.hasBlockAtPosition( 1, paragraphBlockName ) ) && + ( await editorPage.hasBlockAtPosition( 2, paragraphBlockName ) ) + ).toBe( true ); + + const text0 = await editorPage.getTextForParagraphBlockAtPosition( 1 ); + const text1 = await editorPage.getTextForParagraphBlockAtPosition( 2 ); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement + ); + await clickBeginningOfElement( driver, textViewElement ); + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + backspace + ); + + const text = await editorPage.getTextForParagraphBlockAtPosition( 1 ); + expect( text0 + text1 ).toMatch( text ); + + expect( + await editorPage.hasBlockAtPosition( 2, paragraphBlockName ) + ).toBe( false ); + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } ); + + it( 'should be able to create a post with multiple paragraph blocks', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.sendTextToParagraphBlock( 1, testData.longText ); + + for ( let i = 3; i > 0; i-- ) { + await swipeUp( driver ); + await editorPage.removeBlockAtPosition( paragraphBlockName, i ); + } + } ); + + // Restricting these test to Android because I was not able to update the html on iOS + if ( isAndroid() ) { + it( 'should be able to merge blocks with unknown html elements', async () => { + await editorPage.setHtmlContentAndroid( ` + +

abcD

+ + + +

E

+` ); + + // // Merge paragraphs + const secondParagraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + await clickBeginningOfElement( + driver, + secondParagraphBlockElement + ); + await editorPage.typeTextToParagraphBlock( + secondParagraphBlockElement, + backspace + ); + + // verify the editor has not crashed + const text = await editorPage.getTextForParagraphBlockAtPosition( + 1 + ); + expect( text.length ).not.toEqual( 0 ); + + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } ); + + // Based on https://github.com/wordpress-mobile/gutenberg-mobile/pull/1507 + it( 'should handle multiline paragraphs from web', async () => { + await editorPage.setHtmlContentAndroid( ` + +

multiple lines

+ + + +

+ ` ); + + // // Merge paragraphs + const secondParagraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + await clickBeginningOfElement( + driver, + secondParagraphBlockElement + ); + await editorPage.typeTextToParagraphBlock( + secondParagraphBlockElement, + backspace + ); + + // verify the editor has not crashed + const text = await editorPage.getTextForParagraphBlockAtPosition( + 1 + ); + expect( text.length ).not.toEqual( 0 ); + + await editorPage.removeBlockAtPosition( paragraphBlockName ); + } ); + } + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js new file mode 100644 index 00000000000000..75f18abd3c2511 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-paste.test.js @@ -0,0 +1,139 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + longPressMiddleOfElement, + tapSelectAllAboveElement, + tapCopyAboveElement, + tapPasteAboveElement, + stopDriver, + isAndroid, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor paste tests', () => { + // skip iOS for now + if ( ! isAndroid() ) { + it( 'skips the tests on any platform other than Android', async () => {} ); + return; + } + + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + await driver.setClipboard( '', 'plaintext' ); + editorPage = new EditorPage( driver ); + } ); + + it( 'copies plain text from one paragraph block and pastes in another', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.pastePlainText + ); + const textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement + ); + + // copy content to clipboard + await longPressMiddleOfElement( driver, textViewElement ); + await tapSelectAllAboveElement( driver, textViewElement ); + await tapCopyAboveElement( driver, textViewElement ); + + // create another paragraph block + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement2 = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + if ( isAndroid() ) { + await paragraphBlockElement2.click(); + } + + const textViewElement2 = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement2 + ); + + // paste into second paragraph block + await longPressMiddleOfElement( driver, textViewElement2 ); + await tapPasteAboveElement( driver, textViewElement2 ); + + const text = await editorPage.getTextForParagraphBlockAtPosition( 2 ); + expect( text ).toBe( testData.pastePlainText ); + } ); + + it( 'copies styled text from one paragraph block and pastes in another', async () => { + // create paragraph block with styled text by editing html + await editorPage.setHtmlContentAndroid( testData.pasteHtmlText ); + const paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + const textViewElement = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement + ); + + // copy content to clipboard + await longPressMiddleOfElement( driver, textViewElement ); + await tapSelectAllAboveElement( driver, textViewElement ); + await tapCopyAboveElement( driver, textViewElement ); + + // create another paragraph block + await editorPage.addNewBlock( paragraphBlockName ); + const paragraphBlockElement2 = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + if ( isAndroid() ) { + await paragraphBlockElement2.click(); + } + + const textViewElement2 = await editorPage.getTextViewForParagraphBlock( + paragraphBlockElement2 + ); + + // paste into second paragraph block + await longPressMiddleOfElement( driver, textViewElement2 ); + await tapPasteAboveElement( driver, textViewElement2 ); + + // check styled text by verifying html contents + await editorPage.verifyHtmlContent( testData.pasteHtmlTextResult ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js new file mode 100644 index 00000000000000..85e426aa5dff3f --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-rotation.test.js @@ -0,0 +1,94 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { + setupDriver, + isLocalEnvironment, + stopDriver, + isAndroid, + toggleOrientation, +} from './helpers/utils'; +import testData from './helpers/test-data'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor tests', () => { + let driver; + let editorPage; + let allPassed = true; + const paragraphBlockName = 'Paragraph'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add blocks , rotate device and continue adding blocks', async () => { + await editorPage.addNewBlock( paragraphBlockName ); + let paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName + ); + if ( isAndroid() ) { + await paragraphBlockElement.click(); + } + + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.mediumText + ); + + await toggleOrientation( driver ); + // On Android the keyboard hides the add block button, let's hide it after rotation + if ( isAndroid() ) { + await driver.hideDeviceKeyboard(); + } + + await editorPage.addNewBlock( paragraphBlockName ); + + if ( isAndroid() ) { + await driver.hideDeviceKeyboard(); + } + + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + while ( ! paragraphBlockElement ) { + await driver.hideDeviceKeyboard(); + paragraphBlockElement = await editorPage.getBlockAtPosition( + paragraphBlockName, + 2 + ); + } + await editorPage.typeTextToParagraphBlock( + paragraphBlockElement, + testData.mediumText + ); + await toggleOrientation( driver ); + + await editorPage.verifyHtmlContent( testData.deviceRotationHtml ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js new file mode 100644 index 00000000000000..438e1a5c1c9c5b --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-separator.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Separator Block test', () => { + let driver; + let editorPage; + let allPassed = true; + const separatorBlockName = 'Separator'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add an separator block', async () => { + await editorPage.addNewBlock( separatorBlockName ); + const separatorBlock = await editorPage.getBlockAtPosition( + separatorBlockName + ); + + expect( separatorBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( separatorBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js new file mode 100644 index 00000000000000..2aa09cc523bb15 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-spacer.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Spacer Block test', () => { + let driver; + let editorPage; + let allPassed = true; + const spacerBlockName = 'Spacer'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add an separator block', async () => { + await editorPage.addNewBlock( spacerBlockName ); + const separatorBlock = await editorPage.getBlockAtPosition( + spacerBlockName + ); + + expect( separatorBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( spacerBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js b/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js new file mode 100644 index 00000000000000..bc8412a3ee832f --- /dev/null +++ b/packages/react-native-editor/__device-tests__/gutenberg-editor-verse.test.js @@ -0,0 +1,51 @@ +/** + * Internal dependencies + */ +import EditorPage from './pages/editor-page'; +import { setupDriver, isLocalEnvironment, stopDriver } from './helpers/utils'; + +jest.setTimeout( 1000000 ); + +describe( 'Gutenberg Editor Verse Block Tests', () => { + let driver; + let editorPage; + let allPassed = true; + const verseBlockName = 'Verse'; + + // Use reporter for setting status for saucelabs Job + if ( ! isLocalEnvironment() ) { + const reporter = { + specDone: async ( result ) => { + allPassed = allPassed && result.status !== 'failed'; + }, + }; + + jasmine.getEnv().addReporter( reporter ); + } + + beforeAll( async () => { + driver = await setupDriver(); + editorPage = new EditorPage( driver ); + } ); + + it( 'should be able to see visual editor', async () => { + await expect( editorPage.getBlockList() ).resolves.toBe( true ); + } ); + + it( 'should be able to add a verse block', async () => { + await editorPage.addNewBlock( verseBlockName ); + const verseBlock = await editorPage.getBlockAtPosition( + verseBlockName + ); + + expect( verseBlock ).toBeTruthy(); + await editorPage.removeBlockAtPosition( verseBlockName ); + } ); + + afterAll( async () => { + if ( ! isLocalEnvironment() ) { + driver.sauceJobStatus( allPassed ); + } + await stopDriver( driver ); + } ); +} ); diff --git a/packages/react-native-editor/__device-tests__/helpers/appium-local.js b/packages/react-native-editor/__device-tests__/helpers/appium-local.js new file mode 100644 index 00000000000000..71a0cd44aea18b --- /dev/null +++ b/packages/react-native-editor/__device-tests__/helpers/appium-local.js @@ -0,0 +1,53 @@ +/** + * External dependencies + */ +import childProcess from 'child_process'; + +// Spawns an appium process +export const start = ( localAppiumPort ) => + new Promise( ( resolve, reject ) => { + const appium = childProcess.spawn( 'appium', [ + '--port', + localAppiumPort.toString(), + '--log', + './appium-out.log', + '--log-no-colors', + '--relaxed-security', // Needed for mobile:shell commend for text entry on Android + ] ); + + let appiumOutputBuffer = ''; + let resolved = false; + appium.stdout.on( 'data', ( data ) => { + if ( ! resolved ) { + appiumOutputBuffer += data.toString(); + if ( + appiumOutputBuffer.indexOf( + 'Appium REST http interface listener started' + ) >= 0 + ) { + resolved = true; + resolve( appium ); + } + } + } ); + + appium.on( 'close', ( code ) => { + if ( ! resolved ) { + reject( + new Error( `Appium process exited with code ${ code }` ) + ); + } + } ); + } ); + +export const stop = async ( appium ) => { + if ( ! appium ) { + return; + } + await appium.kill( 'SIGINT' ); +}; + +export default { + start, + stop, +}; diff --git a/packages/react-native-editor/__device-tests__/helpers/caps.js b/packages/react-native-editor/__device-tests__/helpers/caps.js new file mode 100644 index 00000000000000..9b10b52d068ab1 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/helpers/caps.js @@ -0,0 +1,40 @@ +const ios = { + browserName: '', + platformName: 'iOS', + platformVersion: '13.4', + deviceName: 'iPhone 11', + os: 'iOS', + deviceOrientation: 'portrait', + automationName: 'XCUITest', + appiumVersion: '1.16.0', // SauceLabs requires appiumVersion to be specified. + app: undefined, // will be set later, locally this is relative to root of project + processArguments: { + args: [ 'uitesting' ], + }, +}; + +exports.iosLocal = { + ...ios, + platformVersion: '13.4', + deviceName: 'iPhone 11', +}; + +exports.iosServer = { + ...ios, + platformVersion: '13.0', + deviceName: 'iPhone 11 Simulator', +}; + +exports.android = { + browserName: '', + platformName: 'Android', + platformVersion: '9.0', + deviceName: 'Google Pixel 3 XL GoogleAPI Emulator', + automationName: 'UiAutomator2', + os: 'Android', + appPackage: 'com.gutenberg', + appActivity: 'com.gutenberg.MainActivity', + deviceOrientation: 'portrait', + appiumVersion: '1.16.0', + app: undefined, +}; diff --git a/packages/react-native-editor/__device-tests__/helpers/serverConfigs.js b/packages/react-native-editor/__device-tests__/helpers/serverConfigs.js new file mode 100644 index 00000000000000..d675a65229edcb --- /dev/null +++ b/packages/react-native-editor/__device-tests__/helpers/serverConfigs.js @@ -0,0 +1,10 @@ +exports.local = { + host: 'localhost', + port: 4723, // Port for local Appium runs +}; + +exports.sauce = { + host: 'ondemand.saucelabs.com', + port: 80, + auth: process.env.SAUCE_USERNAME + ':' + process.env.SAUCE_ACCESS_KEY, +}; diff --git a/packages/react-native-editor/__device-tests__/helpers/test-data.js b/packages/react-native-editor/__device-tests__/helpers/test-data.js new file mode 100644 index 00000000000000..3f6086eb074684 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/helpers/test-data.js @@ -0,0 +1,100 @@ +exports.shortText = `Rock music approaches at high velocity.`; + +exports.mediumText = `The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?`; + +exports.longText = `Beneath the busy continuum blinks the ineffective husband. Why a metric now outside the official subway? How can the prompt crop exhaust his tree +Does this chord crowd my emptied search? A theory bubbles under the cartoon. The discontinued speaker cracks every thick epic. extraordinary twin shifts behind +The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?`; + +exports.listItem1 = `Milk`; +exports.listItem2 = `Honey`; +exports.listHtml = ` +
  • Milk
  • Honey
+`; +exports.listHtmlOrdered = ` +
  1. Milk
  2. Honey
+`; +exports.listEndedHtml = ` +
  • Milk
+ + + +

+`; +exports.heading = 'Lorem Ipsum'; + +exports.pastePlainText = `Hello paste`; + +const pastedHtmlText = ` +

Hello paste

+`; + +exports.pasteHtmlText = pastedHtmlText; + +exports.pasteHtmlTextResult = `${ pastedHtmlText }\n\n${ pastedHtmlText }`; + +exports.deviceRotationHtml = ` +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+ + + +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+`; + +exports.blockInsertionHtml = ` +

Beneath the busy continuum blinks the ineffective husband. Why a metric now outside the official subway? How can the prompt crop exhaust his tree

+ + + +

Does this chord crowd my emptied search? A theory bubbles under the cartoon. The discontinued speaker cracks every thick epic. extraordinary twin shifts behind

+ + + +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+ + + +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+`; + +exports.blockInsertionHtmlFromTitle = ` +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+ + + +

Beneath the busy continuum blinks the ineffective husband. Why a metric now outside the official subway? How can the prompt crop exhaust his tree

+ + + +

Does this chord crowd my emptied search? A theory bubbles under the cartoon. The discontinued speaker cracks every thick epic. extraordinary twin shifts behind

+ + + +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+`; + +exports.imageCaption = `C'est la vie my friends`; + +exports.imageCompletehtml = ` +
C'est la vie my friends
+ + + +

Beneath the busy continuum blinks the ineffective husband. Why a metric now outside the official subway? How can the prompt crop exhaust his tree

+ + + +

Does this chord crowd my emptied search? A theory bubbles under the cartoon. The discontinued speaker cracks every thick epic. extraordinary twin shifts behind

+ + + +

The finer continuum interprets the polynomial rabbit. When can the geology runs? An astronomer runs. Should a communist consent?

+`; + +exports.imageShorteHtml = ` +
C'est la vie my friends
+ + + +

rock music approaches at high velocity.

+`; diff --git a/packages/react-native-editor/__device-tests__/helpers/utils.js b/packages/react-native-editor/__device-tests__/helpers/utils.js new file mode 100644 index 00000000000000..283e0ed0f72543 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/helpers/utils.js @@ -0,0 +1,532 @@ +/** + * External dependencies + */ +import childProcess from 'child_process'; +// eslint-disable-next-line import/no-extraneous-dependencies +import wd from 'wd'; +import crypto from 'crypto'; +import path from 'path'; +import fs from 'fs'; + +/** + * Internal dependencies + */ +import serverConfigs from './serverConfigs'; +import { iosServer, iosLocal, android } from './caps'; +import AppiumLocal from './appium-local'; +// eslint-disable-next-line import/no-extraneous-dependencies +import _ from 'underscore'; + +// Platform setup +const defaultPlatform = 'android'; +const rnPlatform = process.env.TEST_RN_PLATFORM || defaultPlatform; + +// Environment setup, local environment or Sauce Labs +const defaultEnvironment = 'local'; +const testEnvironment = process.env.TEST_ENV || defaultEnvironment; + +// Local App Paths +const defaultAndroidAppPath = + './android/app/build/outputs/apk/debug/app-debug.apk'; +const defaultIOSAppPath = + './ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app'; + +const localAndroidAppPath = + process.env.ANDROID_APP_PATH || defaultAndroidAppPath; +const localIOSAppPath = process.env.IOS_APP_PATH || defaultIOSAppPath; + +const localAppiumPort = serverConfigs.local.port; // Port to spawn appium process for local runs +let appiumProcess; +let iOSScreenRecordingProcess; +let androidScreenRecordingProcess; + +const backspace = '\u0008'; + +// Used to map unicode and special values to keycodes on Android +// Docs for keycode values: https://developer.android.com/reference/android/view/KeyEvent.html +const strToKeycode = { + '\n': 66, + [ backspace ]: 67, +}; + +const timer = ( ms ) => new Promise( ( res ) => setTimeout( res, ms ) ); + +const isAndroid = () => { + return rnPlatform.toLowerCase() === 'android'; +}; + +const isLocalEnvironment = () => { + return testEnvironment.toLowerCase() === 'local'; +}; + +const isMacOSEnvironment = () => { + return process.platform === 'darwin'; +}; + +const IOS_RECORDINGS_DIR = './ios-screen-recordings'; +const ANDROID_RECORDINGS_DIR = './android-screen-recordings'; + +const getScreenRecordingFileNameBase = ( testPath, id ) => { + const suiteName = path.basename( testPath, '.test.js' ); + return `${ suiteName }.${ id }`; +}; + +jasmine.getEnv().addReporter( { + specStarted: ( { testPath, id } ) => { + if ( ! isMacOSEnvironment() ) { + return; + } + + const fileName = + getScreenRecordingFileNameBase( testPath, id ) + '.mp4'; + + if ( isAndroid() ) { + if ( ! fs.existsSync( ANDROID_RECORDINGS_DIR ) ) { + fs.mkdirSync( ANDROID_RECORDINGS_DIR ); + } + + androidScreenRecordingProcess = childProcess.spawn( 'adb', [ + 'shell', + 'screenrecord', + '--verbose', + '--bit-rate', + '1M', + '--size', + '720x1280', + `/sdcard/${ fileName }`, + ] ); + + androidScreenRecordingProcess.stderr.on( 'data', ( data ) => { + // eslint-disable-next-line no-console + console.log( `Android screen recording error => ${ data }` ); + } ); + + return; + } + + if ( ! fs.existsSync( IOS_RECORDINGS_DIR ) ) { + fs.mkdirSync( IOS_RECORDINGS_DIR ); + } + + iOSScreenRecordingProcess = childProcess.spawn( + 'xcrun', + [ + 'simctl', + 'io', + 'booted', + 'recordVideo', + '--mask=black', + '--force', + fileName, + ], + { + cwd: IOS_RECORDINGS_DIR, + } + ); + }, + specDone: ( { testPath, id, status } ) => { + if ( ! isMacOSEnvironment() ) { + return; + } + + const fileNameBase = getScreenRecordingFileNameBase( testPath, id ); + + if ( isAndroid() ) { + androidScreenRecordingProcess.kill( 'SIGINT' ); + // wait for kill + childProcess.execSync( 'sleep 1' ); + + try { + childProcess.execSync( + `adb pull /sdcard/${ fileNameBase }.mp4 ${ ANDROID_RECORDINGS_DIR }` + ); + } catch ( error ) { + // Some (old) Android devices don't support screen recording or + // sometimes the initial `should be able to see visual editor` + // tests are too fast and a recording is not generated. This is + // when `adb pull` can't find the recording file. In these cases + // we ignore the errors and keep running the tests. + // eslint-disable-next-line no-console + console.log( + `Android screen recording error => ${ error.stdout }` + ); + } + + const oldPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.mp4`; + const newPath = `${ ANDROID_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`; + + if ( fs.existsSync( oldPath ) ) { + fs.renameSync( oldPath, newPath ); + } + return; + } + + iOSScreenRecordingProcess.kill( 'SIGINT' ); + + const oldPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.mp4`; + const newPath = `${ IOS_RECORDINGS_DIR }/${ fileNameBase }.${ status }.mp4`; + + if ( fs.existsSync( oldPath ) ) { + fs.renameSync( oldPath, newPath ); + } + }, +} ); + +// Initialises the driver and desired capabilities for appium +const setupDriver = async () => { + const branch = process.env.CIRCLE_BRANCH || ''; + const safeBranchName = branch.replace( /\//g, '-' ); + if ( isLocalEnvironment() ) { + try { + appiumProcess = await AppiumLocal.start( localAppiumPort ); + } catch ( err ) { + // Ignore error here, Appium is probably already running (Appium desktop has its own server for instance) + // eslint-disable-next-line no-console + await console.log( + 'Could not start Appium server', + err.toString() + ); + } + } + + const serverConfig = isLocalEnvironment() + ? serverConfigs.local + : serverConfigs.sauce; + const driver = wd.promiseChainRemote( serverConfig ); + + let desiredCaps; + if ( isAndroid() ) { + desiredCaps = _.clone( android ); + if ( isLocalEnvironment() ) { + desiredCaps.app = path.resolve( localAndroidAppPath ); + try { + const androidVersion = childProcess + .execSync( 'adb shell getprop ro.build.version.release' ) + .toString() + .replace( /^\s+|\s+$/g, '' ); + delete desiredCaps.platformVersion; + desiredCaps.deviceName = 'Android Emulator'; + // eslint-disable-next-line no-console + console.log( + 'Detected Android device running Android %s', + androidVersion + ); + } catch ( error ) { + // ignore error + } + } else { + desiredCaps.app = `sauce-storage:Gutenberg-${ safeBranchName }.apk`; // App should be preloaded to sauce storage, this can also be a URL + } + } else { + desiredCaps = _.clone( iosServer ); + desiredCaps.app = `sauce-storage:Gutenberg-${ safeBranchName }.app.zip`; // App should be preloaded to sauce storage, this can also be a URL + if ( isLocalEnvironment() ) { + desiredCaps = _.clone( iosLocal ); + desiredCaps.app = path.resolve( localIOSAppPath ); + } + } + + if ( ! isLocalEnvironment() ) { + desiredCaps.name = `Gutenberg Editor Tests[${ rnPlatform }]-${ branch }`; + desiredCaps.tags = [ 'Gutenberg', branch ]; + } + + await driver.init( desiredCaps ); + + const status = await driver.status(); + // Display the driver status + // eslint-disable-next-line no-console + console.log( status ); + + await driver.setImplicitWaitTimeout( 5000 ); + await timer( 5000 ); + + await driver.setOrientation( 'PORTRAIT' ); + return driver; +}; + +const stopDriver = async ( driver ) => { + if ( ! isLocalEnvironment() ) { + const jobID = driver.sessionID; + + const hash = crypto + .createHmac( 'md5', jobID ) + .update( serverConfigs.sauce.auth ) + .digest( 'hex' ); + const jobURL = `https://saucelabs.com/jobs/${ jobID }?auth=${ hash }.`; + // eslint-disable-next-line no-console + console.log( `You can view the video of this test run at ${ jobURL }` ); + } + if ( driver === undefined ) { + return; + } + await driver.quit(); + + if ( appiumProcess !== undefined ) { + await AppiumLocal.stop( appiumProcess ); + } +}; + +/* + * Problems about the 'clear' parameter: + * + * On Android: "clear" is defaulted to true because not clearing the text requires Android to use ADB, which + * has demonstrated itself to be very flaky, particularly on CI. In other words, clear the view unless you absolutely + * have to append the new text and, in that case, append fewest number of characters possible. + * + * On iOS: "clear" is not defaulted to true because calling element.clear when a text is present takes a very long time (approx. 23 seconds) + */ +const typeString = async ( driver, element, str, clear ) => { + if ( isAndroid() ) { + await typeStringAndroid( driver, element, str, clear ); + } else { + await typeStringIos( driver, element, str, clear ); + } +}; + +const typeStringIos = async ( driver, element, str, clear ) => { + if ( clear ) { + //await element.clear(); This was not working correctly on iOS so need a custom implementation + await clearTextBox( driver, element ); + } + await element.type( str ); +}; + +const clearTextBox = async ( driver, element ) => { + await element.click(); + let originalText = await element.text(); + let text = originalText; + // We are double tapping on the text field and pressing backspace until all content is removed. + do { + originalText = await element.text(); + const action = new wd.TouchAction( driver ); + action.tap( { el: element, count: 2 } ); + await action.perform(); + await element.type( '\b' ); + text = await element.text(); + // We compare with the original content and not empty because text always return any hint set on the element. + } while ( originalText !== text ); +}; + +const typeStringAndroid = async ( + driver, + element, + str, + clear = true // see comment above for why it is defaulted to true +) => { + if ( str in strToKeycode ) { + return await driver.pressKeycode( strToKeycode[ str ] ); + } else if ( clear ) { + /* + * On Android `element.type` deletes the contents of the EditText before typing and, unfortunately, + * with our blocks it also deletes the block entirely. We used to avoid this by using adb to enter + * long text along these lines: + * await driver.execute( 'mobile: shell', { command: 'input', + * args: [ 'text', 'text I want to enter...' ] } ) + * but using adb in this way proved to be very flaky (frequently all of the text would not get entered, + * particularly on CI). We are now using the `type` approach again, but adding a space to the block to + * insure it is not empty, which avoids the deletion of the block when `type` executes. + * + * Note that this approach does not allow appending text to the text in a block on account + * of `type` always clearing the block (on Android). + */ + + await driver.execute( 'mobile: shell', { + command: 'input', + args: [ 'text', '%s' ], + } ); + await element.type( str ); + } else { + // eslint-disable-next-line no-console + console.log( + 'Warning: Using `adb shell input text` on Android which is rather flaky.' + ); + + const paragraphs = str.split( '\n' ); + for ( let i = 0; i < paragraphs.length; i++ ) { + const paragraph = paragraphs[ i ].replace( /[ ]/g, '%s' ); + if ( paragraph in strToKeycode ) { + await driver.pressKeycode( strToKeycode[ paragraph ] ); + } else { + // Execute with adb shell input since normal type auto clears field on Android + await driver.execute( 'mobile: shell', { + command: 'input', + args: [ 'text', paragraph ], + } ); + } + if ( i !== paragraphs.length - 1 ) { + await driver.pressKeycode( strToKeycode[ '\n' ] ); + } + } + } +}; + +// Calculates middle x,y and clicks that position +const clickMiddleOfElement = async ( driver, element ) => { + const location = await element.getLocation(); + const size = await element.getSize(); + + const action = await new wd.TouchAction( driver ); + action.press( { x: location.x + size.width / 2, y: location.y } ); + action.release(); + await action.perform(); +}; + +// Clicks in the top left of an element +const clickBeginningOfElement = async ( driver, element ) => { + const location = await element.getLocation(); + const action = await new wd.TouchAction( driver ); + action.press( { x: location.x, y: location.y } ); + action.release(); + await action.perform(); +}; + +// long press to activate context menu +const longPressMiddleOfElement = async ( driver, element ) => { + const location = await element.getLocation(); + const size = await element.getSize(); + + const action = await new wd.TouchAction( driver ); + const x = location.x + size.width / 2; + const y = location.y + size.height / 2; + action.press( { x, y } ); + action.wait( 2000 ); + action.release(); + await action.perform(); +}; + +// press "Select All" in floating context menu +const tapSelectAllAboveElement = async ( driver, element ) => { + const location = await element.getLocation(); + const action = await new wd.TouchAction( driver ); + const x = location.x + 300; + const y = location.y - 50; + action.press( { x, y } ); + action.release(); + await action.perform(); +}; + +// press "Copy" in floating context menu +const tapCopyAboveElement = async ( driver, element ) => { + const location = await element.getLocation(); + const action = await new wd.TouchAction( driver ); + const x = location.x + 220; + const y = location.y - 50; + action.wait( 2000 ); + action.press( { x, y } ); + action.wait( 2000 ); + action.release(); + await action.perform(); +}; + +// press "Paste" in floating context menu +const tapPasteAboveElement = async ( driver, element ) => { + const location = await element.getLocation(); + const action = await new wd.TouchAction( driver ); + action.wait( 2000 ); + action.press( { x: location.x + 100, y: location.y - 50 } ); + action.wait( 2000 ); + action.release(); + await action.perform(); +}; + +// Starts from the middle of the screen or the element(if specified) +// and swipes upwards +const swipeUp = async ( driver, element = undefined ) => { + let size = await driver.getWindowSize(); + let y = 0; + if ( element !== undefined ) { + size = await element.getSize(); + const location = await element.getLocation(); + y = location.y; + } + + const startX = size.width / 2; + const startY = y + size.height / 3; + const endX = startX; + const endY = startY + startY * -1 * 0.5; + + const action = await new wd.TouchAction( driver ); + action.press( { x: startX, y: startY } ); + action.wait( 3000 ); + action.moveTo( { x: endX, y: endY } ); + action.release(); + await action.perform(); +}; + +// Starts from the middle of the screen and swipes downwards +const swipeDown = async ( driver ) => { + const size = await driver.getWindowSize(); + const y = 0; + + const startX = size.width / 2; + const startY = y + size.height / 3; + const endX = startX; + const endY = startY - startY * -1 * 0.5; + + const action = await new wd.TouchAction( driver ); + action.press( { x: startX, y: startY } ); + action.wait( 3000 ); + action.moveTo( { x: endX, y: endY } ); + action.release(); + await action.perform(); +}; + +const toggleHtmlMode = async ( driver, toggleOn ) => { + if ( isAndroid() ) { + // Hit the "Menu" key + await driver.pressKeycode( 82 ); + + // Go at the end of the popup to hit the "Show html" + // TODO: c'mon, find a more robust way to hit that item! :( + for ( let i = 0; i < 10; i++ ) { + await driver.pressKeycode( 20 ); + } + + // hit Enter + await driver.pressKeycode( 66 ); + } else { + const menuButton = await driver.elementByAccessibilityId( '...' ); + await menuButton.click(); + let toggleHtmlButton; + if ( toggleOn ) { + toggleHtmlButton = await driver.elementByAccessibilityId( + 'Switch to HTML' + ); + } else { + toggleHtmlButton = await driver.elementByAccessibilityId( + 'Switch To Visual' + ); + } + await toggleHtmlButton.click(); + } +}; + +const toggleOrientation = async ( driver ) => { + const orientation = await driver.getOrientation(); + if ( orientation === 'LANDSCAPE' ) { + await driver.setOrientation( 'PORTRAIT' ); + } else { + await driver.setOrientation( 'LANDSCAPE' ); + } +}; + +module.exports = { + backspace, + timer, + setupDriver, + isLocalEnvironment, + isAndroid, + typeString, + clickMiddleOfElement, + clickBeginningOfElement, + longPressMiddleOfElement, + tapSelectAllAboveElement, + tapCopyAboveElement, + tapPasteAboveElement, + swipeDown, + swipeUp, + stopDriver, + toggleHtmlMode, + toggleOrientation, +}; diff --git a/packages/react-native-editor/__device-tests__/pages/editor-page.js b/packages/react-native-editor/__device-tests__/pages/editor-page.js new file mode 100644 index 00000000000000..18976667843510 --- /dev/null +++ b/packages/react-native-editor/__device-tests__/pages/editor-page.js @@ -0,0 +1,473 @@ +/** + * Internal dependencies + */ +import { + isAndroid, + swipeUp, + swipeDown, + typeString, + toggleHtmlMode, +} from '../helpers/utils'; + +export default class EditorPage { + driver; + accessibilityIdKey; + accessibilityIdXPathAttrib; + paragraphBlockName = 'Paragraph'; + verseBlockName = 'Verse'; + orderedListButtonName = 'Convert to ordered list'; + + constructor( driver ) { + this.driver = driver; + this.accessibilityIdKey = 'name'; + this.accessibilityIdXPathAttrib = 'name'; + + if ( isAndroid() ) { + this.accessibilityIdXPathAttrib = 'content-desc'; + this.accessibilityIdKey = 'contentDescription'; + } + + driver.setImplicitWaitTimeout( 5000 ); + } + + async getBlockList() { + return await this.driver.hasElementByAccessibilityId( 'block-list' ); + } + + // Finds the wd element for new block that was added and sets the element attribute + // and accessibilityId attributes on this object and selects the block + // position uses one based numbering + async getBlockAtPosition( + blockName, + position = 1, + options = { autoscroll: false } + ) { + const blockLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, "${ blockName } Block. Row ${ position }")]`; + const elements = await this.driver.elementsByXPath( blockLocator ); + const lastElementFound = elements[ elements.length - 1 ]; + if ( elements.length === 0 && options.autoscroll ) { + const firstBlockVisible = await this.getFirstBlockVisible(); + const lastBlockVisible = await this.getLastBlockVisible(); + // exit if no block is found + if ( ! firstBlockVisible || ! lastBlockVisible ) { + return lastElementFound; + } + const firstBlockAccessibilityId = await firstBlockVisible.getAttribute( + this.accessibilityIdKey + ); + const firstBlockRowMatch = /Row (\d+)\./.exec( + firstBlockAccessibilityId + ); + const firstBlockRow = + firstBlockRowMatch && Number( firstBlockRowMatch[ 1 ] ); + const lastBlockAccessibilityId = await lastBlockVisible.getAttribute( + this.accessibilityIdKey + ); + const lastBlockRowMatch = /Row (\d+)\./.exec( + lastBlockAccessibilityId + ); + const lastBlockRow = + lastBlockRowMatch && Number( lastBlockRowMatch[ 1 ] ); + if ( firstBlockRow && position < firstBlockRow ) { + if ( firstBlockRow === 1 ) { + // we're at the top already stop recursing + return lastElementFound; + } + // scroll up + await swipeDown( this.driver ); + } else if ( lastBlockRow && position > lastBlockRow ) { + // scroll down + await swipeUp( this.driver ); + } + return await this.getBlockAtPosition( + blockName, + position, + options + ); + } + return lastElementFound; + } + + async getFirstBlockVisible() { + const firstBlockLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, " Block. Row ")]`; + const elements = await this.driver.elementsByXPath( firstBlockLocator ); + return elements[ 0 ]; + } + + async getLastBlockVisible() { + const firstBlockLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, " Block. Row ")]`; + const elements = await this.driver.elementsByXPath( firstBlockLocator ); + return elements[ elements.length - 1 ]; + } + + async hasBlockAtPosition( position = 1, blockName = '' ) { + return ( + undefined !== + ( await this.getBlockAtPosition( blockName, position ) ) + ); + } + + async getTitleElement( options = { autoscroll: false } ) { + //TODO: Improve the identifier for this element + const elements = await this.driver.elementsByXPath( + `//*[contains(@${ this.accessibilityIdXPathAttrib }, "Post title.")]` + ); + if ( elements.length === 0 && options.autoscroll ) { + await swipeDown( this.driver ); + return this.getTitleElement( options ); + } + return elements[ elements.length - 1 ]; + } + + async getTextViewForHtmlViewContent() { + const accessibilityId = 'html-view-content'; + let blockLocator = `//*[@${ this.accessibilityIdXPathAttrib }="${ accessibilityId }"]`; + + if ( ! isAndroid() ) { + blockLocator += '//XCUIElementTypeTextView'; + } + return await this.driver.elementByXPath( blockLocator ); + } + + // Converts to lower case and checks for a match to lowercased html content + // Ensure to take additional steps to handle text being changed by auto correct + async verifyHtmlContent( html ) { + await toggleHtmlMode( this.driver, true ); + + const htmlContentView = await this.getTextViewForHtmlViewContent(); + const text = await htmlContentView.text(); + expect( text.toLowerCase() ).toBe( html.toLowerCase() ); + + await toggleHtmlMode( this.driver, false ); + } + + // set html editor content explicitly + async setHtmlContentAndroid( html ) { + await toggleHtmlMode( this.driver, true ); + + const htmlContentView = await this.getTextViewForHtmlViewContent(); + await htmlContentView.setText( html ); + + await toggleHtmlMode( this.driver, false ); + } + + async dismissKeyboard() { + await this.driver.sleep( 1000 ); /// wait for any keyboard animations + const keyboardShown = await this.driver.isKeyboardShown(); + if ( ! keyboardShown ) { + return; + } + if ( isAndroid() ) { + return await this.driver.hideDeviceKeyboard(); + } + const hideKeyboardToolbarButton = await this.driver.elementByXPath( + '//XCUIElementTypeButton[@name="Hide keyboard"]' + ); + await hideKeyboardToolbarButton.click(); + } + + // ========================= + // Block toolbar functions + // ========================= + + async addNewBlock( blockName ) { + // Click add button + let identifier = 'Add block'; + if ( isAndroid() ) { + identifier = 'Add block, Double tap to add a block'; + } + const addButton = await this.driver.elementByAccessibilityId( + identifier + ); + await addButton.click(); + + // Click on block of choice + const blockButton = await this.findBlockButton( blockName ); + if ( isAndroid() ) { + await blockButton.click(); + } else { + await this.driver.execute( 'mobile: tap', { + element: blockButton, + x: 10, + y: 10, + } ); + } + } + + // Attempts to find the given block button in the block inserter control. + async findBlockButton( blockName ) { + if ( isAndroid() ) { + // Checks if the Block Button is available, and if not will scroll to the second half of the available buttons. + while ( + ! ( await this.driver.hasElementByAccessibilityId( blockName ) ) + ) { + await this.driver.pressKeycode( 20 ); // Press the Down arrow to force a scroll. + } + + return await this.driver.elementByAccessibilityId( blockName ); + } + + const blockButton = await this.driver.elementByAccessibilityId( + blockName + ); + const size = await this.driver.getWindowSize(); + const height = size.height - 5; + + while ( ! ( await blockButton.isDisplayed() ) ) { + await this.driver.execute( 'mobile: dragFromToForDuration', { + fromX: 50, + fromY: height, + toX: 50, + toY: height - 450, + duration: 0.5, + } ); + } + + return blockButton; + } + + async clickToolBarButton( buttonName ) { + const toolBarButton = await this.driver.elementByAccessibilityId( + buttonName + ); + await toolBarButton.click(); + } + + // ========================= + // Inline toolbar functions + // ========================= + + // position of the block to move up + async moveBlockUpAtPosition( position, blockName = '' ) { + if ( ! ( await this.hasBlockAtPosition( position, blockName ) ) ) { + throw Error( `No Block at position ${ position }` ); + } + + const parentLocator = `//*[@${ this.accessibilityIdXPathAttrib }="${ blockName } Block. Row ${ position }."]`; + let blockLocator = `${ parentLocator }/following-sibling::*`; + blockLocator += isAndroid() ? '' : '//*'; + blockLocator += `[@${ + this.accessibilityIdXPathAttrib + }="Move block up from row ${ position } to row ${ position - 1 }"]`; + const moveUpButton = await this.driver.elementByXPath( blockLocator ); + await moveUpButton.click(); + } + + // position of the block to move down + async moveBlockDownAtPosition( position, blockName = '' ) { + if ( ! ( await this.hasBlockAtPosition( position, blockName ) ) ) { + throw Error( `No Block at position ${ position }` ); + } + + const parentLocator = `//*[contains(@${ this.accessibilityIdXPathAttrib }, "${ blockName } Block. Row ${ position }.")]`; + let blockLocator = `${ parentLocator }/following-sibling::*`; + blockLocator += isAndroid() ? '' : '//*'; + blockLocator += `[@${ + this.accessibilityIdXPathAttrib + }="Move block down from row ${ position } to row ${ position + 1 }"]`; + const moveDownButton = await this.driver.elementByXPath( blockLocator ); + await moveDownButton.click(); + } + + // position of the block to remove + // Block will no longer be present if this succeeds + async removeBlockAtPosition( blockName = '', position = 1 ) { + if ( ! ( await this.hasBlockAtPosition( position, blockName ) ) ) { + throw Error( `No Block at position ${ position }` ); + } + + const buttonElementName = isAndroid() + ? '//*' + : '//XCUIElementTypeButton'; + const blockActionsMenuButtonIdentifier = `Open Block Actions Menu`; + const blockActionsMenuButtonLocator = `${ buttonElementName }[contains(@${ this.accessibilityIdXPathAttrib }, "${ blockActionsMenuButtonIdentifier }")]`; + + if ( isAndroid() ) { + const block = await this.getBlockAtPosition( blockName, position ); + let checkList = await this.driver.elementsByXPath( + blockActionsMenuButtonLocator + ); + while ( checkList.length === 0 ) { + await swipeUp( this.driver, block ); // Swipe up to show remove icon at the bottom + checkList = await this.driver.elementsByXPath( + blockActionsMenuButtonLocator + ); + } + } + + const blockActionsMenuButton = await this.driver.elementByXPath( + blockActionsMenuButtonLocator + ); + await blockActionsMenuButton.click(); + + const removeActionButtonIdentifier = `Remove ${ blockName }`; + const removeActionButtonLocator = `${ buttonElementName }[contains(@${ this.accessibilityIdXPathAttrib }, "${ removeActionButtonIdentifier }")]`; + const removeActionButton = await this.driver.elementByXPath( + removeActionButtonLocator + ); + + await removeActionButton.click(); + } + + // ========================= + // Paragraph Block functions + // ========================= + + async getTextViewForParagraphBlock( block ) { + let textViewElementName = 'XCUIElementTypeTextView'; + if ( isAndroid() ) { + textViewElementName = 'android.widget.EditText'; + } + + const accessibilityId = await block.getAttribute( + this.accessibilityIdKey + ); + const blockLocator = `//*[@${ + this.accessibilityIdXPathAttrib + }=${ JSON.stringify( accessibilityId ) }]//${ textViewElementName }`; + return await this.driver.elementByXPath( blockLocator ); + } + + async typeTextToParagraphBlock( block, text, clear ) { + const textViewElement = await this.getTextViewForParagraphBlock( + block + ); + await typeString( this.driver, textViewElement, text, clear ); + await this.driver.sleep( 1000 ); // Give time for the block to rerender (such as for accessibility) + } + + async sendTextToParagraphBlock( position, text, clear ) { + const paragraphs = text.split( '\n' ); + for ( let i = 0; i < paragraphs.length; i++ ) { + // Select block first + const block = await this.getBlockAtPosition( + this.paragraphBlockName, + position + i + ); + await block.click(); + + await this.typeTextToParagraphBlock( + block, + paragraphs[ i ], + clear + ); + if ( i !== paragraphs.length - 1 ) { + await this.typeTextToParagraphBlock( block, '\n', false ); + } + } + } + + async getTextForParagraphBlock( block ) { + const textViewElement = await this.getTextViewForParagraphBlock( + block + ); + const text = await textViewElement.text(); + return text.toString(); + } + + async getTextForParagraphBlockAtPosition( position ) { + // Select block first + let block = await this.getBlockAtPosition( + this.paragraphBlockName, + position + ); + await block.click(); + + block = await this.getBlockAtPosition( + this.paragraphBlockName, + position + ); + const text = await this.getTextForParagraphBlock( block ); + return text.toString(); + } + + // ========================= + // List Block functions + // ========================= + + async getTextViewForListBlock( block ) { + let textViewElementName = 'XCUIElementTypeTextView'; + if ( isAndroid() ) { + textViewElementName = 'android.widget.EditText'; + } + + const accessibilityId = await block.getAttribute( + this.accessibilityIdKey + ); + const blockLocator = `//*[@${ + this.accessibilityIdXPathAttrib + }=${ JSON.stringify( accessibilityId ) }]//${ textViewElementName }`; + return await this.driver.elementByXPath( blockLocator ); + } + + async sendTextToListBlock( block, text ) { + const textViewElement = await this.getTextViewForListBlock( block ); + + // Cannot clear list blocks because it messes up the list bullet + const clear = false; + + return await typeString( this.driver, textViewElement, text, clear ); + } + + async clickOrderedListToolBarButton() { + await this.clickToolBarButton( this.orderedListButtonName ); + } + + // ========================= + // Image Block functions + // ========================= + + async selectEmptyImageBlock( block ) { + const accessibilityId = await block.getAttribute( + this.accessibilityIdKey + ); + const blockLocator = `//*[@${ this.accessibilityIdXPathAttrib }="${ accessibilityId }"]//XCUIElementTypeButton[@name="Image block. Empty"]`; + const imageBlockInnerElement = await this.driver.elementByXPath( + blockLocator + ); + await imageBlockInnerElement.click(); + } + + async chooseMediaLibrary() { + const mediaLibraryButton = await this.driver.elementByAccessibilityId( + 'WordPress Media Library' + ); + await mediaLibraryButton.click(); + } + + async enterCaptionToSelectedImageBlock( caption, clear = true ) { + const imageBlockCaptionField = await this.driver.elementByXPath( + '//XCUIElementTypeButton[starts-with(@name, "Image caption.")]' + ); + await imageBlockCaptionField.click(); + await typeString( this.driver, imageBlockCaptionField, caption, clear ); + } + + // ========================= + // Heading Block functions + // ========================= + + // Inner element changes on iOS if Heading Block is empty + async getTextViewForHeadingBlock( block, empty ) { + let textViewElementName = empty + ? 'XCUIElementTypeStaticText' + : 'XCUIElementTypeTextView'; + if ( isAndroid() ) { + textViewElementName = 'android.widget.EditText'; + } + + const accessibilityId = await block.getAttribute( + this.accessibilityIdKey + ); + const blockLocator = `//*[@${ this.accessibilityIdXPathAttrib }="${ accessibilityId }"]//${ textViewElementName }`; + return await this.driver.elementByXPath( blockLocator ); + } + + async sendTextToHeadingBlock( block, text, clear = true ) { + const textViewElement = await this.getTextViewForHeadingBlock( + block, + true + ); + return await typeString( this.driver, textViewElement, text, clear ); + } +} diff --git a/packages/react-native-editor/android/app/BUCK b/packages/react-native-editor/android/app/BUCK new file mode 100644 index 00000000000000..bd517c4b3f0328 --- /dev/null +++ b/packages/react-native-editor/android/app/BUCK @@ -0,0 +1,55 @@ +# To learn about Buck see [Docs](https://buckbuild.com/). +# To run your application with Buck: +# - install Buck +# - `npm start` - to start the packager +# - `cd android` +# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` +# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck +# - `buck install -r android/app` - compile, install and run application +# + +load(":build_defs.bzl", "create_aar_targets", "create_jar_targets") + +lib_deps = [] + +create_aar_targets(glob(["libs/*.aar"])) + +create_jar_targets(glob(["libs/*.jar"])) + +android_library( + name = "all-libs", + exported_deps = lib_deps, +) + +android_library( + name = "app-code", + srcs = glob([ + "src/main/java/**/*.java", + ]), + deps = [ + ":all-libs", + ":build_config", + ":res", + ], +) + +android_build_config( + name = "build_config", + package = "com.gutenberg", +) + +android_resource( + name = "res", + package = "com.gutenberg", + res = "src/main/res", +) + +android_binary( + name = "app", + keystore = "//android/keystores:debug", + manifest = "src/main/AndroidManifest.xml", + package_type = "debug", + deps = [ + ":app-code", + ], +) diff --git a/packages/react-native-editor/android/app/build.gradle b/packages/react-native-editor/android/app/build.gradle new file mode 100644 index 00000000000000..3f150b4c1669d9 --- /dev/null +++ b/packages/react-native-editor/android/app/build.gradle @@ -0,0 +1,179 @@ +apply plugin: "com.android.application" + +import com.android.build.OutputFile + +/** + * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets + * and bundleReleaseJsAndAssets). + * These basically call `react-native bundle` with the correct arguments during the Android build + * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the + * bundle directly from the development server. Below you can see all the possible configurations + * and their defaults. If you decide to add a configuration block, make sure to add it before the + * `apply from: "../../node_modules/react-native/react.gradle"` line. + * + * project.ext.react = [ + * // the name of the generated asset file containing your JS bundle + * bundleAssetName: "index.android.bundle", + * + * // the entry file for bundle generation + * entryFile: "index.android.js", + * + * // whether to bundle JS and assets in debug mode + * bundleInDebug: false, + * + * // whether to bundle JS and assets in release mode + * bundleInRelease: true, + * + * // whether to bundle JS and assets in another build variant (if configured). + * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants + * // The configuration property can be in the following formats + * // 'bundleIn${productFlavor}${buildType}' + * // 'bundleIn${buildType}' + * // bundleInFreeDebug: true, + * // bundleInPaidRelease: true, + * // bundleInBeta: true, + * + * // whether to disable dev mode in custom build variants (by default only disabled in release) + * // for example: to disable dev mode in the staging build type (if configured) + * devDisabledInStaging: true, + * // The configuration property can be in the following formats + * // 'devDisabledIn${productFlavor}${buildType}' + * // 'devDisabledIn${buildType}' + * + * // the root of your project, i.e. where "package.json" lives + * root: "../../", + * + * // where to put the JS bundle asset in debug mode + * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", + * + * // where to put the JS bundle asset in release mode + * jsBundleDirRelease: "$buildDir/intermediates/assets/release", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in debug mode + * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", + * + * // where to put drawable resources / React Native assets, e.g. the ones you use via + * // require('./image.png')), in release mode + * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", + * + * // by default the gradle tasks are skipped if none of the JS files or assets change; this means + * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to + * // date; if you have any other folders that you want to ignore for performance reasons (gradle + * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ + * // for example, you might want to remove it from here. + * inputExcludes: ["android/**", "ios/**"], + * + * // override which node gets called and with what additional arguments + * nodeExecutableAndArgs: ["node"], + * + * // supply additional arguments to the packager + * extraPackagerArgs: [] + * ] + */ + +project.ext.react = [ + entryFile: "index.js", + enableHermes: true, // clean and rebuild if changing +] + +apply from: "../../../../node_modules/react-native/react.gradle" + +/** + * Set this to true to create two separate APKs instead of one: + * - An APK that only works on ARM devices + * - An APK that only works on x86 devices + * The advantage is the size of the APK is reduced by about 4MB. + * Upload all the APKs to the Play Store and people will download + * the correct one based on the CPU architecture of their device. + */ +def enableSeparateBuildPerCPUArchitecture = false + +/** + * Run Proguard to shrink the Java bytecode in release builds. + */ +def enableProguardInReleaseBuilds = false + +/** + * Whether to enable the Hermes VM. + * + * This should be set on project.ext.react and mirrored here. If it is not set + * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode + * and the benefits of using Hermes will therefore be sharply reduced. + */ +def enableHermes = project.ext.react.get("enableHermes", false); + +android { + compileSdkVersion rootProject.ext.compileSdkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + applicationId "com.gutenberg" + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + versionCode 1 + versionName "1.0" + } + splits { + abi { + reset() + enable enableSeparateBuildPerCPUArchitecture + universalApk false // If true, also generate a universal APK + include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + } + } + buildTypes { + release { + minifyEnabled enableProguardInReleaseBuilds + proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" + } + } + // applicationVariants are e.g. debug, release + applicationVariants.all { variant -> + variant.outputs.each { output -> + // For each separate APK per architecture, set a unique version code as described here: + // https://developer.android.com/studio/build/configure-apk-splits.html + def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4] + def abi = output.getFilter(OutputFile.ABI) + if (abi != null) { // null for the universal-debug, universal-release variants + output.versionCodeOverride = + versionCodes.get(abi) * 1048576 + defaultConfig.versionCode + } + } + } + + packagingOptions { + pickFirst 'META-INF/-no-jdk.kotlin_module' + } +} + +repositories { + google() + jcenter() + maven { url "https://jitpack.io" } +} + + +dependencies { + implementation project(':@wordpress_react-native-aztec') + implementation project(':@wordpress_react-native-bridge') + implementation project(':react-native-linear-gradient') + implementation project(':@react-native-community_slider') + implementation project(':react-native-video') + implementation project(':react-native-svg') + implementation project(':react-native-get-random-values') + implementation "org.wordpress:utils:$wordpressUtilsVersion" + implementation 'androidx.appcompat:appcompat:1.0.0' + implementation "com.facebook.react:react-native:+" // From node_modules +} + +// Run this once to be able to run the application with BUCK +// puts all compile dependencies into folder libs for BUCK to use +task copyDownloadableDepsToLibs(type: Copy) { + from configurations.compile + into 'libs' +} diff --git a/packages/react-native-editor/android/app/build_defs.bzl b/packages/react-native-editor/android/app/build_defs.bzl new file mode 100644 index 00000000000000..fff270f8d1d484 --- /dev/null +++ b/packages/react-native-editor/android/app/build_defs.bzl @@ -0,0 +1,19 @@ +"""Helper definitions to glob .aar and .jar targets""" + +def create_aar_targets(aarfiles): + for aarfile in aarfiles: + name = "aars__" + aarfile[aarfile.rindex("/") + 1:aarfile.rindex(".aar")] + lib_deps.append(":" + name) + android_prebuilt_aar( + name = name, + aar = aarfile, + ) + +def create_jar_targets(jarfiles): + for jarfile in jarfiles: + name = "jars__" + jarfile[jarfile.rindex("/") + 1:jarfile.rindex(".jar")] + lib_deps.append(":" + name) + prebuilt_jar( + name = name, + binary_jar = jarfile, + ) diff --git a/packages/react-native-editor/android/app/proguard-rules.pro b/packages/react-native-editor/android/app/proguard-rules.pro new file mode 100644 index 00000000000000..11b025724a3f7a --- /dev/null +++ b/packages/react-native-editor/android/app/proguard-rules.pro @@ -0,0 +1,10 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: diff --git a/packages/react-native-editor/android/app/src/debug/AndroidManifest.xml b/packages/react-native-editor/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000000000..1fce564881ff37 --- /dev/null +++ b/packages/react-native-editor/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/packages/react-native-editor/android/app/src/debug/res/xml/react_native_config.xml b/packages/react-native-editor/android/app/src/debug/res/xml/react_native_config.xml new file mode 100644 index 00000000000000..ba4b23070be6cc --- /dev/null +++ b/packages/react-native-editor/android/app/src/debug/res/xml/react_native_config.xml @@ -0,0 +1,8 @@ + + + + localhost + 10.0.2.2 + 10.0.3.2 + + diff --git a/packages/react-native-editor/android/app/src/main/AndroidManifest.xml b/packages/react-native-editor/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000000000..a17ac1a08abfa8 --- /dev/null +++ b/packages/react-native-editor/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java new file mode 100644 index 00000000000000..46662bc94a9cd5 --- /dev/null +++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainActivity.java @@ -0,0 +1,37 @@ +package com.gutenberg; + +import android.os.Bundle; + +import androidx.annotation.Nullable; + +import com.facebook.react.ReactActivity; +import com.facebook.react.ReactActivityDelegate; + +import org.wordpress.mobile.WPAndroidGlue.WPAndroidGlueCode; + +public class MainActivity extends ReactActivity { + + /** + * Returns the name of the main component registered from JavaScript. + * This is used to schedule rendering of the component. + */ + @Override + protected String getMainComponentName() { + return "gutenberg"; + } + + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegate(this, getMainComponentName()) { + @Nullable + @Override + protected Bundle getLaunchOptions() { + Bundle bundle = new Bundle(); + Bundle capabilities = new Bundle(); + capabilities.putBoolean(WPAndroidGlueCode.PROP_NAME_CAPABILITIES_MENTIONS, true); + bundle.putBundle(WPAndroidGlueCode.PROP_NAME_CAPABILITIES, capabilities); + return bundle; + } + }; + } +} diff --git a/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java new file mode 100644 index 00000000000000..25a6aadc526f75 --- /dev/null +++ b/packages/react-native-editor/android/app/src/main/java/com/gutenberg/MainApplication.java @@ -0,0 +1,248 @@ +package com.gutenberg; + +import android.app.Application; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Bundle; +import android.util.Log; + +import androidx.core.util.Consumer; + +import com.facebook.react.ReactApplication; +import com.BV.LinearGradient.LinearGradientPackage; +import com.facebook.react.bridge.ReadableMap; +import com.reactnativecommunity.slider.ReactSliderPackage; +import com.brentvatne.react.ReactVideoPackage; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.devsupport.interfaces.DevOptionHandler; +import com.facebook.react.devsupport.interfaces.DevSupportManager; +import com.horcrux.svg.SvgPackage; +import org.linusu.RNGetRandomValuesPackage; + +import org.wordpress.mobile.ReactNativeAztec.ReactAztecPackage; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeInterface; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergBridgeJS2Parent; +import org.wordpress.mobile.ReactNativeGutenbergBridge.GutenbergWebViewActivity; +import org.wordpress.mobile.ReactNativeGutenbergBridge.RNMedia; +import org.wordpress.mobile.ReactNativeGutenbergBridge.RNReactNativeGutenbergBridgePackage; +import org.wordpress.mobile.WPAndroidGlue.Media; + +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.shell.MainReactPackage; +import com.facebook.soloader.SoLoader; + +import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; + +public class MainApplication extends Application implements ReactApplication, GutenbergBridgeInterface { + + private static final String TAG = "MainApplication"; + + private ReactNativeHost mReactNativeHost; + private RNReactNativeGutenbergBridgePackage mRnReactNativeGutenbergBridgePackage; + private GutenbergBridgeJS2Parent.ReplaceUnsupportedBlockCallback mReplaceUnsupportedBlockCallback; + + private ReactNativeHost createReactNativeHost() { + mRnReactNativeGutenbergBridgePackage = new RNReactNativeGutenbergBridgePackage(new GutenbergBridgeJS2Parent() { + @Override + public void responseHtml(String title, String html, boolean changed, ReadableMap contentInfo) { + } + + @Override + public void requestMediaImport(String url, MediaSelectedCallback mediaSelectedCallback) { + } + + @Override + public void requestMediaPickerFromDeviceCamera(MediaSelectedCallback mediaSelectedCallback, MediaType mediaType) { + } + + @Override + public void requestMediaPickFromDeviceLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) { + } + + @Override + public void requestMediaPickFromMediaLibrary(MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection, MediaType mediaType) { + List rnMediaList = new ArrayList<>(); + if (mediaType == MediaType.IMAGE) { + rnMediaList.add(new Media(1, "https://cldup.com/cXyG__fTLN.jpg", "image", "Mountain" )); + } else if (mediaType == MediaType.VIDEO) { + rnMediaList.add(new Media(2, "https://i.cloudup.com/YtZFJbuQCE.mov", "video", "Cloudup" )); + } + mediaSelectedCallback.onMediaFileSelected(rnMediaList); + } + + + @Override + public void mediaUploadSync(MediaSelectedCallback mediaSelectedCallback) { + } + + @Override + public void requestImageFailedRetryDialog(int mediaId) { + } + + @Override + public void requestImageUploadCancelDialog(int mediaId) { + } + + @Override + public void requestImageUploadCancel(int mediaId) { + } + + @Override + public void editorDidMount(ReadableArray unsupportedBlockNames) { + } + + @Override + public void editorDidAutosave() { + } + + @Override + public void getOtherMediaPickerOptions(OtherMediaOptionsReceivedCallback otherMediaOptionsReceivedCallback, MediaType mediaType) { + + } + + @Override + public void requestMediaPickFrom(String mediaSource, MediaSelectedCallback mediaSelectedCallback, Boolean allowMultipleSelection) { + + } + + @Override + public void requestImageFullscreenPreview(String mediaUrl) { + + } + + @Override + public void requestMediaEditor(MediaSelectedCallback mediaSelectedCallback, String mediaUrl) { + + } + + @Override + public void logUserEvent(GutenbergUserEvent gutenbergUserEvent, ReadableMap eventProperties) { + } + + @Override + public void setStarterPageTemplatesTooltipShown(boolean tooltipShown) { + } + + @Override + public void requestStarterPageTemplatesTooltipShown(StarterPageTemplatesTooltipShownCallback starterPageTemplatesTooltipShownCallback) { + } + + @Override + public void editorDidEmitLog(String message, LogLevel logLevel) { + switch (logLevel) { + case TRACE: + Log.d(TAG, message); + break; + case INFO: + Log.i(TAG, message); + break; + case WARN: + Log.w(TAG, message); + break; + case ERROR: + Log.e(TAG, message); + break; + } + } + + @Override + public void performRequest(String path, Consumer onSuccess, Consumer onError) {} + + @Override + public void gutenbergDidRequestUnsupportedBlockFallback(ReplaceUnsupportedBlockCallback replaceUnsupportedBlockCallback, + String content, + String blockId, + String blockName) { + mReplaceUnsupportedBlockCallback = replaceUnsupportedBlockCallback; + openGutenbergWebView(content, blockId, blockName); + } + + @Override + public void onAddMention(Consumer onSuccess) { + onSuccess.accept("matt"); + } + + }, isDarkMode()); + + return new ReactNativeHost(this) { + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + return Arrays.asList( + new MainReactPackage(), + new ReactSliderPackage(), + new ReactVideoPackage(), + new SvgPackage(), + // passing null because we do not need log handlers in the demo app + new ReactAztecPackage(null, null), + new LinearGradientPackage(), + new RNGetRandomValuesPackage(), + mRnReactNativeGutenbergBridgePackage); + } + + @Override + protected String getJSMainModuleName() { + return "index"; + } + }; + } + + private boolean isDarkMode() { + Configuration configuration = getResources().getConfiguration(); + int currentNightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; + + return currentNightMode == Configuration.UI_MODE_NIGHT_YES; + } + + private void openGutenbergWebView(String content, + String blockId, + String blockName) { + Intent intent = new Intent(this, GutenbergWebViewActivity.class); + intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_CONTENT, content); + intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_ID, blockId); + intent.putExtra(GutenbergWebViewActivity.ARG_BLOCK_NAME, blockName); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); + } + + @Override + public ReactNativeHost getReactNativeHost() { + if (mReactNativeHost == null) { + mReactNativeHost = createReactNativeHost(); + createCustomDevOptions(mReactNativeHost); + } + + return mReactNativeHost; + } + + @Override + public void onCreate() { + super.onCreate(); + SoLoader.init(this, /* native exopackage */ false); + } + + private void createCustomDevOptions(ReactNativeHost reactNativeHost) { + DevSupportManager devSupportManager = reactNativeHost.getReactInstanceManager().getDevSupportManager(); + + devSupportManager.addCustomDevOption("Show html", new DevOptionHandler() { + @Override + public void onOptionSelected() { + mRnReactNativeGutenbergBridgePackage.getRNReactNativeGutenbergBridgeModule().toggleEditorMode(); + } + }); + } + + @Override + public void saveContent(String content, String blockId) { + if (mReplaceUnsupportedBlockCallback != null) { + mReplaceUnsupportedBlockCallback.replaceUnsupportedBlock(content, blockId); + } + } +} diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000000000..a2f5908281d070 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 00000000000000..1b523998081149 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000000000..ff10afd6e182ed Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 00000000000000..115a4c768a20c9 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000000000..dcd3cd80833582 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 00000000000000..459ca609d3ae0d Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000000000..8ca12fe024be86 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 00000000000000..8e19b410a1b15f Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000000000..b824ebdd48db91 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 00000000000000..4c19a13c239cb6 Binary files /dev/null and b/packages/react-native-editor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/packages/react-native-editor/android/app/src/main/res/values/strings.xml b/packages/react-native-editor/android/app/src/main/res/values/strings.xml new file mode 100644 index 00000000000000..29e2e4d13944c2 --- /dev/null +++ b/packages/react-native-editor/android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Gutenberg + diff --git a/packages/react-native-editor/android/app/src/main/res/values/styles.xml b/packages/react-native-editor/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000000000..319eb0ca100b5a --- /dev/null +++ b/packages/react-native-editor/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/packages/react-native-editor/android/build.gradle b/packages/react-native-editor/android/build.gradle new file mode 100644 index 00000000000000..641f576b14a14e --- /dev/null +++ b/packages/react-native-editor/android/build.gradle @@ -0,0 +1,37 @@ +buildscript { + ext { + gradlePluginVersion = '3.4.2' + kotlinVersion = '1.3.61' + buildToolsVersion = "28.0.3" + minSdkVersion = 21 + compileSdkVersion = 28 + targetSdkVersion = 28 + supportLibVersion = '28.0.0' + wordpressUtilsVersion = '1.22' + } + repositories { + google() + jcenter() + } + dependencies { + classpath "com.android.tools.build:gradle:$gradlePluginVersion" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" + } +} + +// Load the "build from source" flag value but default to `true` since this is the demo gutenberg-mobile project so +project.ext.buildGutenbergFromSource = project.properties.getOrDefault('wp.BUILD_GUTENBERG_FROM_SOURCE', true).toBoolean() + +allprojects { + repositories { + mavenLocal() + maven { + // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm + url("$rootDir/../../../node_modules/react-native/android") + } + + google() + jcenter() + maven { url 'https://jitpack.io' } + } +} diff --git a/packages/react-native-editor/android/gradle.properties b/packages/react-native-editor/android/gradle.properties new file mode 100644 index 00000000000000..027ef9db8a3001 --- /dev/null +++ b/packages/react-native-editor/android/gradle.properties @@ -0,0 +1,21 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true + +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.jar b/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 00000000000000..01b8bf6b1f99ca Binary files /dev/null and b/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.jar differ diff --git a/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.properties b/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000000000..fb2e41dd7126a4 --- /dev/null +++ b/packages/react-native-editor/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Jun 10 13:39:31 EDT 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip diff --git a/packages/react-native-editor/android/gradlew b/packages/react-native-editor/android/gradlew new file mode 100755 index 00000000000000..cccdd3d517fc52 --- /dev/null +++ b/packages/react-native-editor/android/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/packages/react-native-editor/android/gradlew.bat b/packages/react-native-editor/android/gradlew.bat new file mode 100644 index 00000000000000..e95643d6a2ca62 --- /dev/null +++ b/packages/react-native-editor/android/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/packages/react-native-editor/android/keystores/BUCK b/packages/react-native-editor/android/keystores/BUCK new file mode 100644 index 00000000000000..88e4c31b28d497 --- /dev/null +++ b/packages/react-native-editor/android/keystores/BUCK @@ -0,0 +1,8 @@ +keystore( + name = "debug", + properties = "debug.keystore.properties", + store = "debug.keystore", + visibility = [ + "PUBLIC", + ], +) diff --git a/packages/react-native-editor/android/keystores/debug.keystore.properties b/packages/react-native-editor/android/keystores/debug.keystore.properties new file mode 100644 index 00000000000000..121bfb49f0dfda --- /dev/null +++ b/packages/react-native-editor/android/keystores/debug.keystore.properties @@ -0,0 +1,4 @@ +key.store=debug.keystore +key.alias=androiddebugkey +key.store.password=android +key.alias.password=android diff --git a/packages/react-native-editor/android/settings.gradle b/packages/react-native-editor/android/settings.gradle new file mode 100644 index 00000000000000..f7ae4dfa566f50 --- /dev/null +++ b/packages/react-native-editor/android/settings.gradle @@ -0,0 +1,18 @@ +rootProject.name = 'gutenberg' + +include ':@wordpress_react-native-bridge' +project(':@wordpress_react-native-bridge').projectDir = new File(rootProject.projectDir, '../../react-native-bridge/android') +include ':@wordpress_react-native-aztec' +project(':@wordpress_react-native-aztec').projectDir = new File(rootProject.projectDir, '../../react-native-aztec/android') +include ':@react-native-community_slider' +project(':@react-native-community_slider').projectDir = new File(rootProject.projectDir, '../../../node_modules/@react-native-community/slider/src/android') +include ':react-native-video' +project(':react-native-video').projectDir = new File(rootProject.projectDir, '../../../node_modules/react-native-video/android-exoplayer') +include ':react-native-svg' +project(':react-native-svg').projectDir = new File(rootProject.projectDir, '../../../node_modules/react-native-svg/android') +include ':react-native-linear-gradient' +project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../../../node_modules/react-native-linear-gradient/android') +include ':react-native-get-random-values' +project(':react-native-get-random-values').projectDir = new File(rootProject.projectDir, '../../../node_modules/react-native-get-random-values/android') + +include ':app' diff --git a/packages/react-native-editor/app.json b/packages/react-native-editor/app.json new file mode 100644 index 00000000000000..4d6b29af714c40 --- /dev/null +++ b/packages/react-native-editor/app.json @@ -0,0 +1,4 @@ +{ + "name": "gutenberg", + "displayName": "Gutenberg" +} diff --git a/packages/react-native-editor/babel.config.js b/packages/react-native-editor/babel.config.js new file mode 100644 index 00000000000000..0fd51ac0d10061 --- /dev/null +++ b/packages/react-native-editor/babel.config.js @@ -0,0 +1,51 @@ +module.exports = function ( api ) { + api.cache( true ); + return { + presets: [ 'module:metro-react-native-babel-preset' ], + plugins: [ + '@babel/plugin-proposal-async-generator-functions', + '@babel/plugin-transform-runtime', + [ + 'react-native-platform-specific-extensions', + { + extensions: [ 'css', 'scss', 'sass' ], + }, + ], + ], + overrides: [ + { + // Transforms JSX into JS function calls and use `createElement` instead of the default `React.createElement` + plugins: [ + [ + '@babel/plugin-transform-react-jsx', + { + pragma: 'createElement', + pragmaFrag: 'Fragment', + }, + ], + ], + exclude: /node_modules\/(react-native|@react-native-community)/, + }, + { + // Auto-add `import { createElement } from '@wordpress/element';` when JSX is found + plugins: [ + [ + '@wordpress/babel-plugin-import-jsx-pragma', + { + scopeVariable: 'createElement', + scopeVariableFrag: 'Fragment', + source: '@wordpress/element', + isDefault: false, + }, + ], + ], + exclude: /node_modules\/(react-native|@react-native-community)/, + }, + ], + env: { + development: { + plugins: [ '@babel/transform-react-jsx-source' ], + }, + }, + }; +}; diff --git a/packages/react-native-editor/docs/Releasing.md b/packages/react-native-editor/docs/Releasing.md new file mode 100644 index 00000000000000..51d2c4f322452f --- /dev/null +++ b/packages/react-native-editor/docs/Releasing.md @@ -0,0 +1,178 @@ +# Making a release + +The `bundle` directory contains the production version of the project's Javascript. This is what the WordPress apps use to avoid having to build Gutenberg. + +You can rebuild those files at any time by running + +``` +yarn bundle +``` + +This is useful in case you want to use an unreleased version of the bundle in the apps. For instance, on a PR that's a work in progress, you might want to include to a specific gutenberg-mobile branch in the apps with an updated bundle so reviewers can see the latest changes before approving them (and releasing a new version). + +# Release Checklist Template + +Just copy this checklist and replace all occurrences of `X.XX.X` with the applicable release number, when we are ready to +cut a new release. + +``` + +

Gutenberg Mobile X.XX.X – Release Scenario

+ + + +

This checklist is based on the Release Checklist Template. If you need a checklist for a new gutenberg-mobile release, please copy from that template.

+ + + +

+mobilegutenberg

+ + + +

Day 1 - create the release branch, update the version

+ + + +

o Visit all opened PR's in gutenberg-mobile repo that are assigned to milestone X.XX.X and leave proper message with options to merge them or to bump them to the next version.

+ + + +

o In the gutenberg-mobile submodule, branch develop to the release branch (eg. git checkout develop; git pull origin develop; git checkout -b release/X.XX.X).

+ + + +

o Update the package.json file with the new version number, run: yarn version and enter the new version name when you get asked: X.XX.X (Changes will be committed automatically).

+ + + +

o Push the release branch, git push origin release/X.XX.X.

+ + + +

o Create the gutenberg submodule branch: cd gutenberg; git checkout -b rnmobile/release-X.XX.X.

+ + + +

o Push the gutenberg submodule branch: git push origin rnmobile/release-X.XX.X.

+ + + +

o Make sure we use a released version of Aztec iOS and Aztec Android: grep WordPress-Aztec-iOS RNTAztecView.podspec and grep aztecVersion react-native-aztec/android/build.gradle(should be part of a ./release-check.sh script). Also insure that the line for testing non-official versions of Aztec on iOS is commented out (this command should find a match: grep "^s*#pod 'WordPress-Aztec-iOS'" ios/Podfile)

+ + + +

o Open a PR based on the release branch in Gutenberg-Mobile and target master. Example PR: https://github.com/wordpress-mobile/gutenberg-mobile/pull/1627. There should not be any conflicts with this PR.

+ + + +

o Create a new branch in the main WP apps (WordPress-iOS, WordPress-Android) named gutenberg/integrate_release_X.XX.X.

+ + + +

o Use the commit hash of the head of the release branch in Gutenberg-Mobile as the reference for the main apps.

+ + + +

o Create a PR in WPAndroid and WPiOS. Example on WPAndroid, WPiOS. To write the PR description: pull the differences between previous and current releases. Update the RELEASE-NOTES.txt files in each PR (get info from the gutenberg-mobile RELEASE-NOTES.txt).

+ + + +

o In iOS update the file Podfile to point to the new hash in GB-Mobile and if needed also update the reference to Aztec to the new release. Then run rake dependencies, commit and push.

+ + + +

o On Android update the git submodule reference for libs/gutenberg-mobile (cd libs/gutenberg-mobile && git checkout release/X.XX.X && git pull origin release/X.XX.X && cd .. && git add gutenberg-mobile) and run python tools/merge_strings_xml.py to update the main strings.xml file.

+ + + +

o Create new branches gutenberg/after_X.XX.X in WPAndroid and WPiOS and keep them up to date with the release branches. These are to be doubles for develop on the main apps for mobile gutenberg dev’s WP app PR’s that didn’t or shouldn’t make it into the X.XX.X editor release.

+ + + +

New Aztec Release

+ + + +

o Make sure there is no pending Aztec PR required for this Gutenberg release. Check the commit hash referred in the gutenberg repo is in the Aztec develop branch. If it's not, make sure pending PRs are merged before next steps.

+ + + +

o Open a PR on Aztec repo to update the CHANGELOG.md and README.md files with the new version name.

+ + + +

o Create a new release and name it with the tag name from step 1. For Aztec-iOS, follow this process. For Aztec-Android, releases are created via the GitHub releases page by hitting the “Draft new release” button, put the tag name to be created in the tag version field and release title field, and also add the changelog to the release description. The binary assets (.zip, tar.gz files) are attached automatically after hitting “Publish release”.

+ + + +

(Optional) Specific tasks after a PR has been merged after the freeze

+ + + +

o After a merge happened in gutenberg-mobile release/X.XX.X or in gutenberg rnmobile/release-X.XX.X, make sure the gutenberg submodule points to the right hash (and make sure the rnmobile/release-X.XX.X in the gutenberg repo branch has been updated)

+ + + +

o If there were changes in Gutenberg repo, make sure to cherry-pick the changes that landed in the master branch back to the release branch.

+ + + +

Last Day

+ + + +

o Make sure that the bundle files on the Gutenberg-Mobile release branch have been updated to include any changes to the release branch.

+ + + +

o Merge the Gutenberg-Mobile PR to master. WARNING: Don’t merge the Gutenberg PR to master at this point.

+ + + +

o Tag the head of Gutenberg release branch that the Gutenberg-Mobile release branch is pointing to with the rnmobile/X.XX.X tag.

+ + + +

o Create a new GitHub release pointing to the tag: https://github.com/wordpress-mobile/gutenberg-mobile/releases/new?tag=X.XX.X&target=master&title=X.XX.X. Include a list of changes in the release's description

+ + + +

o In WPiOS update the reference to point to the tag. For iOS do not forget to remove ‘develop’ branch reference near 3rd party pod specs if any.

+ + + +

o In WPAndroid, update the submodule to point to the merge commit on master.

+ + + +

o Main apps PRs should be ready to merge to their develop now. Merge them or get them merged.

+ + + +

o Once everything is merged, ping our friends in #platform9 and let them know we’ve merged our release so everything is right from our side to cut the main app releases.

+ + + +

o Open a PR from Gutenberg-Mobile master to bring all the gutenberg/after_X.XX.X changes to develop and point to the Gutenberg side PR (if any changes happened specifically for the release). Merge the PR (or PR domino if Gutenberg changes are there)

+ + + +

AFTER the main apps have cut their release branches

+ + + +

o Update the gutenberg/after_X.XX.X branches and open a PR against develop. If the branches are empty we’ll just delete them. The PR can actually get created as soon as something gets merged to the after-ooo branches.  Merge the gutenberg/after_X.XX.X PR(s) only AFTER the main apps have cut their release branches.

+ + + +

You're done

+ + + +

o Pass the baton. Ping the dev who is responsible for the next release

+ + + +

o Celebrate!

+ +``` diff --git a/packages/react-native-editor/i18n-cache/.gitignore b/packages/react-native-editor/i18n-cache/.gitignore new file mode 100644 index 00000000000000..4262a76c530230 --- /dev/null +++ b/packages/react-native-editor/i18n-cache/.gitignore @@ -0,0 +1,3 @@ +# ignore native version of this module as it will be generated + +index.native.js diff --git a/packages/react-native-editor/i18n-cache/data/.gitignore b/packages/react-native-editor/i18n-cache/data/.gitignore new file mode 100644 index 00000000000000..e13e2719e01705 --- /dev/null +++ b/packages/react-native-editor/i18n-cache/data/.gitignore @@ -0,0 +1,3 @@ +# ignore all the contents of this folder except this file +* +!.gitignore \ No newline at end of file diff --git a/packages/react-native-editor/i18n-cache/index.js b/packages/react-native-editor/i18n-cache/index.js new file mode 100644 index 00000000000000..9ff94b17a3f0fc --- /dev/null +++ b/packages/react-native-editor/i18n-cache/index.js @@ -0,0 +1,183 @@ +/* eslint-disable no-console */ + +/** + * External dependencies + */ +const fs = require( 'fs' ); +const path = require( 'path' ); +const fetch = require( 'node-fetch' ); + +const supportedLocales = [ + 'ar', // Arabic + 'bg', // Bulgarian + 'bo', // Tibetan + 'ca', // Catalan + 'cs', // Czech + 'cy', // Welsh + 'da', // Danish + 'de', // German + 'en-au', // English (Australia) + 'en-ca', // English (Canada) + 'en-gb', // English (UK) + 'en-nz', // English (New Zealand) + 'en-za', // English (South Africa) + 'el', // Greek + 'es', // Spanish + 'es-ar', // Spanish (Argentina) + 'es-cl', // Spanish (Chile) + 'es-cr', // Spanish (Costa Rica) + 'fa', // Persian + 'fr', // French + 'gl', // Galician + 'he', // Hebrew + 'hr', // Croatian + 'hu', // Hungarian + 'id', // Indonesian + 'is', // Icelandic + 'it', // Italian + 'ja', // Japanese + 'ka', // Georgian + 'ko', // Korean + 'nb', // Norwegian (Bokmål) + 'nl', // Dutch + 'nl-be', // Dutch (Belgium) + 'pl', // Polish + 'pt', // Portuguese + 'pt-br', // Portuguese (Brazil) + 'ro', // Romainian + 'ru', // Russian + 'sk', // Slovak + 'sq', // Albanian + 'sr', // Serbian + 'sv', // Swedish + 'th', // Thai + 'tr', // Turkish + 'uk', // Ukrainian + 'ur', // Urdu + 'vi', // Vietnamese + 'zh-cn', // Chinese (China) + 'zh-tw', // Chinese (Taiwan) +]; + +const getLanguageUrl = ( locale ) => + `https://translate.wordpress.org/projects/wp-plugins/gutenberg/dev/${ locale }/default/export-translations\?format\=json`; +const getTranslationFilePath = ( locale ) => `./data/${ locale }.json`; + +const getTranslation = ( locale ) => + require( getTranslationFilePath( locale ) ); + +const fetchTranslation = ( locale ) => { + if ( ! process.env.REFRESH_I18N_CACHE ) { + try { + const localData = getTranslation( locale ); + console.log( `Using cached locale data for ${ locale }` ); + return Promise.resolve( { + response: localData, + locale, + inCache: true, + } ); + } catch ( error ) { + // translation not found, let's fetch it + } + } + + console.log( 'fetching', getLanguageUrl( locale ) ); + const localeUrl = getLanguageUrl( locale ); + return fetch( localeUrl ) + .then( ( response ) => response.json() ) + .then( ( body ) => { + return { response: body, locale }; + } ) + .catch( () => { + console.error( `Could not find translation file ${ localeUrl }` ); + } ); +}; + +const fetchTranslations = () => { + const fetchPromises = supportedLocales.map( ( locale ) => + fetchTranslation( locale ) + ); + + return Promise.all( fetchPromises ).then( ( results ) => { + const fetchedTranslations = results.filter( Boolean ); + const translationFilePromises = fetchedTranslations.map( + ( languageResult ) => { + return new Promise( ( resolve, reject ) => { + const translationRelativePath = getTranslationFilePath( + languageResult.locale + ); + + if ( languageResult.inCache ) { + languageResult.path = translationRelativePath; + resolve( translationRelativePath ); + return; + } + + const translationAbsolutePath = path.resolve( + __dirname, + translationRelativePath + ); + + fs.writeFile( + translationAbsolutePath, + JSON.stringify( languageResult.response ), + 'utf8', + ( err ) => { + if ( err ) { + reject( err ); + } else { + languageResult.path = translationRelativePath; + resolve( translationRelativePath ); + } + } + ); + } ); + } + ); + return Promise.all( translationFilePromises ).then( + () => fetchedTranslations + ); + } ); +}; + +module.exports = { + getTranslation, +}; + +// if run as a script +if ( require.main === module ) { + fetchTranslations().then( ( translations ) => { + const indexNative = `/* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */ +/* eslint-disable prettier/prettier */ + +const translations = { +${ translations + .filter( Boolean ) + .map( + ( translation ) => + `\t"${ translation.locale }": require( "${ translation.path }" ),` + ) + .join( '\n' ) } +}; + +export const getTranslation = ( locale ) => translations[ locale ]; + +/* eslint-enable prettier/prettier */ +`; + + fs.writeFile( + path.join( __dirname, 'index.native.js' ), + indexNative, + 'utf8', + ( error ) => { + if ( error ) { + console.error( error ); + return; + } + console.log( 'Done.' ); + } + ); + } ); +} + +/* eslint-enable no-console */ diff --git a/packages/react-native-editor/images/recommended-extensions.png b/packages/react-native-editor/images/recommended-extensions.png new file mode 100644 index 00000000000000..1f7acb2ad2f2d7 Binary files /dev/null and b/packages/react-native-editor/images/recommended-extensions.png differ diff --git a/packages/react-native-editor/index.js b/packages/react-native-editor/index.js new file mode 100644 index 00000000000000..1417cc0322975d --- /dev/null +++ b/packages/react-native-editor/index.js @@ -0,0 +1,4 @@ +/** + * Internal dependencies + */ +import './src'; diff --git a/packages/react-native-editor/ios/.bundle/config b/packages/react-native-editor/ios/.bundle/config new file mode 100644 index 00000000000000..2369228816d467 --- /dev/null +++ b/packages/react-native-editor/ios/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_PATH: "vendor/bundle" diff --git a/packages/react-native-editor/ios/CustomImageLoader.swift b/packages/react-native-editor/ios/CustomImageLoader.swift new file mode 100644 index 00000000000000..e543734b8df843 --- /dev/null +++ b/packages/react-native-editor/ios/CustomImageLoader.swift @@ -0,0 +1,36 @@ +import Foundation + +class CustomImageLoader: NSObject, RCTImageURLLoader { + + static func moduleName() -> String! { + return "CustomImageLoader" + } + + func canLoadImageURL(_ requestURL: URL!) -> Bool { + return !requestURL.isFileURL + } + + func loadImage(for imageURL: URL!, size: CGSize, scale: CGFloat, resizeMode: RCTResizeMode, progressHandler: RCTImageLoaderProgressBlock!, partialLoadHandler: RCTImageLoaderPartialLoadBlock!, completionHandler: RCTImageLoaderCompletionBlock!) -> RCTImageLoaderCancellationBlock! { + let task = URLSession.shared.dataTask(with: imageURL) { (data, response, error) in + if let error = error { + completionHandler(error, nil) + return + } + guard let data = data, + let image = UIImage.init(data: data) else { + completionHandler?(NSError(domain: NSURLErrorDomain, code: NSURLErrorCancelled, userInfo: nil), nil) + return; + } + completionHandler?(nil, image) + } + task.resume() + return { () in + task.cancel() + } + } + + func loaderPriority() -> Float { + return 100 + } + +} diff --git a/packages/react-native-editor/ios/Gemfile b/packages/react-native-editor/ios/Gemfile new file mode 100644 index 00000000000000..09c4d6ef1eb6f4 --- /dev/null +++ b/packages/react-native-editor/ios/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' do + gem 'cocoapods', '~> 1.8.0' +end diff --git a/packages/react-native-editor/ios/Gemfile.lock b/packages/react-native-editor/ios/Gemfile.lock new file mode 100644 index 00000000000000..8537a61386f86b --- /dev/null +++ b/packages/react-native-editor/ios/Gemfile.lock @@ -0,0 +1,83 @@ +GEM + remote: https://rubygems.org/ + specs: + CFPropertyList (3.0.1) + activesupport (4.2.11.1) + i18n (~> 0.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + algoliasearch (1.27.1) + httpclient (~> 2.8, >= 2.8.3) + json (>= 1.5.1) + atomos (0.1.3) + claide (1.0.3) + cocoapods (1.8.4) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.2, < 2.0) + cocoapods-core (= 1.8.4) + cocoapods-deintegrate (>= 1.0.3, < 2.0) + cocoapods-downloader (>= 1.2.2, < 2.0) + cocoapods-plugins (>= 1.0.0, < 2.0) + cocoapods-search (>= 1.0.0, < 2.0) + cocoapods-stats (>= 1.0.0, < 2.0) + cocoapods-trunk (>= 1.4.0, < 2.0) + cocoapods-try (>= 1.1.0, < 2.0) + colored2 (~> 3.1) + escape (~> 0.0.4) + fourflusher (>= 2.3.0, < 3.0) + gh_inspector (~> 1.0) + molinillo (~> 0.6.6) + nap (~> 1.0) + ruby-macho (~> 1.4) + xcodeproj (>= 1.11.1, < 2.0) + cocoapods-core (1.8.4) + activesupport (>= 4.0.2, < 6) + algoliasearch (~> 1.0) + concurrent-ruby (~> 1.1) + fuzzy_match (~> 2.0.4) + nap (~> 1.0) + cocoapods-deintegrate (1.0.4) + cocoapods-downloader (1.3.0) + cocoapods-plugins (1.0.0) + nap + cocoapods-search (1.0.0) + cocoapods-stats (1.1.0) + cocoapods-trunk (1.4.1) + nap (>= 0.8, < 2.0) + netrc (~> 0.11) + cocoapods-try (1.1.0) + colored2 (3.1.2) + concurrent-ruby (1.1.5) + escape (0.0.4) + fourflusher (2.3.1) + fuzzy_match (2.0.4) + gh_inspector (1.1.3) + httpclient (2.8.3) + i18n (0.9.5) + concurrent-ruby (~> 1.0) + json (2.2.0) + minitest (5.13.0) + molinillo (0.6.6) + nanaimo (0.2.6) + nap (1.1.0) + netrc (0.11.0) + ruby-macho (1.4.0) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + xcodeproj (1.13.0) + CFPropertyList (>= 2.3.3, < 4.0) + atomos (~> 0.1.3) + claide (>= 1.0.2, < 2.0) + colored2 (~> 3.1) + nanaimo (~> 0.2.6) + +PLATFORMS + ruby + +DEPENDENCIES + cocoapods (~> 1.8.0)! + +BUNDLED WITH + 2.0.2 diff --git a/packages/react-native-editor/ios/Podfile b/packages/react-native-editor/ios/Podfile new file mode 100644 index 00000000000000..4585276dd919a3 --- /dev/null +++ b/packages/react-native-editor/ios/Podfile @@ -0,0 +1,66 @@ +project 'gutenberg.xcodeproj' + +# Uncomment the next line to define a global platform for your project +platform :ios, '11.0' +require_relative '../../../node_modules/@react-native-community/cli-platform-ios/native_modules' + +target 'gutenberg' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for gutenberg + pod 'FBLazyVector', :path => "../../../node_modules/react-native/Libraries/FBLazyVector" + pod 'FBReactNativeSpec', :path => "../../../node_modules/react-native/Libraries/FBReactNativeSpec" + pod 'RCTRequired', :path => "../../../node_modules/react-native/Libraries/RCTRequired" + pod 'RCTTypeSafety', :path => "../../../node_modules/react-native/Libraries/TypeSafety" + pod 'React', :path => '../../../node_modules/react-native/' + pod 'React-Core', :path => '../../../node_modules/react-native/' + pod 'React-CoreModules', :path => '../../../node_modules/react-native/React/CoreModules' + pod 'React-Core/DevSupport', :path => '../../../node_modules/react-native/' + pod 'React-RCTActionSheet', :path => '../../../node_modules/react-native/Libraries/ActionSheetIOS' + pod 'React-RCTAnimation', :path => '../../../node_modules/react-native/Libraries/NativeAnimation' + pod 'React-RCTBlob', :path => '../../../node_modules/react-native/Libraries/Blob' + pod 'React-RCTImage', :path => '../../../node_modules/react-native/Libraries/Image' + pod 'React-RCTLinking', :path => '../../../node_modules/react-native/Libraries/LinkingIOS' + pod 'React-RCTNetwork', :path => '../../../node_modules/react-native/Libraries/Network' + pod 'React-RCTSettings', :path => '../../../node_modules/react-native/Libraries/Settings' + pod 'React-RCTText', :path => '../../../node_modules/react-native/Libraries/Text' + pod 'React-RCTVibration', :path => '../../../node_modules/react-native/Libraries/Vibration' + pod 'React-Core/RCTWebSocket', :path => '../../../node_modules/react-native/' + pod 'React-cxxreact', :path => '../../../node_modules/react-native/ReactCommon/cxxreact' + pod 'React-jsi', :path => '../../../node_modules/react-native/ReactCommon/jsi' + pod 'React-jsiexecutor', :path => '../../../node_modules/react-native/ReactCommon/jsiexecutor' + pod 'React-jsinspector', :path => '../../../node_modules/react-native/ReactCommon/jsinspector' + pod 'ReactCommon/jscallinvoker', :path => "../../../node_modules/react-native/ReactCommon" + pod 'ReactCommon/turbomodule/core', :path => "../../../node_modules/react-native/ReactCommon" + pod 'Yoga', :path => '../../../node_modules/react-native/ReactCommon/yoga' + pod 'DoubleConversion', :podspec => '../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' + pod 'glog', :podspec => '../../../node_modules/react-native/third-party-podspecs/glog.podspec' + pod 'Folly', :podspec => '../../../node_modules/react-native/third-party-podspecs/Folly.podspec' + pod 'RNTAztecView', :path => '../../react-native-aztec/RNTAztecView.podspec' + #Use for testing non official versions of Aztec + #pod 'WordPress-Aztec-iOS', :git => 'https://github.com/wordpress-mobile/WordPress-Aztec-iOS.git', :commit => '29dff741f4b19435d75f21179e27766337de8e9d' + pod 'Gutenberg', :path => '../../react-native-bridge/Gutenberg.podspec' + + + + target 'gutenbergTests' do + inherit! :search_paths + # Pods for testing + end + + use_native_modules! +end + +target 'gutenberg-tvOS' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for gutenberg-tvOS + + target 'gutenberg-tvOSTests' do + inherit! :search_paths + # Pods for testing + end + +end diff --git a/packages/react-native-editor/ios/Podfile.lock b/packages/react-native-editor/ios/Podfile.lock new file mode 100644 index 00000000000000..a3d2e224932655 --- /dev/null +++ b/packages/react-native-editor/ios/Podfile.lock @@ -0,0 +1,408 @@ +PODS: + - boost-for-react-native (1.63.0) + - BVLinearGradient (2.5.6): + - React + - DoubleConversion (1.1.6) + - FBLazyVector (0.61.5) + - FBReactNativeSpec (0.61.5): + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.61.5) + - RCTTypeSafety (= 0.61.5) + - React-Core (= 0.61.5) + - React-jsi (= 0.61.5) + - ReactCommon/turbomodule/core (= 0.61.5) + - Folly (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - Folly/Default (= 2018.10.22.00) + - glog + - Folly/Default (2018.10.22.00): + - boost-for-react-native + - DoubleConversion + - glog + - glog (0.3.5) + - Gutenberg (8.3.0): + - React (= 0.61.5) + - React-CoreModules (= 0.61.5) + - React-RCTImage (= 0.61.5) + - RNTAztecView + - RCTRequired (0.61.5) + - RCTTypeSafety (0.61.5): + - FBLazyVector (= 0.61.5) + - Folly (= 2018.10.22.00) + - RCTRequired (= 0.61.5) + - React-Core (= 0.61.5) + - React (0.61.5): + - React-Core (= 0.61.5) + - React-Core/DevSupport (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-RCTActionSheet (= 0.61.5) + - React-RCTAnimation (= 0.61.5) + - React-RCTBlob (= 0.61.5) + - React-RCTImage (= 0.61.5) + - React-RCTLinking (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTSettings (= 0.61.5) + - React-RCTText (= 0.61.5) + - React-RCTVibration (= 0.61.5) + - React-Core (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/CoreModulesHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/Default (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/DevSupport (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - React-jsinspector (= 0.61.5) + - Yoga + - React-Core/RCTActionSheetHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTAnimationHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTBlobHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTImageHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTLinkingHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTNetworkHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTSettingsHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTTextHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTVibrationHeaders (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-Core/RCTWebSocket (0.61.5): + - Folly (= 2018.10.22.00) + - glog + - React-Core/Default (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsiexecutor (= 0.61.5) + - Yoga + - React-CoreModules (0.61.5): + - FBReactNativeSpec (= 0.61.5) + - Folly (= 2018.10.22.00) + - RCTTypeSafety (= 0.61.5) + - React-Core/CoreModulesHeaders (= 0.61.5) + - React-RCTImage (= 0.61.5) + - ReactCommon/turbomodule/core (= 0.61.5) + - React-cxxreact (0.61.5): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsinspector (= 0.61.5) + - React-jsi (0.61.5): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsi/Default (= 0.61.5) + - React-jsi/Default (0.61.5): + - boost-for-react-native (= 1.63.0) + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-jsiexecutor (0.61.5): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - React-jsinspector (0.61.5) + - react-native-get-random-values (1.4.0): + - React + - react-native-keyboard-aware-scroll-view (0.8.8): + - React + - react-native-safe-area (0.5.1): + - React + - react-native-slider (2.0.7): + - React + - react-native-video (5.0.2): + - React + - react-native-video/Video (= 5.0.2) + - react-native-video/Video (5.0.2): + - React + - React-RCTActionSheet (0.61.5): + - React-Core/RCTActionSheetHeaders (= 0.61.5) + - React-RCTAnimation (0.61.5): + - React-Core/RCTAnimationHeaders (= 0.61.5) + - React-RCTBlob (0.61.5): + - React-Core/RCTBlobHeaders (= 0.61.5) + - React-Core/RCTWebSocket (= 0.61.5) + - React-jsi (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTImage (0.61.5): + - React-Core/RCTImageHeaders (= 0.61.5) + - React-RCTNetwork (= 0.61.5) + - React-RCTLinking (0.61.5): + - React-Core/RCTLinkingHeaders (= 0.61.5) + - React-RCTNetwork (0.61.5): + - React-Core/RCTNetworkHeaders (= 0.61.5) + - React-RCTSettings (0.61.5): + - React-Core/RCTSettingsHeaders (= 0.61.5) + - React-RCTText (0.61.5): + - React-Core/RCTTextHeaders (= 0.61.5) + - React-RCTVibration (0.61.5): + - React-Core/RCTVibrationHeaders (= 0.61.5) + - ReactCommon/jscallinvoker (0.61.5): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-cxxreact (= 0.61.5) + - ReactCommon/turbomodule/core (0.61.5): + - DoubleConversion + - Folly (= 2018.10.22.00) + - glog + - React-Core (= 0.61.5) + - React-cxxreact (= 0.61.5) + - React-jsi (= 0.61.5) + - ReactCommon/jscallinvoker (= 0.61.5) + - ReactNativeDarkMode (0.0.10): + - React + - RNSVG (9.13.6-gb): + - React + - RNTAztecView (0.1.11): + - React-Core + - WordPress-Aztec-iOS (~> 1.19.2) + - WordPress-Aztec-iOS (1.19.2) + - Yoga (1.14.0) + +DEPENDENCIES: + - BVLinearGradient (from `../../../node_modules/react-native-linear-gradient`) + - DoubleConversion (from `../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) + - FBLazyVector (from `../../../node_modules/react-native/Libraries/FBLazyVector`) + - FBReactNativeSpec (from `../../../node_modules/react-native/Libraries/FBReactNativeSpec`) + - Folly (from `../../../node_modules/react-native/third-party-podspecs/Folly.podspec`) + - glog (from `../../../node_modules/react-native/third-party-podspecs/glog.podspec`) + - Gutenberg (from `../../react-native-bridge/Gutenberg.podspec`) + - RCTRequired (from `../../../node_modules/react-native/Libraries/RCTRequired`) + - RCTTypeSafety (from `../../../node_modules/react-native/Libraries/TypeSafety`) + - React (from `../../../node_modules/react-native/`) + - React-Core (from `../../../node_modules/react-native/`) + - React-Core/DevSupport (from `../../../node_modules/react-native/`) + - React-Core/RCTWebSocket (from `../../../node_modules/react-native/`) + - React-CoreModules (from `../../../node_modules/react-native/React/CoreModules`) + - React-cxxreact (from `../../../node_modules/react-native/ReactCommon/cxxreact`) + - React-jsi (from `../../../node_modules/react-native/ReactCommon/jsi`) + - React-jsiexecutor (from `../../../node_modules/react-native/ReactCommon/jsiexecutor`) + - React-jsinspector (from `../../../node_modules/react-native/ReactCommon/jsinspector`) + - react-native-get-random-values (from `../../../node_modules/react-native-get-random-values`) + - react-native-keyboard-aware-scroll-view (from `../../../node_modules/react-native-keyboard-aware-scroll-view`) + - react-native-safe-area (from `../../../node_modules/react-native-safe-area`) + - "react-native-slider (from `../../../node_modules/@react-native-community/slider`)" + - react-native-video (from `../../../node_modules/react-native-video`) + - React-RCTActionSheet (from `../../../node_modules/react-native/Libraries/ActionSheetIOS`) + - React-RCTAnimation (from `../../../node_modules/react-native/Libraries/NativeAnimation`) + - React-RCTBlob (from `../../../node_modules/react-native/Libraries/Blob`) + - React-RCTImage (from `../../../node_modules/react-native/Libraries/Image`) + - React-RCTLinking (from `../../../node_modules/react-native/Libraries/LinkingIOS`) + - React-RCTNetwork (from `../../../node_modules/react-native/Libraries/Network`) + - React-RCTSettings (from `../../../node_modules/react-native/Libraries/Settings`) + - React-RCTText (from `../../../node_modules/react-native/Libraries/Text`) + - React-RCTVibration (from `../../../node_modules/react-native/Libraries/Vibration`) + - ReactCommon/jscallinvoker (from `../../../node_modules/react-native/ReactCommon`) + - ReactCommon/turbomodule/core (from `../../../node_modules/react-native/ReactCommon`) + - ReactNativeDarkMode (from `../../../node_modules/react-native-dark-mode`) + - RNSVG (from `../../../node_modules/react-native-svg`) + - RNTAztecView (from `../../react-native-aztec/RNTAztecView.podspec`) + - Yoga (from `../../../node_modules/react-native/ReactCommon/yoga`) + +SPEC REPOS: + trunk: + - boost-for-react-native + - WordPress-Aztec-iOS + +EXTERNAL SOURCES: + BVLinearGradient: + :path: "../../../node_modules/react-native-linear-gradient" + DoubleConversion: + :podspec: "../../../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" + FBLazyVector: + :path: "../../../node_modules/react-native/Libraries/FBLazyVector" + FBReactNativeSpec: + :path: "../../../node_modules/react-native/Libraries/FBReactNativeSpec" + Folly: + :podspec: "../../../node_modules/react-native/third-party-podspecs/Folly.podspec" + glog: + :podspec: "../../../node_modules/react-native/third-party-podspecs/glog.podspec" + Gutenberg: + :path: "../../react-native-bridge/Gutenberg.podspec" + RCTRequired: + :path: "../../../node_modules/react-native/Libraries/RCTRequired" + RCTTypeSafety: + :path: "../../../node_modules/react-native/Libraries/TypeSafety" + React: + :path: "../../../node_modules/react-native/" + React-Core: + :path: "../../../node_modules/react-native/" + React-CoreModules: + :path: "../../../node_modules/react-native/React/CoreModules" + React-cxxreact: + :path: "../../../node_modules/react-native/ReactCommon/cxxreact" + React-jsi: + :path: "../../../node_modules/react-native/ReactCommon/jsi" + React-jsiexecutor: + :path: "../../../node_modules/react-native/ReactCommon/jsiexecutor" + React-jsinspector: + :path: "../../../node_modules/react-native/ReactCommon/jsinspector" + react-native-get-random-values: + :path: "../../../node_modules/react-native-get-random-values" + react-native-keyboard-aware-scroll-view: + :path: "../../../node_modules/react-native-keyboard-aware-scroll-view" + react-native-safe-area: + :path: "../../../node_modules/react-native-safe-area" + react-native-slider: + :path: "../../../node_modules/@react-native-community/slider" + react-native-video: + :path: "../../../node_modules/react-native-video" + React-RCTActionSheet: + :path: "../../../node_modules/react-native/Libraries/ActionSheetIOS" + React-RCTAnimation: + :path: "../../../node_modules/react-native/Libraries/NativeAnimation" + React-RCTBlob: + :path: "../../../node_modules/react-native/Libraries/Blob" + React-RCTImage: + :path: "../../../node_modules/react-native/Libraries/Image" + React-RCTLinking: + :path: "../../../node_modules/react-native/Libraries/LinkingIOS" + React-RCTNetwork: + :path: "../../../node_modules/react-native/Libraries/Network" + React-RCTSettings: + :path: "../../../node_modules/react-native/Libraries/Settings" + React-RCTText: + :path: "../../../node_modules/react-native/Libraries/Text" + React-RCTVibration: + :path: "../../../node_modules/react-native/Libraries/Vibration" + ReactCommon: + :path: "../../../node_modules/react-native/ReactCommon" + ReactNativeDarkMode: + :path: "../../../node_modules/react-native-dark-mode" + RNSVG: + :path: "../../../node_modules/react-native-svg" + RNTAztecView: + :path: "../../react-native-aztec/RNTAztecView.podspec" + Yoga: + :path: "../../../node_modules/react-native/ReactCommon/yoga" + +SPEC CHECKSUMS: + boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c + BVLinearGradient: 60a475b2edfe7707deda00278cb8ce9bfe70e669 + DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2 + FBLazyVector: aaeaf388755e4f29cd74acbc9e3b8da6d807c37f + FBReactNativeSpec: 118d0d177724c2d67f08a59136eb29ef5943ec75 + Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51 + glog: 1f3da668190260b06b429bb211bfbee5cd790c28 + Gutenberg: 237167a5bb725cedcef0fa56f73b009bc1c389bd + RCTRequired: b153add4da6e7dbc44aebf93f3cf4fcae392ddf1 + RCTTypeSafety: 9aa1b91d7f9310fc6eadc3cf95126ffe818af320 + React: b6a59ef847b2b40bb6e0180a97d0ca716969ac78 + React-Core: 688b451f7d616cc1134ac95295b593d1b5158a04 + React-CoreModules: d04f8494c1a328b69ec11db9d1137d667f916dcb + React-cxxreact: d0f7bcafa196ae410e5300736b424455e7fb7ba7 + React-jsi: cb2cd74d7ccf4cffb071a46833613edc79cdf8f7 + React-jsiexecutor: d5525f9ed5f782fdbacb64b9b01a43a9323d2386 + React-jsinspector: fa0ecc501688c3c4c34f28834a76302233e29dc0 + react-native-get-random-values: 8940331a943a46c165d3ed05802c09c392f8dd46 + react-native-keyboard-aware-scroll-view: ffa9152671fec9a571197ed2d02e0fcb90206e60 + react-native-safe-area: e8230b0017d76c00de6b01e2412dcf86b127c6a3 + react-native-slider: f81b89fa0c1f9a65742d33f889a194ca6653a985 + react-native-video: 961749da457e73bf0b5565edfbaffc25abfb8974 + React-RCTActionSheet: 600b4d10e3aea0913b5a92256d2719c0cdd26d76 + React-RCTAnimation: 791a87558389c80908ed06cc5dfc5e7920dfa360 + React-RCTBlob: d89293cc0236d9cb0933d85e430b0bbe81ad1d72 + React-RCTImage: 6b8e8df449eb7c814c99a92d6b52de6fe39dea4e + React-RCTLinking: 121bb231c7503cf9094f4d8461b96a130fabf4a5 + React-RCTNetwork: fb353640aafcee84ca8b78957297bd395f065c9a + React-RCTSettings: 8db258ea2a5efee381fcf7a6d5044e2f8b68b640 + React-RCTText: 9ccc88273e9a3aacff5094d2175a605efa854dbe + React-RCTVibration: a49a1f42bf8f5acf1c3e297097517c6b3af377ad + ReactCommon: 198c7c8d3591f975e5431bec1b0b3b581aa1c5dd + ReactNativeDarkMode: f61376360c5d983907e5c316e8e1c853a8c2f348 + RNSVG: 68a534a5db06dcbdaebfd5079349191598caef7b + RNTAztecView: b4c945bdc156b98dbf5c8a676def6c7736efa337 + WordPress-Aztec-iOS: d01bf0c5e150ae6a046f06ba63b7cc2762061c0b + Yoga: f2a7cd4280bfe2cca5a7aed98ba0eb3d1310f18b + +PODFILE CHECKSUM: c8a36f1dc00b0194bc4eb8fad6ae0c674a2dfd2b + +COCOAPODS: 1.8.4 diff --git a/packages/react-native-editor/ios/gutenberg-Bridging-Header.h b/packages/react-native-editor/ios/gutenberg-Bridging-Header.h new file mode 100644 index 00000000000000..5422961cdb05a0 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg-Bridging-Header.h @@ -0,0 +1,8 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import +#import +#import diff --git a/packages/react-native-editor/ios/gutenberg-tvOS/Info.plist b/packages/react-native-editor/ios/gutenberg-tvOS/Info.plist new file mode 100644 index 00000000000000..2fb6a11c2c3356 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg-tvOS/Info.plist @@ -0,0 +1,54 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + NSLocationWhenInUseUsageDescription + + NSAppTransportSecurity + + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + + diff --git a/packages/react-native-editor/ios/gutenberg-tvOSTests/Info.plist b/packages/react-native-editor/ios/gutenberg-tvOSTests/Info.plist new file mode 100644 index 00000000000000..886825ccc9bf0d --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg-tvOSTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/packages/react-native-editor/ios/gutenberg.xcodeproj/project.pbxproj b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.pbxproj new file mode 100644 index 00000000000000..01bb92522a2d0c --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.pbxproj @@ -0,0 +1,1152 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 00E356F31AD99517003FC87E /* gutenbergTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* gutenbergTests.m */; }; + 05908C6EA5B80A39F74C4FEF /* Pods_gutenberg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 38E210A05B5C8829E0B3BE83 /* Pods_gutenberg.framework */; }; + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 1E4F2E752459E6F200EB73E7 /* WebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E85944D2449D85A006CC6A0 /* WebViewController.swift */; }; + 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; + 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2D16E6891FA4F8E400B85C8A /* libReact.a */; }; + 2DCD954D1E0B4F2C00145EB5 /* gutenbergTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* gutenbergTests.m */; }; + 4858A387C929BA42C247FA16 /* Pods_gutenberg_tvOSTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE48AF171A9B998D71F3078B /* Pods_gutenberg_tvOSTests.framework */; }; + 7EC7328F21907E3F00FED2E6 /* GutenbergViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7EC7328E21907E3F00FED2E6 /* GutenbergViewController.swift */; }; + 8C666FF0C9224FB88C2C0447 /* libRNSVG-tvOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9BFAFEB337654221B2F14D03 /* libRNSVG-tvOS.a */; }; + C05E07BC5927E0FBD17C828D /* Pods_gutenbergTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D57C380A7861BFFC2565FE6E /* Pods_gutenbergTests.framework */; }; + F151983C2100DC3D000F6E97 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F15198392100DC3D000F6E97 /* AppDelegate.swift */; }; + F151983D2100DC3D000F6E97 /* MediaProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = F151983A2100DC3D000F6E97 /* MediaProvider.swift */; }; + F1EE6F7821E7F0A500241744 /* NotoSerif-BoldItalic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1EE6F7421E7F0A500241744 /* NotoSerif-BoldItalic.ttf */; }; + F1EE6F7921E7F0A500241744 /* NotoSerif-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1EE6F7521E7F0A500241744 /* NotoSerif-Regular.ttf */; }; + F1EE6F7A21E7F0A500241744 /* NotoSerif-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1EE6F7621E7F0A500241744 /* NotoSerif-Italic.ttf */; }; + F1EE6F7B21E7F0A500241744 /* NotoSerif-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F1EE6F7721E7F0A500241744 /* NotoSerif-Bold.ttf */; }; + FAE17A4A0C1CA38AB8862805 /* Pods_gutenberg_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E418A3212D0A388EEA0698C5 /* Pods_gutenberg_tvOS.framework */; }; + FF37F903223819FA00AFA3DB /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FF37F8D0223819FA00AFA3DB /* JavaScriptCore.framework */; }; + FF6836C822035EAB00A0C562 /* MediaUploadCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF6836C722035EAB00A0C562 /* MediaUploadCoordinator.swift */; }; + FF83DAA92226905A00A34C93 /* CustomImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF83DAA82226905A00A34C93 /* CustomImageLoader.swift */; }; + FF9A6F4121FA8E2500D36D14 /* MediaPickCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF9A6F1621FA8E2500D36D14 /* MediaPickCoordinator.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 13B07F861A680F5B00A75B9A; + remoteInfo = gutenberg; + }; + 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7; + remoteInfo = "gutenberg-tvOS"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = ""; }; + 00E356EE1AD99517003FC87E /* gutenbergTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = gutenbergTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 00E356F21AD99517003FC87E /* gutenbergTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = gutenbergTests.m; sourceTree = ""; }; + 034874811302E030BA1637A1 /* Pods-gutenbergTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenbergTests.debug.xcconfig"; path = "Target Support Files/Pods-gutenbergTests/Pods-gutenbergTests.debug.xcconfig"; sourceTree = ""; }; + 083D3CAD9B26701AE0659EEB /* Pods-gutenberg.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg.release.xcconfig"; path = "Target Support Files/Pods-gutenberg/Pods-gutenberg.release.xcconfig"; sourceTree = ""; }; + 0EB766FE2F6D446A80AC6E6A /* libRNSVG.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSVG.a; sourceTree = ""; }; + 13B07F961A680F5B00A75B9A /* GutenbergDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GutenbergDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = gutenberg/Images.xcassets; sourceTree = ""; }; + 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = gutenberg/Info.plist; sourceTree = ""; }; + 1E85944D2449D85A006CC6A0 /* WebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = WebViewController.swift; path = gutenberg/WebViewController.swift; sourceTree = ""; }; + 2D02E47B1E0B4A5D006451C7 /* gutenberg-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "gutenberg-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D02E4901E0B4A5D006451C7 /* gutenberg-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "gutenberg-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 2D16E6891FA4F8E400B85C8A /* libReact.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libReact.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 38E210A05B5C8829E0B3BE83 /* Pods_gutenberg.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_gutenberg.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3ADEFEC092CF4D00BEF1019E /* libRNTAztecView.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNTAztecView.a; sourceTree = ""; }; + 3D53EF8FEF024C98A7AC9A56 /* libRCTVideo.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRCTVideo.a; sourceTree = ""; }; + 549A3E45719DB5BA2F7ECC95 /* Pods-gutenberg-tvOSTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg-tvOSTests.release.xcconfig"; path = "Target Support Files/Pods-gutenberg-tvOSTests/Pods-gutenberg-tvOSTests.release.xcconfig"; sourceTree = ""; }; + 6206F0B13B70AD60CA886558 /* Pods-gutenbergTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenbergTests.release.xcconfig"; path = "Target Support Files/Pods-gutenbergTests/Pods-gutenbergTests.release.xcconfig"; sourceTree = ""; }; + 69F3DF692A7C4E5994CD3CBB /* libRNSafeArea.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libRNSafeArea.a; sourceTree = ""; }; + 7EA30CF021AC8CDA0092F894 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; + 7EC7328E21907E3F00FED2E6 /* GutenbergViewController.swift */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.swift; name = GutenbergViewController.swift; path = gutenberg/GutenbergViewController.swift; sourceTree = ""; tabWidth = 1; }; + 9193870E2260BA5500E4FBD6 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; }; + 9193873C2260BA7800E4FBD6 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; }; + 9BFAFEB337654221B2F14D03 /* libRNSVG-tvOS.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = "libRNSVG-tvOS.a"; sourceTree = ""; }; + A6B9393B15FAEBA6A3C885F2 /* Pods-gutenberg.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg.debug.xcconfig"; path = "Target Support Files/Pods-gutenberg/Pods-gutenberg.debug.xcconfig"; sourceTree = ""; }; + A7031126C4DE90D4D7AAACD5 /* Pods-gutenberg-tvOSTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg-tvOSTests.debug.xcconfig"; path = "Target Support Files/Pods-gutenberg-tvOSTests/Pods-gutenberg-tvOSTests.debug.xcconfig"; sourceTree = ""; }; + CE48AF171A9B998D71F3078B /* Pods_gutenberg_tvOSTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_gutenberg_tvOSTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D57C380A7861BFFC2565FE6E /* Pods_gutenbergTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_gutenbergTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D742287512CBBB046F519E11 /* Pods-gutenberg-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg-tvOS.release.xcconfig"; path = "Target Support Files/Pods-gutenberg-tvOS/Pods-gutenberg-tvOS.release.xcconfig"; sourceTree = ""; }; + E418A3212D0A388EEA0698C5 /* Pods_gutenberg_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_gutenberg_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F1289ECA2100E4320091E81D /* Aztec.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Aztec.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F15198372100DC3C000F6E97 /* gutenberg-Bridging-Header.h */ = {isa = PBXFileReference; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = "gutenberg-Bridging-Header.h"; sourceTree = ""; tabWidth = 1; }; + F15198392100DC3D000F6E97 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = gutenberg/AppDelegate.swift; sourceTree = ""; tabWidth = 1; }; + F151983A2100DC3D000F6E97 /* MediaProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 4; lastKnownFileType = sourcecode.swift; name = MediaProvider.swift; path = gutenberg/MediaProvider.swift; sourceTree = ""; tabWidth = 1; usesTabs = 0; }; + F1EE6F7421E7F0A500241744 /* NotoSerif-BoldItalic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-BoldItalic.ttf"; sourceTree = ""; }; + F1EE6F7521E7F0A500241744 /* NotoSerif-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Regular.ttf"; sourceTree = ""; }; + F1EE6F7621E7F0A500241744 /* NotoSerif-Italic.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Italic.ttf"; sourceTree = ""; }; + F1EE6F7721E7F0A500241744 /* NotoSerif-Bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "NotoSerif-Bold.ttf"; sourceTree = ""; }; + FE6E9E6AEF37DEEE897DAC75 /* Pods-gutenberg-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-gutenberg-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-gutenberg-tvOS/Pods-gutenberg-tvOS.debug.xcconfig"; sourceTree = ""; }; + FF37F8D0223819FA00AFA3DB /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; + FF6836C722035EAB00A0C562 /* MediaUploadCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MediaUploadCoordinator.swift; path = gutenberg/MediaUploadCoordinator.swift; sourceTree = ""; }; + FF83DAA82226905A00A34C93 /* CustomImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomImageLoader.swift; sourceTree = ""; }; + FF9A6F1621FA8E2500D36D14 /* MediaPickCoordinator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MediaPickCoordinator.swift; path = gutenberg/MediaPickCoordinator.swift; sourceTree = ""; }; + FFFA53E823C794F500829A43 /* Gutenberg.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Gutenberg.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 00E356EB1AD99517003FC87E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C05E07BC5927E0FBD17C828D /* Pods_gutenbergTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FF37F903223819FA00AFA3DB /* JavaScriptCore.framework in Frameworks */, + 05908C6EA5B80A39F74C4FEF /* Pods_gutenberg.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4781E0B4A5D006451C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D16E6881FA4F8E400B85C8A /* libReact.a in Frameworks */, + 8C666FF0C9224FB88C2C0447 /* libRNSVG-tvOS.a in Frameworks */, + FAE17A4A0C1CA38AB8862805 /* Pods_gutenberg_tvOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4858A387C929BA42C247FA16 /* Pods_gutenberg_tvOSTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 00E356EF1AD99517003FC87E /* gutenbergTests */ = { + isa = PBXGroup; + children = ( + 00E356F21AD99517003FC87E /* gutenbergTests.m */, + 00E356F01AD99517003FC87E /* Supporting Files */, + ); + path = gutenbergTests; + sourceTree = ""; + }; + 00E356F01AD99517003FC87E /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 00E356F11AD99517003FC87E /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 13B07FAE1A68108700A75B9A /* gutenberg */ = { + isa = PBXGroup; + children = ( + 008F07F21AC5B25A0029DE68 /* main.jsbundle */, + F15198372100DC3C000F6E97 /* gutenberg-Bridging-Header.h */, + F15198392100DC3D000F6E97 /* AppDelegate.swift */, + 7EC7328E21907E3F00FED2E6 /* GutenbergViewController.swift */, + 1E85944D2449D85A006CC6A0 /* WebViewController.swift */, + FF9A6F1621FA8E2500D36D14 /* MediaPickCoordinator.swift */, + FF6836C722035EAB00A0C562 /* MediaUploadCoordinator.swift */, + F151983A2100DC3D000F6E97 /* MediaProvider.swift */, + 13B07FB51A68108700A75B9A /* Images.xcassets */, + 13B07FB61A68108700A75B9A /* Info.plist */, + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, + FF83DAA82226905A00A34C93 /* CustomImageLoader.swift */, + ); + name = gutenberg; + sourceTree = ""; + }; + 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { + isa = PBXGroup; + children = ( + FFFA53E823C794F500829A43 /* Gutenberg.framework */, + 9193873C2260BA7800E4FBD6 /* CoreServices.framework */, + 9193870E2260BA5500E4FBD6 /* MobileCoreServices.framework */, + FF37F8D0223819FA00AFA3DB /* JavaScriptCore.framework */, + 7EA30CF021AC8CDA0092F894 /* libxml2.tbd */, + F1289ECA2100E4320091E81D /* Aztec.framework */, + 2D16E6891FA4F8E400B85C8A /* libReact.a */, + 38E210A05B5C8829E0B3BE83 /* Pods_gutenberg.framework */, + E418A3212D0A388EEA0698C5 /* Pods_gutenberg_tvOS.framework */, + CE48AF171A9B998D71F3078B /* Pods_gutenberg_tvOSTests.framework */, + D57C380A7861BFFC2565FE6E /* Pods_gutenbergTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 832341AE1AAA6A7D00B99B32 /* Libraries */ = { + isa = PBXGroup; + children = ( + ); + name = Libraries; + sourceTree = ""; + }; + 83CBB9F61A601CBA00E9B192 = { + isa = PBXGroup; + children = ( + 13B07FAE1A68108700A75B9A /* gutenberg */, + F1EE6F7221E7F0A500241744 /* resources */, + 832341AE1AAA6A7D00B99B32 /* Libraries */, + 00E356EF1AD99517003FC87E /* gutenbergTests */, + 83CBBA001A601CBA00E9B192 /* Products */, + 2D16E6871FA4F8E400B85C8A /* Frameworks */, + F1B3E79320FFA9990042D8C3 /* Recovered References */, + 918EE91F38EF19A86F38D86F /* Pods */, + ); + indentWidth = 2; + sourceTree = ""; + tabWidth = 2; + usesTabs = 0; + }; + 83CBBA001A601CBA00E9B192 /* Products */ = { + isa = PBXGroup; + children = ( + 13B07F961A680F5B00A75B9A /* GutenbergDemo.app */, + 00E356EE1AD99517003FC87E /* gutenbergTests.xctest */, + 2D02E47B1E0B4A5D006451C7 /* gutenberg-tvOS.app */, + 2D02E4901E0B4A5D006451C7 /* gutenberg-tvOSTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 918EE91F38EF19A86F38D86F /* Pods */ = { + isa = PBXGroup; + children = ( + A6B9393B15FAEBA6A3C885F2 /* Pods-gutenberg.debug.xcconfig */, + 083D3CAD9B26701AE0659EEB /* Pods-gutenberg.release.xcconfig */, + FE6E9E6AEF37DEEE897DAC75 /* Pods-gutenberg-tvOS.debug.xcconfig */, + D742287512CBBB046F519E11 /* Pods-gutenberg-tvOS.release.xcconfig */, + A7031126C4DE90D4D7AAACD5 /* Pods-gutenberg-tvOSTests.debug.xcconfig */, + 549A3E45719DB5BA2F7ECC95 /* Pods-gutenberg-tvOSTests.release.xcconfig */, + 034874811302E030BA1637A1 /* Pods-gutenbergTests.debug.xcconfig */, + 6206F0B13B70AD60CA886558 /* Pods-gutenbergTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + F1B3E79320FFA9990042D8C3 /* Recovered References */ = { + isa = PBXGroup; + children = ( + 3ADEFEC092CF4D00BEF1019E /* libRNTAztecView.a */, + 0EB766FE2F6D446A80AC6E6A /* libRNSVG.a */, + 9BFAFEB337654221B2F14D03 /* libRNSVG-tvOS.a */, + 69F3DF692A7C4E5994CD3CBB /* libRNSafeArea.a */, + 3D53EF8FEF024C98A7AC9A56 /* libRCTVideo.a */, + ); + name = "Recovered References"; + sourceTree = ""; + }; + F1EE6F7221E7F0A500241744 /* resources */ = { + isa = PBXGroup; + children = ( + F1EE6F7321E7F0A500241744 /* fonts */, + ); + name = resources; + path = ../resources; + sourceTree = ""; + }; + F1EE6F7321E7F0A500241744 /* fonts */ = { + isa = PBXGroup; + children = ( + F1EE6F7421E7F0A500241744 /* NotoSerif-BoldItalic.ttf */, + F1EE6F7521E7F0A500241744 /* NotoSerif-Regular.ttf */, + F1EE6F7621E7F0A500241744 /* NotoSerif-Italic.ttf */, + F1EE6F7721E7F0A500241744 /* NotoSerif-Bold.ttf */, + ); + path = fonts; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 00E356ED1AD99517003FC87E /* gutenbergTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "gutenbergTests" */; + buildPhases = ( + 70B839CE7B6A174DC4DE8FB6 /* [CP] Check Pods Manifest.lock */, + 00E356EA1AD99517003FC87E /* Sources */, + 00E356EB1AD99517003FC87E /* Frameworks */, + 00E356EC1AD99517003FC87E /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 00E356F51AD99517003FC87E /* PBXTargetDependency */, + ); + name = gutenbergTests; + productName = gutenbergTests; + productReference = 00E356EE1AD99517003FC87E /* gutenbergTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 13B07F861A680F5B00A75B9A /* gutenberg */ = { + isa = PBXNativeTarget; + buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "gutenberg" */; + buildPhases = ( + 74E4D376F06BC61DB863CCC7 /* [CP] Check Pods Manifest.lock */, + 13B07F871A680F5B00A75B9A /* Sources */, + 13B07F8C1A680F5B00A75B9A /* Frameworks */, + 13B07F8E1A680F5B00A75B9A /* Resources */, + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, + 06CE89E9A162D62B604C3B6C /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = gutenberg; + productName = "Hello World"; + productReference = 13B07F961A680F5B00A75B9A /* GutenbergDemo.app */; + productType = "com.apple.product-type.application"; + }; + 2D02E47A1E0B4A5D006451C7 /* gutenberg-tvOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "gutenberg-tvOS" */; + buildPhases = ( + EAFF01B6A058BE3235FB054C /* [CP] Check Pods Manifest.lock */, + 2D02E4771E0B4A5D006451C7 /* Sources */, + 2D02E4781E0B4A5D006451C7 /* Frameworks */, + 2D02E4791E0B4A5D006451C7 /* Resources */, + 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "gutenberg-tvOS"; + productName = "gutenberg-tvOS"; + productReference = 2D02E47B1E0B4A5D006451C7 /* gutenberg-tvOS.app */; + productType = "com.apple.product-type.application"; + }; + 2D02E48F1E0B4A5D006451C7 /* gutenberg-tvOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "gutenberg-tvOSTests" */; + buildPhases = ( + 944E2FEABB650B8AB00B7918 /* [CP] Check Pods Manifest.lock */, + 2D02E48C1E0B4A5D006451C7 /* Sources */, + 2D02E48D1E0B4A5D006451C7 /* Frameworks */, + 2D02E48E1E0B4A5D006451C7 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */, + ); + name = "gutenberg-tvOSTests"; + productName = "gutenberg-tvOSTests"; + productReference = 2D02E4901E0B4A5D006451C7 /* gutenberg-tvOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 83CBB9F71A601CBA00E9B192 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 610; + ORGANIZATIONNAME = Facebook; + TargetAttributes = { + 00E356ED1AD99517003FC87E = { + CreatedOnToolsVersion = 6.2; + TestTargetID = 13B07F861A680F5B00A75B9A; + }; + 13B07F861A680F5B00A75B9A = { + DevelopmentTeam = PZYM8XX95Q; + LastSwiftMigration = 940; + ProvisioningStyle = Automatic; + }; + 2D02E47A1E0B4A5D006451C7 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + }; + 2D02E48F1E0B4A5D006451C7 = { + CreatedOnToolsVersion = 8.2.1; + ProvisioningStyle = Automatic; + TestTargetID = 2D02E47A1E0B4A5D006451C7; + }; + }; + }; + buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "gutenberg" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + English, + en, + Base, + ); + mainGroup = 83CBB9F61A601CBA00E9B192; + productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 13B07F861A680F5B00A75B9A /* gutenberg */, + 00E356ED1AD99517003FC87E /* gutenbergTests */, + 2D02E47A1E0B4A5D006451C7 /* gutenberg-tvOS */, + 2D02E48F1E0B4A5D006451C7 /* gutenberg-tvOSTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 00E356EC1AD99517003FC87E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F8E1A680F5B00A75B9A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, + F1EE6F7B21E7F0A500241744 /* NotoSerif-Bold.ttf in Resources */, + F1EE6F7921E7F0A500241744 /* NotoSerif-Regular.ttf in Resources */, + F1EE6F7A21E7F0A500241744 /* NotoSerif-Italic.ttf in Resources */, + 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, + F1EE6F7821E7F0A500241744 /* NotoSerif-BoldItalic.ttf in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4791E0B4A5D006451C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48E1E0B4A5D006451C7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native code and images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../../../node_modules/react-native/scripts/react-native-xcode.sh\n"; + }; + 06CE89E9A162D62B604C3B6C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-gutenberg/Pods-gutenberg-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/BVLinearGradient/BVLinearGradient.framework", + "${BUILT_PRODUCTS_DIR}/DoubleConversion/DoubleConversion.framework", + "${BUILT_PRODUCTS_DIR}/FBReactNativeSpec/FBReactNativeSpec.framework", + "${BUILT_PRODUCTS_DIR}/Folly/folly.framework", + "${BUILT_PRODUCTS_DIR}/Gutenberg/Gutenberg.framework", + "${BUILT_PRODUCTS_DIR}/RCTTypeSafety/RCTTypeSafety.framework", + "${BUILT_PRODUCTS_DIR}/RNSVG/RNSVG.framework", + "${BUILT_PRODUCTS_DIR}/RNTAztecView/RNTAztecView.framework", + "${BUILT_PRODUCTS_DIR}/React-Core/React.framework", + "${BUILT_PRODUCTS_DIR}/React-CoreModules/CoreModules.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTActionSheet/RCTActionSheet.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTAnimation/RCTAnimation.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTBlob/RCTBlob.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTImage/RCTImage.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTLinking/RCTLinking.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTNetwork/RCTNetwork.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTSettings/RCTSettings.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTText/RCTText.framework", + "${BUILT_PRODUCTS_DIR}/React-RCTVibration/RCTVibration.framework", + "${BUILT_PRODUCTS_DIR}/React-cxxreact/cxxreact.framework", + "${BUILT_PRODUCTS_DIR}/React-jsi/jsi.framework", + "${BUILT_PRODUCTS_DIR}/React-jsiexecutor/jsireact.framework", + "${BUILT_PRODUCTS_DIR}/React-jsinspector/jsinspector.framework", + "${BUILT_PRODUCTS_DIR}/ReactCommon/ReactCommon.framework", + "${BUILT_PRODUCTS_DIR}/ReactNativeDarkMode/ReactNativeDarkMode.framework", + "${BUILT_PRODUCTS_DIR}/WordPress-Aztec-iOS/Aztec.framework", + "${BUILT_PRODUCTS_DIR}/Yoga/yoga.framework", + "${BUILT_PRODUCTS_DIR}/glog/glog.framework", + "${BUILT_PRODUCTS_DIR}/react-native-get-random-values/react_native_get_random_values.framework", + "${BUILT_PRODUCTS_DIR}/react-native-keyboard-aware-scroll-view/react_native_keyboard_aware_scroll_view.framework", + "${BUILT_PRODUCTS_DIR}/react-native-safe-area/react_native_safe_area.framework", + "${BUILT_PRODUCTS_DIR}/react-native-slider/react_native_slider.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/BVLinearGradient.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/DoubleConversion.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FBReactNativeSpec.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/folly.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Gutenberg.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTTypeSafety.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNSVG.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RNTAztecView.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/React.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CoreModules.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTActionSheet.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTAnimation.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTBlob.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTImage.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTLinking.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTNetwork.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTSettings.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTText.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RCTVibration.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cxxreact.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsi.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsireact.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/jsinspector.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactCommon.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ReactNativeDarkMode.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Aztec.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/yoga.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_get_random_values.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_keyboard_aware_scroll_view.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_safe_area.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/react_native_slider.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-gutenberg/Pods-gutenberg-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Bundle React Native Code And Images"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; + }; + 70B839CE7B6A174DC4DE8FB6 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-gutenbergTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 74E4D376F06BC61DB863CCC7 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-gutenberg-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 944E2FEABB650B8AB00B7918 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-gutenberg-tvOSTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + EAFF01B6A058BE3235FB054C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-gutenberg-tvOS-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 00E356EA1AD99517003FC87E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 00E356F31AD99517003FC87E /* gutenbergTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 13B07F871A680F5B00A75B9A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F151983C2100DC3D000F6E97 /* AppDelegate.swift in Sources */, + FF83DAA92226905A00A34C93 /* CustomImageLoader.swift in Sources */, + FF9A6F4121FA8E2500D36D14 /* MediaPickCoordinator.swift in Sources */, + F151983D2100DC3D000F6E97 /* MediaProvider.swift in Sources */, + 1E4F2E752459E6F200EB73E7 /* WebViewController.swift in Sources */, + FF6836C822035EAB00A0C562 /* MediaUploadCoordinator.swift in Sources */, + 7EC7328F21907E3F00FED2E6 /* GutenbergViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E4771E0B4A5D006451C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 2D02E48C1E0B4A5D006451C7 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DCD954D1E0B4F2C00145EB5 /* gutenbergTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 13B07F861A680F5B00A75B9A /* gutenberg */; + targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; + }; + 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 2D02E47A1E0B4A5D006451C7 /* gutenberg-tvOS */; + targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 13B07FB21A68108700A75B9A /* Base */, + ); + name = LaunchScreen.xib; + path = gutenberg; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 00E356F61AD99517003FC87E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 034874811302E030BA1637A1 /* Pods-gutenbergTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = gutenbergTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + "$(inherited)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gutenberg.app/gutenberg"; + }; + name = Debug; + }; + 00E356F71AD99517003FC87E /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6206F0B13B70AD60CA886558 /* Pods-gutenbergTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + COPY_PHASE_STRIP = NO; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = gutenbergTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + "$(inherited)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gutenberg.app/gutenberg"; + }; + name = Release; + }; + 13B07F941A680F5B00A75B9A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A6B9393B15FAEBA6A3C885F2 /* Pods-gutenberg.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEAD_CODE_STRIPPING = NO; + DEVELOPMENT_TEAM = PZYM8XX95Q; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../react-native-gutenberg-bridge/ios/**", + "$(SRCROOT)/../react-native-aztec/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = gutenberg/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.wordpress.gutenberg.development; + PRODUCT_NAME = GutenbergDemo; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "gutenberg-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 13B07F951A680F5B00A75B9A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 083D3CAD9B26701AE0659EEB /* Pods-gutenberg.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = PZYM8XX95Q; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /usr/include/libxml2, + ); + INFOPLIST_FILE = gutenberg/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.wordpress.gutenberg.development; + PRODUCT_NAME = GutenbergDemo; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "gutenberg-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; + 2D02E4971E0B4A5E006451C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = FE6E9E6AEF37DEEE897DAC75 /* Pods-gutenberg-tvOS.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = "gutenberg-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.gutenberg-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.2; + }; + name = Debug; + }; + 2D02E4981E0B4A5E006451C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D742287512CBBB046F519E11 /* Pods-gutenberg-tvOS.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_NO_COMMON_BLOCKS = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = "gutenberg-tvOS/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.gutenberg-tvOS"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TARGETED_DEVICE_FAMILY = 3; + TVOS_DEPLOYMENT_TARGET = 9.2; + }; + name = Release; + }; + 2D02E4991E0B4A5E006451C7 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = A7031126C4DE90D4D7AAACD5 /* Pods-gutenberg-tvOSTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_TESTABILITY = YES; + GCC_NO_COMMON_BLOCKS = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = "gutenberg-tvOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.gutenberg-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gutenberg-tvOS.app/gutenberg-tvOS"; + TVOS_DEPLOYMENT_TARGET = 10.1; + }; + name = Debug; + }; + 2D02E49A1E0B4A5E006451C7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 549A3E45719DB5BA2F7ECC95 /* Pods-gutenberg-tvOSTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_NO_COMMON_BLOCKS = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../react-native-aztec/example/iOS/example", + "$(SRCROOT)/../node_modules/react-native-svg/ios/**", + "$(SRCROOT)/../node_modules/react-native-safe-area/ios/RNSafeArea", + "$(SRCROOT)/../node_modules/react-native-video/ios/**", + ); + INFOPLIST_FILE = "gutenberg-tvOSTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + "\"$(SRCROOT)/$(TARGET_NAME)\"", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "-lc++", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.gutenberg-tvOSTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/gutenberg-tvOS.app/gutenberg-tvOS"; + TVOS_DEPLOYMENT_TARGET = 10.1; + }; + name = Release; + }; + 83CBBA201A601CBA00E9B192 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 83CBBA211A601CBA00E9B192 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SWIFT_VERSION = 5.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "gutenbergTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 00E356F61AD99517003FC87E /* Debug */, + 00E356F71AD99517003FC87E /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "gutenberg" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 13B07F941A680F5B00A75B9A /* Debug */, + 13B07F951A680F5B00A75B9A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "gutenberg-tvOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2D02E4971E0B4A5E006451C7 /* Debug */, + 2D02E4981E0B4A5E006451C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "gutenberg-tvOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 2D02E4991E0B4A5E006451C7 /* Debug */, + 2D02E49A1E0B4A5E006451C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "gutenberg" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 83CBBA201A601CBA00E9B192 /* Debug */, + 83CBBA211A601CBA00E9B192 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; +} diff --git a/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000000..919434a6254f0e --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000000..18d981003d68d0 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg-tvOS.xcscheme b/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg-tvOS.xcscheme new file mode 100644 index 00000000000000..6f7879ba8657f8 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg-tvOS.xcscheme @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg.xcscheme b/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg.xcscheme new file mode 100644 index 00000000000000..8c6a40ffb9c923 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcodeproj/xcshareddata/xcschemes/gutenberg.xcscheme @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcworkspace/contents.xcworkspacedata b/packages/react-native-editor/ios/gutenberg.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000000000..6b9e6f57aaaccb --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000000000..18d981003d68d0 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000000000..f9b0d7c5ea15f1 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/packages/react-native-editor/ios/gutenberg/AppDelegate.swift b/packages/react-native-editor/ios/gutenberg/AppDelegate.swift new file mode 100644 index 00000000000000..8338adc0a435f8 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/AppDelegate.swift @@ -0,0 +1,33 @@ +import Foundation +import UIKit + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + AppDelegate.setupUITest() + + window = UIWindow(frame: UIScreen.main.bounds) + + let rootViewController = GutenbergViewController() + + window?.rootViewController = UINavigationController(rootViewController: rootViewController) + window?.makeKeyAndVisible() + + return true + } + + static func setupUITest() { + if ( isUITesting() ) { + UIApplication.shared.keyWindow?.layer.speed = 100; + UIView.setAnimationsEnabled(false); + } + } + + static func isUITesting() -> Bool { + return ProcessInfo.processInfo.arguments.contains("uitesting") + } +} diff --git a/packages/react-native-editor/ios/gutenberg/Base.lproj/LaunchScreen.xib b/packages/react-native-editor/ios/gutenberg/Base.lproj/LaunchScreen.xib new file mode 100644 index 00000000000000..16f37cd9324e06 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/Base.lproj/LaunchScreen.xib @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/react-native-editor/ios/gutenberg/GutenbergViewController.swift b/packages/react-native-editor/ios/gutenberg/GutenbergViewController.swift new file mode 100644 index 00000000000000..1a28d073245431 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/GutenbergViewController.swift @@ -0,0 +1,354 @@ + +import UIKit +import Gutenberg +import Aztec + +class GutenbergViewController: UIViewController { + + fileprivate lazy var gutenberg = Gutenberg(dataSource: self, extraModules: [CustomImageLoader()]) + fileprivate var htmlMode = false + fileprivate var mediaPickCoordinator: MediaPickCoordinator? + fileprivate lazy var mediaUploadCoordinator: MediaUploadCoordinator = { + let mediaUploadCoordinator = MediaUploadCoordinator(gutenberg: self.gutenberg) + return mediaUploadCoordinator + }() + fileprivate var longPressGesture: UILongPressGestureRecognizer! + fileprivate var contentInfo: ContentInfo? + + override func loadView() { + view = gutenberg.rootView + } + + override func viewDidLoad() { + super.viewDidLoad() + configureNavigationBar() + gutenberg.delegate = self + navigationController?.navigationBar.isTranslucent = false + registerLongPressGestureRecognizer() + + _ = try! FallbackJavascriptInjection(blockHTML: "Hello", userId: "1") + } + + @objc func moreButtonPressed(sender: UIBarButtonItem) { + showMoreSheet() + } + + @objc func saveButtonPressed(sender: UIBarButtonItem) { + gutenberg.requestHTML() + } + + func registerLongPressGestureRecognizer() { + longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(handleLongPress)) + view.addGestureRecognizer(longPressGesture) + } + + @objc func handleLongPress() { + NotificationCenter.default.post(Notification(name: MediaUploadCoordinator.failUpload )) + } +} + +extension GutenbergViewController: GutenbergBridgeDelegate { + + func gutenbergDidRequestFetch(path: String, completion: @escaping (Result) -> Void) { + completion(Result.success([:])) + } + + func editorDidAutosave() { + print("➡️ Editor Did Autosave") + } + + func gutenbergDidLoad() { + gutenberg.setFocusOnTitle() + } + + func gutenbergDidMount(unsupportedBlockNames: [String]) { + print("gutenbergDidMount(unsupportedBlockNames: \(unsupportedBlockNames))") + gutenberg.requestHTML() + } + + func gutenbergDidProvideHTML(title: String, html: String, changed: Bool, contentInfo: ContentInfo?) { + print("didProvideHTML:") + print("↳ Content changed: \(changed)") + print("↳ Title: \(title)") + print("↳ HTML: \(html)") + print("↳ Content Info: \(contentInfo)") + self.contentInfo = contentInfo + } + + func gutenbergDidRequestMedia(from source: Gutenberg.MediaSource, filter: [Gutenberg.MediaType], allowMultipleSelection: Bool, with callback: @escaping MediaPickerDidPickMediaCallback) { + guard let currentFilter = filter.first else { + return + } + switch source { + case .mediaLibrary: + print("Gutenberg did request media picker, passing a sample url in callback") + switch currentFilter { + case .image: + if(allowMultipleSelection) { + callback([MediaInfo(id: 1, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image"), + MediaInfo(id: 3, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image", caption: "Mountain")]) + } else { + callback([MediaInfo(id: 1, url: "https://cldup.com/cXyG__fTLN.jpg", type: "image", caption: "Mountain")]) + } + case .video: + if(allowMultipleSelection) { + callback([MediaInfo(id: 2, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video"), + MediaInfo(id: 4, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video")]) + } else { + callback([MediaInfo(id: 2, url: "https://i.cloudup.com/YtZFJbuQCE.mov", type: "video", caption: "Cloudup")]) + } + default: + break + } + case .deviceLibrary: + print("Gutenberg did request a device media picker, opening the device picker") + pickAndUpload(from: .savedPhotosAlbum, filter: currentFilter, callback: callback) + case .deviceCamera: + print("Gutenberg did request a device media picker, opening the camera picker") + pickAndUpload(from: .camera, filter: currentFilter, callback: callback) + default: break + } + } + + func gutenbergDidRequestImport(from url: URL, with callback: @escaping MediaImportCallback) { + let id = mediaUploadCoordinator.upload(url: url) + callback(MediaInfo(id: id, url: url.absoluteString, type: "image")) + } + + func pickAndUpload(from source: UIImagePickerController.SourceType, filter: Gutenberg.MediaType, callback: @escaping MediaPickerDidPickMediaCallback) { + mediaPickCoordinator = MediaPickCoordinator(presenter: self, filter: filter, callback: { (url) in + guard let url = url, let mediaID = self.mediaUploadCoordinator.upload(url: url) else { + callback([MediaInfo(id: nil, url: nil, type: nil)]) + return + } + callback([MediaInfo(id: mediaID, url: url.absoluteString, type: "image")]) + self.mediaPickCoordinator = nil + } ) + mediaPickCoordinator?.pick(from: source) + } + + func gutenbergDidRequestMediaUploadSync() { + print("Gutenberg request for media uploads to be resync") + } + + func gutenbergDidRequestMediaUploadActionDialog(for mediaID: Int32) { + guard let progress = mediaUploadCoordinator.progressForUpload(mediaID: mediaID) else { + return + } + + let title: String = "Media Options" + var message: String? = "" + let alertController = UIAlertController(title: title, message: nil, preferredStyle: .actionSheet) + let dismissAction = UIAlertAction(title: "Dismiss", style: .cancel) { (action) in + + } + alertController.addAction(dismissAction) + + if progress.fractionCompleted < 1 && mediaUploadCoordinator.successfullUpload { + let cancelUploadAction = UIAlertAction(title: "Cancel upload", style: .destructive) { (action) in + self.mediaUploadCoordinator.cancelUpload(with: mediaID) + } + alertController.addAction(cancelUploadAction) + } else if let error = progress.userInfo[.mediaError] as? String { + message = error + let retryUploadAction = UIAlertAction(title: "Retry upload", style: .default) { (action) in + self.mediaUploadCoordinator.retryUpload(with: mediaID) + } + alertController.addAction(retryUploadAction) + } + + alertController.title = title + alertController.message = message + alertController.popoverPresentationController?.sourceView = view + alertController.popoverPresentationController?.sourceRect = view.frame + alertController.popoverPresentationController?.permittedArrowDirections = .any + present(alertController, animated: true, completion: nil) + } + + /// Tells the delegate that an image block requested for the upload cancelation. + /// + func gutenbergDidRequestMediaUploadCancelation(for mediaID: Int32) { + guard let progress = mediaUploadCoordinator.progressForUpload(mediaID: mediaID) else { + return + } + progress.cancel() + } + + func gutenbergDidEmitLog(message: String, logLevel: LogLevel) { + switch logLevel { + case .trace: + print("Debug: \(message)") + case .info: + print("Info: \(message)") + case .warn: + print("Warn: \(message)") + case .error: + print("Error: \(message)") + case .fatal: + print("Fatal: \(message)") + } + } + + func gutenbergDidRequestImagePreview(with fullSizeUrl: URL, thumbUrl: URL?) { + print("Gutenberg requested fullscreen image preview for " + fullSizeUrl.absoluteString) + } + + func gutenbergDidRequestMediaEditor(with mediaUrl: URL, callback: @escaping MediaPickerDidPickMediaCallback) { + print("Gutenberg requested media editor for " + mediaUrl.absoluteString) + callback([MediaInfo(id: 1, url: "https://cldup.com/Fz-ASbo2s3.jpg", type: "image")]) + } + + func gutenbergDidLogUserEvent(_ event: GutenbergUserEvent) { + print("Gutenberg loged user event") + } + + func gutenbergDidRequestUnsupportedBlockFallback(for block: Block) { + print("Requesting Fallback for \(block)") + let controller = try! WebViewController(block: block, userId: "0") + controller.delegate = self + present(UINavigationController(rootViewController: controller), animated: true) + } + + func gutenbergDidRequestMention(callback: @escaping (Result) -> Void) { + callback(.success("matt")) + } + + func gutenbergDidRequestStarterPageTemplatesTooltipShown() -> Bool { + return false; + } + + func gutenbergDidRequestSetStarterPageTemplatesTooltipShown(_ tooltipShown: Bool) { + print("Gutenberg requested setting tooltip flag") + } +} + +extension GutenbergViewController: GutenbergWebDelegate { + func webController(controller: GutenbergWebSingleBlockViewController, didPressSave block: Block) { + gutenberg.replace(block: block) + dismiss(webController: controller) + } + + func webControllerDidPressClose(controller: GutenbergWebSingleBlockViewController) { + dismiss(webController: controller) + } + + func webController(controller: GutenbergWebSingleBlockViewController, didLog log: String) { + print("WebView: \(log)") + } + + private func dismiss(webController: GutenbergWebSingleBlockViewController) { + webController.cleanUp() + dismiss(animated: true) + } +} + +extension GutenbergViewController: GutenbergBridgeDataSource { + func gutenbergLocale() -> String? { + return Locale.preferredLanguages.first ?? "en" + } + + func gutenbergTranslations() -> [String : [String]]? { + return nil + } + + func gutenbergInitialContent() -> String? { + return nil + } + + func gutenbergInitialTitle() -> String? { + return nil + } + + func gutenbergCapabilities() -> [String : Bool]? { + return ["mentions": true] + } + + func aztecAttachmentDelegate() -> TextViewAttachmentDelegate { + return ExampleAttachmentDelegate() + } + + func gutenbergEditorTheme() -> GutenbergEditorTheme? { + return nil + } +} + +//MARK: - Navigation bar + +extension GutenbergViewController { + + func configureNavigationBar() { + addSaveButton() + addMoreButton() + } + + func addSaveButton() { + navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, + target: self, + action: #selector(saveButtonPressed(sender:))) + } + + func addMoreButton() { + navigationItem.rightBarButtonItem = UIBarButtonItem(title: "...", + style: .plain, + target: self, + action: #selector(moreButtonPressed(sender:))) + } +} + +//MARK: - More actions + +extension GutenbergViewController { + + func showMoreSheet() { + let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) + alert.popoverPresentationController?.barButtonItem = navigationItem.rightBarButtonItem + if let contentInfo = contentInfo { + alert.title = "Content Structure\nBlocks: \(contentInfo.blockCount), Words: \(contentInfo.wordCount), Characters: \(contentInfo.characterCount)" + } + let cancelAction = UIAlertAction(title: "Keep Editing", style: .cancel) + alert.addAction(toggleHTMLModeAction) + alert.addAction(updateHtmlAction) + alert.addAction(cancelAction) + + present(alert, animated: true) + } + + var toggleHTMLModeAction: UIAlertAction { + return UIAlertAction( + title: htmlMode ? "Switch To Visual" : "Switch to HTML", + style: .default, + handler: { [unowned self] action in + self.toggleHTMLMode(action) + }) + } + + var updateHtmlAction: UIAlertAction { + return UIAlertAction( + title: "Update HTML", + style: .default, + handler: { [unowned self] action in + let alert = self.alertWithTextInput(using: { [unowned self] (htmlInput) in + if let input = htmlInput { + self.gutenberg.updateHtml(input) + } + }) + self.present(alert, animated: true, completion: nil) + }) + } + + func alertWithTextInput(using handler: ((String?) -> Void)?) -> UIAlertController { + let alert = UIAlertController(title: "Enter HTML", message: nil, preferredStyle: .alert) + alert.addTextField() + let submitAction = UIAlertAction(title: "Submit", style: .default) { [unowned alert] (action) in + handler?(alert.textFields?.first?.text) + } + alert.addAction(submitAction) + alert.addAction(UIAlertAction(title: "Cancel", style: .cancel)) + return alert + } + + func toggleHTMLMode(_ action: UIAlertAction) { + htmlMode = !htmlMode + gutenberg.toggleHTMLMode() + } +} diff --git a/packages/react-native-editor/ios/gutenberg/Images.xcassets/AppIcon.appiconset/Contents.json b/packages/react-native-editor/ios/gutenberg/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000000000..19882d568afa3d --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,53 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/packages/react-native-editor/ios/gutenberg/Images.xcassets/Contents.json b/packages/react-native-editor/ios/gutenberg/Images.xcassets/Contents.json new file mode 100644 index 00000000000000..da4a164c918651 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/Images.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/Contents.json b/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/Contents.json new file mode 100644 index 00000000000000..60b8cf92b7beda --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "aztec.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/aztec.png b/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/aztec.png new file mode 100644 index 00000000000000..81b4e8d73e7e87 Binary files /dev/null and b/packages/react-native-editor/ios/gutenberg/Images.xcassets/aztec.imageset/aztec.png differ diff --git a/packages/react-native-editor/ios/gutenberg/Info.plist b/packages/react-native-editor/ios/gutenberg/Info.plist new file mode 100644 index 00000000000000..3929cb00cf60bf --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/Info.plist @@ -0,0 +1,79 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleDisplayName + Gutenberg + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSExceptionDomains + + localhost + + NSExceptionAllowsInsecureHTTPLoads + + + + + NSCameraUsageDescription + To take photos or videos to use in your posts. + NSLocationUsageDescription + The app would like to add your location to posts on sites where you have enabled geotagging. + NSLocationWhenInUseUsageDescription + The app would like to add your location to posts on sites where you have enabled geotagging. + NSMicrophoneUsageDescription + Enable microphone access to record sound in your videos. + NSPhotoLibraryAddUsageDescription + To add photos or videos to your posts. + NSPhotoLibraryUsageDescription + To add photos or videos to your posts. + UIAppFonts + + NotoSerif-BoldItalic.ttf + NotoSerif-Regular.ttf + NotoSerif-Italic.ttf + NotoSerif-Bold.ttf + + UILaunchStoryboardName + LaunchScreen + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/react-native-editor/ios/gutenberg/MediaPickCoordinator.swift b/packages/react-native-editor/ios/gutenberg/MediaPickCoordinator.swift new file mode 100644 index 00000000000000..b6facdde82f36f --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/MediaPickCoordinator.swift @@ -0,0 +1,89 @@ + +import Foundation +import UIKit +import Gutenberg +import CoreServices + +class MediaPickCoordinator: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { + + private let presenter: UIViewController + private let callback: (URL?) -> Void + private let filter: Gutenberg.MediaType + + init(presenter: UIViewController, + filter: Gutenberg.MediaType, + callback: @escaping (URL?) -> Void) { + self.presenter = presenter + self.callback = callback + self.filter = filter + } + + private var mediaTypes: [ String ]? { + switch filter { + case .image: + return [ kUTTypeImage as String ] + case .video: + return [ kUTTypeVideo as String, kUTTypeMovie as String ] + default: + return nil + } + } + + func pick(from source: UIImagePickerController.SourceType) { + guard UIImagePickerController.isSourceTypeAvailable(source) else { + // Camera not available, bound to happen in the simulator + callback(nil) + return + } + let pickerController = UIImagePickerController() + pickerController.sourceType = source + if let mediaTypes = mediaTypes { + pickerController.mediaTypes = mediaTypes + } + pickerController.delegate = self + presenter.show(pickerController, sender: nil) + } + + func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { + presenter.dismiss(animated: true, completion: nil) + callback(nil) + } + + func save(image: UIImage, toTemporaryDirectoryUsingName name: String) -> URL? { + let url = URL(fileURLWithPath: NSTemporaryDirectory() + name + ".jpg") + guard let data = image.jpegData(compressionQuality: 1.0) else { + return nil + } + do { + try data.write(to: url) + return url + } catch { + return nil + } + } + + func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { + presenter.dismiss(animated: true, completion: nil) + let mediaID = UUID().uuidString + switch filter { + case .image: + guard + let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage, + let url = save(image: image, toTemporaryDirectoryUsingName: mediaID) + else { + callback(nil) + return + } + callback(url) + case .video: + guard let url = info[UIImagePickerController.InfoKey.mediaURL] as? URL else { + callback(nil) + return + } + callback(url) + default: + callback(nil) + } + } + +} diff --git a/packages/react-native-editor/ios/gutenberg/MediaProvider.swift b/packages/react-native-editor/ios/gutenberg/MediaProvider.swift new file mode 100644 index 00000000000000..91f6d4f9c203ee --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/MediaProvider.swift @@ -0,0 +1,58 @@ +import Aztec + +class ExampleAttachmentImageProvider: TextViewAttachmentImageProvider { + func textView(_ textView: TextView, shouldRender attachment: NSTextAttachment) -> Bool { + return true + } + + func textView(_ textView: TextView, boundsFor attachment: NSTextAttachment, with lineFragment: CGRect) -> CGRect { + return CGRect(x: 0, y: 0, width: 20, height: 20) + } + + func textView(_ textView: TextView, imageFor attachment: NSTextAttachment, with size: CGSize) -> UIImage? { + let image = UIImage(named: "aztec")! + return scale(image, to: size) + } + + private func scale(_ image: UIImage, to newSize:CGSize) -> UIImage { + UIGraphicsBeginImageContextWithOptions(newSize, false, 0.0) + image.draw(in: CGRect(origin: CGPoint.zero, size: CGSize(width: newSize.width, height: newSize.height))) + let newImage:UIImage = UIGraphicsGetImageFromCurrentImageContext()! + UIGraphicsEndImageContext() + return newImage + } +} + +class ExampleAttachmentDelegate: TextViewAttachmentDelegate { + func textView(_ textView: TextView, attachment: NSTextAttachment, imageAt url: URL, onSuccess success: @escaping (UIImage) -> Void, onFailure failure: @escaping () -> Void) { + URLSession.shared.dataTask(with: url) { (data, response, error) in + guard let data = data, let image = UIImage(data: data) else { + failure() + return + } + DispatchQueue.main.async { + success(image) + } + }.resume() + } + + func textView(_ textView: TextView, urlFor imageAttachment: ImageAttachment) -> URL? { + return URL(string: "www.google.com") + } + + func textView(_ textView: TextView, placeholderFor attachment: NSTextAttachment) -> UIImage { + return UIImage(named: "aztec")! + } + + func textView(_ textView: TextView, deletedAttachment attachment: MediaAttachment) { + + } + + func textView(_ textView: TextView, selected attachment: NSTextAttachment, atPosition position: CGPoint) { + + } + + func textView(_ textView: TextView, deselected attachment: NSTextAttachment, atPosition position: CGPoint) { + + } +} diff --git a/packages/react-native-editor/ios/gutenberg/MediaUploadCoordinator.swift b/packages/react-native-editor/ios/gutenberg/MediaUploadCoordinator.swift new file mode 100644 index 00000000000000..9571d532d92c87 --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/MediaUploadCoordinator.swift @@ -0,0 +1,93 @@ + +import Foundation +import UIKit +import Gutenberg + +class MediaUploadCoordinator: NSObject { + + static let failUpload: Notification.Name = Notification.Name(rawValue: "Notification.FailUpload") + + private let gutenberg: Gutenberg + + private var activeUploads: [Int32: Progress] = [:] + private(set) var successfullUpload = true + + init(gutenberg: Gutenberg) { + self.gutenberg = gutenberg + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(failUpload), name: MediaUploadCoordinator.failUpload, object: nil) + } + + func upload(url: URL) -> Int32? { + //Make sure the media is not larger than a 32 bits to number to avoid problems when bridging to JS + let mediaID = Int32(truncatingIfNeeded:UUID().uuidString.hash) + let progress = Progress(parent: nil, userInfo: [ProgressUserInfoKey.mediaID: mediaID, ProgressUserInfoKey.mediaURL: url]) + progress.totalUnitCount = 100 + activeUploads[mediaID] = progress + let timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timerFireMethod(_:)), userInfo: progress, repeats: true) + progress.cancellationHandler = { () in + timer.invalidate() + self.gutenberg.mediaUploadUpdate(id: mediaID, state: .reset, progress: 0, url: nil, serverID: nil) + } + return mediaID + } + + func progressForUpload(mediaID: Int32) -> Progress? { + return activeUploads[mediaID] + } + + func retryUpload(with mediaID: Int32) { + guard let progress = activeUploads[mediaID] else { + return + } + progress.completedUnitCount = 0 + successfullUpload = true + Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(timerFireMethod(_:)), userInfo: progress, repeats: true) + } + + func cancelUpload(with mediaID: Int32) { + guard let progress = activeUploads[mediaID] else { + return + } + progress.cancel() + } + + @objc func failUpload() { + successfullUpload = false + } + + @objc func timerFireMethod(_ timer: Timer) { + guard let progress = timer.userInfo as? Progress, + let mediaID = progress.userInfo[.mediaID] as? Int32, + let mediaURL = progress.userInfo[.mediaURL] as? URL + else { + timer.invalidate() + return + } + progress.completedUnitCount += 1 + + if !successfullUpload { + timer.invalidate() + progress.setUserInfoObject("Network upload failed", forKey: .mediaError) + gutenberg.mediaUploadUpdate(id: mediaID, state: .failed, progress: 1, url: nil, serverID: nil) + successfullUpload = true + return + } + + //Variable to switch upload final state from success to failure. + if progress.fractionCompleted < 1 { + gutenberg.mediaUploadUpdate(id: mediaID, state: .uploading, progress: Float(progress.fractionCompleted), url: nil, serverID: nil) + } else if progress.fractionCompleted >= 1 { + timer.invalidate() + gutenberg.mediaUploadUpdate(id: mediaID, state: .succeeded, progress: 1, url: mediaURL, serverID: mediaID) + activeUploads[mediaID] = nil + } + } + +} + +extension ProgressUserInfoKey { + static let mediaID = ProgressUserInfoKey("mediaID") + static let mediaURL = ProgressUserInfoKey("mediaURL") + static let mediaError = ProgressUserInfoKey("mediaError") +} diff --git a/packages/react-native-editor/ios/gutenberg/WebViewController.swift b/packages/react-native-editor/ios/gutenberg/WebViewController.swift new file mode 100644 index 00000000000000..40f9c61c99900d --- /dev/null +++ b/packages/react-native-editor/ios/gutenberg/WebViewController.swift @@ -0,0 +1,5 @@ +import Gutenberg + +class WebViewController: GutenbergWebSingleBlockViewController { + +} diff --git a/packages/react-native-editor/ios/gutenbergTests/Info.plist b/packages/react-native-editor/ios/gutenbergTests/Info.plist new file mode 100644 index 00000000000000..886825ccc9bf0d --- /dev/null +++ b/packages/react-native-editor/ios/gutenbergTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/packages/react-native-editor/ios/gutenbergTests/gutenbergTests.m b/packages/react-native-editor/ios/gutenbergTests/gutenbergTests.m new file mode 100644 index 00000000000000..a549f9a8783176 --- /dev/null +++ b/packages/react-native-editor/ios/gutenbergTests/gutenbergTests.m @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +#import +#import + +#define TIMEOUT_SECONDS 600 +#define TEXT_TO_LOOK_FOR @"Welcome to React Native!" + +@interface gutenbergTests : XCTestCase + +@end + +@implementation gutenbergTests + +- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test +{ + if (test(view)) { + return YES; + } + for (UIView *subview in [view subviews]) { + if ([self findSubviewInView:subview matching:test]) { + return YES; + } + } + return NO; +} + +- (void)testRendersWelcomeScreen +{ + UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; + BOOL foundElement = NO; + + __block NSString *redboxError = nil; + RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { + if (level >= RCTLogLevelError) { + redboxError = message; + } + }); + + while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + + foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { + if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { + return YES; + } + return NO; + }]; + } + + RCTSetLogFunction(RCTDefaultLogFunction); + + XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); + XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); +} + + +@end diff --git a/packages/react-native-editor/metro.config.js b/packages/react-native-editor/metro.config.js new file mode 100644 index 00000000000000..b3b71d59566a23 --- /dev/null +++ b/packages/react-native-editor/metro.config.js @@ -0,0 +1,22 @@ +/** + * External dependencies + */ +const path = require( 'path' ); + +module.exports = { + watchFolders: [ path.resolve( __dirname, '../..' ) ], + resolver: { + sourceExts: [ 'js', 'json', 'scss', 'sass', 'ts', 'tsx' ], + platforms: [ 'native', 'android', 'ios' ], + }, + transformer: { + babelTransformerPath: require.resolve( './sass-transformer.js' ), + getTransformOptions: async () => ( { + transform: { + experimentalImportSupport: false, + inlineRequires: false, + }, + } ), + }, + maxWorkers: 2, +}; diff --git a/packages/react-native-editor/package.json b/packages/react-native-editor/package.json new file mode 100644 index 00000000000000..24037e434c78b9 --- /dev/null +++ b/packages/react-native-editor/package.json @@ -0,0 +1,127 @@ +{ + "name": "@wordpress/react-native-editor", + "version": "1.30.0", + "description": "Mobile WordPress gutenberg editor.", + "author": "The WordPress Contributors", + "license": "GPL-2.0-or-later", + "keywords": [ + "wordpress", + "react-native" + ], + "private": true, + "config": { + "jsfiles": "./*.js src/*.js src/**/*.js src/**/**/*.js", + "scssfiles": "src/*.scss src/**/*.scss" + }, + "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/react-native-editor/README.md", + "repository": { + "type": "git", + "url": "https://github.com/WordPress/gutenberg.git", + "directory": "packages/react-native-editor" + }, + "bugs": { + "url": "https://github.com/WordPress/gutenberg/issues" + }, + "engines": { + "node": ">=10", + "npm": ">=6.9" + }, + "main": "src/index.js", + "react-native": "src/index", + "dependencies": { + "@babel/runtime": "^7.9.2", + "@react-native-community/slider": "git+https://github.com/wordpress-mobile/react-native-slider.git#5ad284d92b8d886e366445bf215be741ed53ddc6", + "@wordpress/api-fetch": "file:../api-fetch", + "@wordpress/block-editor": "file:../block-editor", + "@wordpress/block-library": "file:../block-library", + "@wordpress/blocks": "file:../blocks", + "@wordpress/components": "file:../components", + "@wordpress/data": "file:../data", + "@wordpress/edit-post": "file:../edit-post", + "@wordpress/element": "file:../element", + "@wordpress/hooks": "file:../hooks", + "@wordpress/i18n": "file:../i18n", + "@wordpress/react-native-aztec": "file:../react-native-aztec", + "@wordpress/react-native-bridge": "file:../react-native-bridge", + "fast-average-color": "^4.3.0", + "jed": "^1.1.1", + "jsc-android": "^241213.1.0", + "jsdom-jscore-rn": "git+https://github.com/iamcco/jsdom-jscore-rn.git#a562f3d57c27c13e5bfc8cf82d496e69a3ba2800", + "metro-react-native-babel-preset": "0.57.0", + "metro-react-native-babel-transformer": "0.56.0", + "node-fetch": "^2.3.0", + "react-native": "0.61.5", + "react-native-dark-mode": "git+https://github.com/wordpress-mobile/react-native-dark-mode.git#f09bf1480e7b34536413ab3300f29e4375edb2c6", + "react-native-get-random-values": "git+https://github.com/wordpress-mobile/react-native-get-random-values.git#f03f2c16414aff4ea76064dcd00a9e3c6efc838d", + "react-native-hr": "git+https://github.com/Riglerr/react-native-hr.git#2d01a5cf77212d100e8b99e0310cce5234f977b3", + "react-native-hsv-color-picker": "git+https://github.com/wordpress-mobile/react-native-hsv-color-picker", + "react-native-keyboard-aware-scroll-view": "git+https://github.com/wordpress-mobile/react-native-keyboard-aware-scroll-view.git#gb-v0.8.8", + "react-native-linear-gradient": "git+https://github.com/wordpress-mobile/react-native-linear-gradient.git#52bf43077171cff8714ce3e0155f3ebb7f55bc37", + "react-native-modal": "^6.5.0", + "react-native-safe-area": "^0.5.0", + "react-native-sass-transformer": "^1.1.1", + "react-native-svg": "git+https://github.com/wordpress-mobile/react-native-svg.git#a628e92990a2404e30a0086f168bd2b5b7b4ce96", + "react-native-url-polyfill": "^1.1.2", + "react-native-video": "git+https://github.com/wordpress-mobile/react-native-video.git#1b964b107863351ed744fc104d7952bbec3e2d4f" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "start": "react-native start", + "start:reset": "npm run clean:runtime && npm run start -- --reset-cache", + "start:debug": "node --inspect-brk node_modules/.bin/react-native start", + "patch-metro-no-file-watch": "cp ../../node_modules/metro/src/node-haste/DependencyGraph.js ./ && cp DependencyGraph.js.patched ../../node_modules/metro/src/node-haste/DependencyGraph.js", + "un-patch-metro-no-file-watch": "mv ./DependencyGraph.js ../../node_modules/metro/src/node-haste/DependencyGraph.js", + "prebundle": "npm run i18n-cache:force", + "prebundle:android": "npm run patch-metro-no-file-watch", + "postbundle:android": "npm run un-patch-metro-no-file-watch", + "bundle": "npm run bundle:android && npm run bundle:ios", + "bundle:android": "mkdir -p bundle/android && react-native bundle --platform android --dev false --entry-file index.js --assets-dest bundle/android --bundle-output bundle/android/App.js --sourcemap-output bundle/android/App.js.map", + "bundle:ios": "mkdir -p bundle/ios && react-native bundle --platform ios --dev false --entry-file index.js --assets-dest bundle/ios --bundle-output bundle/ios/App.js --sourcemap-output bundle/ios/App.js.map", + "i18n-cache": "node i18n-cache/index.js", + "i18n-cache:force": "cross-env REFRESH_I18N_CACHE=1 node i18n-cache/index.js", + "postinstall": "npm run i18n-cache", + "android": "react-native run-android", + "prewpandroid": "rm -Rf $TMPDIR/gbmobile-wpandroidfakernroot && mkdir $TMPDIR/gbmobile-wpandroidfakernroot && ln -s $(cd \"$(dirname \"../../../../../\")\"; pwd) $TMPDIR/gbmobile-wpandroidfakernroot/android", + "wpandroid": "npm run android -- --root $TMPDIR/gbmobile-wpandroidfakernroot --variant wasabiDebug --appIdSuffix beta --appFolder WordPress --main-activity=ui.WPLaunchActivity", + "preios": "cd ios && (bundle check --path=vendor/bundle > /dev/null || bundle install) && bundle exec pod install --repo-update", + "preios:carthage": "cd ../react-native-aztec && npm run install-aztec-ios", + "preios:carthage:update": "cd ../react-native-aztec && npm run update-aztec-ios", + "preios:xcode10": "cd ../../node_modules/react-native && ./scripts/ios-install-third-party.sh && cd third-party/glog-0.3.5 && [ -f libglog.pc ] || ../../scripts/ios-configure-glog.sh", + "ios": "react-native run-ios", + "ios:fast": "react-native run-ios", + "test": "cross-env NODE_ENV=test jest --verbose --config ../../test/native/jest.config.js", + "test:debug": "cross-env NODE_ENV=test node --inspect-brk jest --runInBand --verbose --config ../../test/native/jest.config.js", + "device-tests": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=3 --reporters=default --reporters=jest-junit --verbose --config ../../test/native/jest_ui.config.js", + "device-tests-canary": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles --no-cache --maxWorkers=2 --testNamePattern=@canary --reporters=default --reporters=jest-junit --verbose --config ../../test/native/jest_ui.config.js", + "device-tests:local": "cross-env NODE_ENV=test jest --runInBand --reporters=default --reporters=jest-junit --detectOpenHandles --verbose --forceExit --config ../../test/native/jest_ui.config.js", + "device-tests:debug": "cross-env NODE_ENV=test node $NODE_DEBUG_OPTION --inspect-brk node_modules/jest/bin/jest --runInBand --reporters=default --reporters=jest-junit --detectOpenHandles --verbose --config ../../test/native/jest_ui.config.js", + "test:e2e": "npm run test:e2e:android && npm run test:e2e:ios", + "test:e2e:android": "TEST_RN_PLATFORM=android npm run device-tests", + "test:e2e:android:debug": "TEST_RN_PLATFORM=android npm run device-tests:debug", + "test:e2e:ios": "TEST_RN_PLATFORM=ios npm run device-tests", + "test:e2e:android:local": "npm run test:e2e:build-app:android && npm run test:e2e:install-app:android && TEST_RN_PLATFORM=android npm run device-tests:local", + "test:e2e:android:local:debug": "npm run test:e2e:build-app:android && npm run test:e2e:install-app:android && npm run test:e2e:android:debug", + "test:e2e:ios:local": "npm run test:e2e:bundle:ios && npm run test:e2e:build-app:ios && TEST_RN_PLATFORM=ios npm run device-tests:local", + "test:e2e:bundle:android": "mkdir -p android/app/src/main/assets && react-native bundle --reset-cache --platform android --dev false --minify false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res", + "test:e2e:build-app:android": "npm run test:e2e:bundle:android && cd android && ./gradlew clean && ./gradlew assembleDebug", + "test:e2e:install-app:android": "cd android && ./gradlew installDebug", + "test:e2e:bundle:ios": "mkdir -p ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app && react-native bundle --reset-cache --platform=ios --dev=false --minify false --entry-file=index.js --bundle-output=./ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app/main.jsbundle --assets-dest=./ios/build/gutenberg/Build/Products/Release-iphonesimulator/GutenbergDemo.app", + "test:e2e:build-app:ios": "npm run ios -- --configuration Release --no-packager --simulator 'iPhone 11 (13.4)'", + "build:gutenberg": "cd gutenberg && npm ci && npm run build", + "clean": "npm run clean:build-artifacts; npm run clean:aztec; npm run cache clean; npm run clean:haste; npm run clean:jest; npm run clean:metro; npm run clean:react; npm run clean:watchman", + "clean:runtime": "npm run clean:haste; npm run clean:react; npm run clean:metro; npm run clean:jest; npm run clean:watchman; npm run clean:babel-cache", + "clean:build-artifacts": "rm -rf ./ios/build && rm -rf ./ios/Pods", + "clean:aztec": "cd ../react-native-aztec && npm run clean", + "clean:haste": "rm -rf /tmp/haste-map-react-native-packager-*", + "clean:install": "npm run clean; npm install", + "clean:jest": "jest --clearCache --config ../../test/native/jest.config.js; rm -rf $TMPDIR/jest_*", + "clean:metro": "rm -rf $TMPDIR/metro-cache-*;", + "clean:react": "rm -rf $TMPDIR/react-*", + "clean:watchman": "command -v watchman >/dev/null 2>&1 && watchman watch-del-all; true", + "clean:babel-cache": "rm -rf ../../node_modules/.cache/babel-loader/*", + "clean:i18n-cache": "rm -rf ./i18n-cache/data/*.json && rm -f ./i18n-cache/index.native.js", + "version": "npm run bundle && git add -A bundle" + } +} diff --git a/packages/react-native-editor/resources/fonts/NotoSerif-Bold.ttf b/packages/react-native-editor/resources/fonts/NotoSerif-Bold.ttf new file mode 100644 index 00000000000000..50b12d3f721392 Binary files /dev/null and b/packages/react-native-editor/resources/fonts/NotoSerif-Bold.ttf differ diff --git a/packages/react-native-editor/resources/fonts/NotoSerif-BoldItalic.ttf b/packages/react-native-editor/resources/fonts/NotoSerif-BoldItalic.ttf new file mode 100644 index 00000000000000..741402e9a97f66 Binary files /dev/null and b/packages/react-native-editor/resources/fonts/NotoSerif-BoldItalic.ttf differ diff --git a/packages/react-native-editor/resources/fonts/NotoSerif-Italic.ttf b/packages/react-native-editor/resources/fonts/NotoSerif-Italic.ttf new file mode 100644 index 00000000000000..84349fb19c9b7f Binary files /dev/null and b/packages/react-native-editor/resources/fonts/NotoSerif-Italic.ttf differ diff --git a/packages/react-native-editor/resources/fonts/NotoSerif-Regular.ttf b/packages/react-native-editor/resources/fonts/NotoSerif-Regular.ttf new file mode 100644 index 00000000000000..ec8afe61f4508a Binary files /dev/null and b/packages/react-native-editor/resources/fonts/NotoSerif-Regular.ttf differ diff --git a/packages/react-native-editor/sass-transformer.js b/packages/react-native-editor/sass-transformer.js new file mode 100644 index 00000000000000..978c645692b24c --- /dev/null +++ b/packages/react-native-editor/sass-transformer.js @@ -0,0 +1,150 @@ +/** + * Parts of this source were derived and modified from react-native-sass-transformer, + * released under the MIT license. + * + * https://github.com/kristerkari/react-native-sass-transformer + * + * The MIT License (MIT) + + * Copyright (c) 2018 Krister Kari + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +// TODO: create a new npm package with this transformer, or extend 'react-native-sass-transformer' + +/** + * External dependencies + */ +const fs = require( 'fs' ); +const path = require( 'path' ); + +// eslint-disable-next-line import/no-extraneous-dependencies +const sass = require( 'node-sass' ); +// eslint-disable-next-line import/no-extraneous-dependencies +const css2rn = require( 'css-to-react-native-transform' ).default; + +const upstreamTransformer = require( 'metro-react-native-babel-transformer' ); + +// TODO: need to find a way to pass the include paths and the default asset files via some config +const autoImportIncludePaths = [ + path.join( path.dirname( __filename ), 'src' ), + path.join( path.dirname( __filename ), '../base-styles' ), +]; +const autoImportAssets = [ + '_colors.scss', + '_breakpoints.scss', + '_variables.scss', + '_native.scss', + '_mixins.scss', + '_animations.scss', + '_z-index.scss', +]; +const imports = + '@import "' + autoImportAssets.join( '";\n@import "' ) + '";\n\n'; + +// Iterate through the include paths and extensions to find the file variant +function findVariant( name, extensions, includePaths ) { + for ( let i = 0; i < includePaths.length; i++ ) { + const includePath = includePaths[ i ]; + + // try to find the file iterating through the extensions, in order. + const foundExtention = extensions.find( ( extension ) => { + const fname = includePath + '/' + name + extension; + const partialfname = includePath + '/_' + name + extension; + return fs.existsSync( fname ) || fs.existsSync( partialfname ); + } ); + + if ( foundExtention ) { + return includePath + '/' + name + foundExtention; + } + } + + return false; +} + +// Transform function taken from react-native-sass-transformer but extended to have more include paths +// and detect and use RN platform specific file variants +function transform( src, filename, options ) { + if ( typeof src === 'object' ) { + // handle RN >= 0.46 + ( { src, filename, options } = src ); + } + + const exts = [ + // add the platform specific extension, first in the array to take precedence + options.platform === 'android' ? '.android.scss' : '.ios.scss', + '.native.scss', + '.scss', + ]; + + if ( filename.endsWith( '.scss' ) || filename.endsWith( '.sass' ) ) { + const result = sass.renderSync( { + data: src, + includePaths: [ + path.dirname( filename ), + ...autoImportIncludePaths, + ], + importer( url /*, prev, done */ ) { + // url is the path in import as is, which LibSass encountered. + // prev is the previously resolved path. + // done is an optional callback, either consume it or return value synchronously. + // this.options contains this options hash, this.callback contains the node-style callback + + const urlPath = path.parse( url ); + const importerOptions = this.options; + const incPaths = importerOptions.includePaths + .slice( 0 ) + .split( ':' ); + if ( urlPath.dir.length > 0 ) { + incPaths.unshift( + path.resolve( path.dirname( filename ), urlPath.dir ) + ); // add the file's dir to the search array + } + const f = findVariant( urlPath.name, exts, incPaths ); + + if ( f ) { + return { file: f }; + } + + return new Error( + url + ' could not be resolved in ' + incPaths + ); + }, + } ); + const css = result.css.toString(); + const cssObject = css2rn( css, { parseMediaQueries: true } ); + + return upstreamTransformer.transform( { + src: 'module.exports = ' + JSON.stringify( cssObject ), + filename, + options, + } ); + } + return upstreamTransformer.transform( { src, filename, options } ); +} + +module.exports.transform = function ( { src, filename, options } ) { + if ( filename.endsWith( '.scss' ) || filename.endsWith( '.sass' ) ) { + // "auto-import" the stylesheets the GB webpack config imports + src = imports + src; + return transform( { src, filename, options } ); + } + return upstreamTransformer.transform( { src, filename, options } ); +}; diff --git a/packages/react-native-editor/src/_native.android.scss b/packages/react-native-editor/src/_native.android.scss new file mode 100644 index 00000000000000..3b90fe27810807 --- /dev/null +++ b/packages/react-native-editor/src/_native.android.scss @@ -0,0 +1,5 @@ +/** @format */ + +// Fonts +$default-monospace-font: monospace; +$default-regular-font: serif; diff --git a/packages/react-native-editor/src/_native.ios.scss b/packages/react-native-editor/src/_native.ios.scss new file mode 100644 index 00000000000000..03c60c155da086 --- /dev/null +++ b/packages/react-native-editor/src/_native.ios.scss @@ -0,0 +1,5 @@ +/** @format */ + +// Fonts +$default-monospace-font: menlo; +$default-regular-font: "Noto Serif"; diff --git a/packages/react-native-editor/src/api-fetch-setup.js b/packages/react-native-editor/src/api-fetch-setup.js new file mode 100644 index 00000000000000..6a396732f49751 --- /dev/null +++ b/packages/react-native-editor/src/api-fetch-setup.js @@ -0,0 +1,53 @@ +/** + * External dependencies + */ +/** + * WordPress dependencies + */ +import { fetchRequest } from '@wordpress/react-native-bridge'; + +/** + * WordPress dependencies + */ +import apiFetch from '@wordpress/api-fetch'; + +const setTimeoutPromise = ( delay ) => + new Promise( ( resolve ) => setTimeout( resolve, delay ) ); + +const fetchHandler = ( { path }, retries = 20, retryCount = 1 ) => { + if ( ! isPathSupported( path ) ) { + return Promise.reject( `Unsupported path: ${ path }` ); + } + + const responsePromise = fetchRequest( path ); + + const parseResponse = ( response ) => { + if ( typeof response === 'string' ) { + response = JSON.parse( response ); + } + return response; + }; + + return responsePromise.then( parseResponse ).catch( ( error ) => { + // eslint-disable-next-line no-console + console.warn( 'Network Error: ', JSON.stringify( error, null, 2 ) ); + if ( error.code >= 400 && error.code < 600 ) { + return error; + } else if ( retries === 0 ) { + return Promise.reject( error ); + } + return setTimeoutPromise( 1000 * retryCount ).then( () => + fetchHandler( { path }, retries - 1, retryCount + 1 ) + ); + } ); +}; + +export const isPathSupported = ( path ) => + [ + /wp\/v2\/(media|categories)\/?\d*?.*/i, + /wpcom\/v2\/gutenberg\/.*/i, + ].some( ( pattern ) => pattern.test( path ) ); + +export default () => { + apiFetch.setFetchHandler( ( options ) => fetchHandler( options ) ); +}; diff --git a/packages/react-native-editor/src/globals.js b/packages/react-native-editor/src/globals.js new file mode 100644 index 00000000000000..4cfebd0150f4f2 --- /dev/null +++ b/packages/react-native-editor/src/globals.js @@ -0,0 +1,59 @@ +/** + * External dependencies + */ +// This library works as a polyfill for the global crypto.getRandomValues which is needed by `uuid` version 7.0.0 +import 'react-native-get-random-values'; +import jsdom from 'jsdom-jscore-rn'; +import jsdomLevel1Core from 'jsdom-jscore-rn/lib/jsdom/level1/core'; + +/** + * WordPress dependencies + */ +import { nativeLoggingHook } from '@wordpress/react-native-bridge'; +import { createElement } from '@wordpress/element'; + +/** + * Internal dependencies + */ + +/** + * Import for side-effects: Patches for jsdom-jscore, mostly to implement + * functions that are called from Gutenberg code paths, where a more full DOM + * implementation is expected (in the browser environment). + * + * More details are available within the comments in the file. + */ +import './jsdom-patches'; + +global.wp = { + element: { + createElement, // load the element creation function, needed by Gutenberg-web + }, +}; + +const doc = jsdom.html( '', null, null ); + +// inject a simple version of the missing createHTMLDocument method that `hpq` depends on +doc.implementation.createHTMLDocument = function ( html ) { + return jsdom.html( html, null, null ); +}; + +// `hpq` depends on `document` be available globally +global.document = doc; + +if ( ! global.window.Node ) { + global.window.Node = jsdomLevel1Core.dom.level1.core.Node; +} + +if ( ! global.window.matchMedia ) { + global.window.matchMedia = () => ( { + matches: false, + addListener: () => {}, + removeListener: () => {}, + } ); +} + +global.window.navigator.userAgent = []; + +// Leverages existing console polyfill from react-native +global.nativeLoggingHook = nativeLoggingHook; diff --git a/packages/react-native-editor/src/index.js b/packages/react-native-editor/src/index.js new file mode 100644 index 00000000000000..bf2369b4a9d41f --- /dev/null +++ b/packages/react-native-editor/src/index.js @@ -0,0 +1,110 @@ +/** + * External dependencies + */ +import { I18nManager } from 'react-native'; + +/** + * Internal dependencies + */ +import './globals'; +import { getTranslation } from '../i18n-cache'; +import initialHtml from './initial-html'; +import setupApiFetch from './api-fetch-setup'; + +const reactNativeSetup = () => { + // Disable warnings as they disrupt the user experience in dev mode + // eslint-disable-next-line no-console + console.disableYellowBox = true; + + I18nManager.forceRTL( false ); // Change to `true` to debug RTL layout easily. +}; + +const gutenbergSetup = () => { + const wpData = require( '@wordpress/data' ); + + // wp-data + const userId = 1; + const storageKey = 'WP_DATA_USER_' + userId; + wpData.use( wpData.plugins.persistence, { storageKey } ); + + setupApiFetch(); + + const isHermes = () => global.HermesInternal !== null; + // eslint-disable-next-line no-console + console.log( 'Hermes is: ' + isHermes() ); + + setupInitHooks(); + + const initializeEditor = require( '@wordpress/edit-post' ).initializeEditor; + initializeEditor( 'gutenberg', 'post', 1 ); +}; + +const setupInitHooks = () => { + const wpHooks = require( '@wordpress/hooks' ); + + wpHooks.addAction( + 'native.pre-render', + 'core/react-native-editor', + ( props ) => { + setupLocale( props.locale, props.translations ); + } + ); + + // Map native props to Editor props + // TODO: normalize props in the bridge (So we don't have to map initialData to initialHtml) + wpHooks.addFilter( + 'native.block_editor_props', + 'core/react-native-editor', + ( props ) => { + const { capabilities = {} } = props; + let { initialData, initialTitle, postType } = props; + + if ( initialData === undefined && __DEV__ ) { + initialData = initialHtml; + } + if ( initialTitle === undefined ) { + initialTitle = 'Welcome to Gutenberg!'; + } + if ( postType === undefined ) { + postType = 'post'; + } + + return { + initialHtml: initialData, + initialHtmlModeEnabled: props.initialHtmlModeEnabled, + initialTitle, + postType, + capabilities, + colors: props.colors, + gradients: props.gradients, + }; + } + ); +}; + +const setupLocale = ( locale, extraTranslations ) => { + const setLocaleData = require( '@wordpress/i18n' ).setLocaleData; + + I18nManager.forceRTL( false ); // Change to `true` to debug RTL layout easily. + + let gutenbergTranslations = getTranslation( locale ); + if ( locale && ! gutenbergTranslations ) { + // Try stripping out the regional + locale = locale.replace( /[-_][A-Za-z]+$/, '' ); + gutenbergTranslations = getTranslation( locale ); + } + const translations = Object.assign( + {}, + gutenbergTranslations, + extraTranslations + ); + // eslint-disable-next-line no-console + console.log( 'locale', locale, translations ); + // Only change the locale if it's supported by gutenberg + if ( gutenbergTranslations || extraTranslations ) { + setLocaleData( translations ); + } +}; + +reactNativeSetup(); +gutenbergSetup(); diff --git a/packages/react-native-editor/src/initial-html.js b/packages/react-native-editor/src/initial-html.js new file mode 100644 index 00000000000000..88ce259eb670dd --- /dev/null +++ b/packages/react-native-editor/src/initial-html.js @@ -0,0 +1,245 @@ +export default ` + +

Text Blocks

+ + + +

What is Gutenberg?

+ + + +

Bold Italic Striked Superscript(1) Subscript(2) Link

+ + + +

List

+ + + +
  • First Item
  • Second Item
  • Third Item
+ + + +

Quote

+ + + +

"This will make running your own blog a viable alternative again."

Adrian Zumbrunnen
+ + + +

One of the hardest things to do in technology is disrupt yourself.

Matt Mullenweg
+ + + +

Style Paragraph

+ + + +

+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer tempor tincidunt sapien, quis dictum orci sollicitudin quis. Proin sed elit id est pulvinar feugiat vitae eget dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

+ + + +

Pre formatted

+ + + +
Some preformatted text...
And more!
+ + + +

Code

+ + + +
if name == "World":
+    return "Hello World"
+else:
+    return "Hello Pony"
+ + + +

Verse

+ + + +
Come
Home.
+ + + +

Media

+ + + +

Images

+ + + +
+ + + +
Mountain
+ + + +

Video

+ + + +
Videos too!
+ + + +

Gallery

+ + + + + + + +

Separators

+ + + + + + + + + + + + + + + +

Layout

+ + + +

Group

+ + + +
+

One.

+ + + +

Two

+ + + +

Three.

+
+ + + +

Columns

+ + + +
+
+

Built with modern technology.

+ + + +

Gutenberg was developed on GitHub using the WordPress REST API, JavaScript, and React.

+ + + +

Learn more

+
+ + + +
+

Designed for compatibility.

+ + + +

We recommend migrating features to blocks, but support for existing WordPress functionality remains. There will be transition paths for shortcodes, meta-boxes, and Custom Post Types.

+ + + +

Learn more

+
+
+ + + +

Media Text

+ + + +
+

+
+ + + +

Cover

+ + + +
+

Cool cover

+
+ + + +

Dynamic Blocks

+ + + + + +

Buttons

+ + + + + + + +

Legacy

+ + + +[youtube https://www.youtube.com/watch?v=ssfHW5lwFZg] + + + +

Jetpack

+ + + +
+ + + + + + + + +
Random Street
+
+ + + +

Unsupported

+ + + +`; diff --git a/packages/react-native-editor/src/jsdom-patches.js b/packages/react-native-editor/src/jsdom-patches.js new file mode 100644 index 00000000000000..3388a74488a44c --- /dev/null +++ b/packages/react-native-editor/src/jsdom-patches.js @@ -0,0 +1,263 @@ +/** + * This file is used in src/globals.js to patch jsdom-jscore. + * + * Node.prototype.contains is implemented as a simple recursive function. + * + * Node.prototype.insertBefore is re-implemented (code copied) with the + * WrongDocumentError exception disabled. + * + * Element.prototype.matches is aliased to Element.prototype.matchesSelector. + * + * Getters are defined on the Node.prototype for the following properties: + * parentElement, previousElementSibling, nextElementSibling. + */ + +/** + * External dependencies + */ +import jsdom from 'jsdom-jscore-rn'; +import jsdomLevel1Core from 'jsdom-jscore-rn/lib/jsdom/level1/core'; + +// must be called to initialize jsdom before patching prototypes +jsdom.html( '', null, null ); + +const { core } = jsdomLevel1Core.dom.level1; +const { Node, Element, CharacterData } = core; + +// Exception codes +const { + NO_MODIFICATION_ALLOWED_ERR, + HIERARCHY_REQUEST_ERR, + NOT_FOUND_ERR, +} = core; + +// Node types +const { ATTRIBUTE_NODE, DOCUMENT_FRAGMENT_NODE } = Node; + +/** + * Simple recursive implementation of Node.contains method + * + * @param {number} otherNode Another node (may be the same node). + * @return {boolean} true if otherNode is a descendant of this node, or is this + * node, false otherwise. + * + * This function is necessary in the mobile environment, because there are code + * paths that make use of functions in the Gutenberg (web) project, which has + * expectation that this is implemented (as it is in the browser environment). + */ +Node.prototype.contains = function ( otherNode ) { + return ( + this === otherNode || + Array.prototype.some.call( this._childNodes, ( childNode ) => { + return childNode.contains( otherNode ); + } ) + ); +}; + +/** + * Copy of insertBefore function from jsdom-jscore, WRONG_DOCUMENT_ERR exception + * disabled. + * + * @param {Object} newChild The node to be insterted. + * @param {Object} refChild The node before which newChild is inserted. + * @return {Object} the newly inserted child node + * + * This function is modified here to remove the WRONG_DOCUMENT_ERR exception + * that is no longer part of the DOM spec for this function. + * see: https://github.com/jsdom/jsdom/issues/717 for more information, * and: + * https://dom.spec.whatwg.org/#dom-node-insertbefore for the latest spec. + */ +Node.prototype.insertBefore = function ( + /* Node */ newChild, + /* Node*/ refChild +) { + if ( this._readonly === true ) { + throw new core.DOMException( + NO_MODIFICATION_ALLOWED_ERR, + 'Attempting to modify a read-only node' + ); + } + + // Adopt unowned children, for weird nodes like DocumentType + if ( ! newChild._ownerDocument ) { + newChild._ownerDocument = this._ownerDocument; + } + + /* + * This is commented out to prevent WrongDocumentError + * see: https://github.com/jsdom/jsdom/issues/717 + * + // TODO - if (!newChild) then? + if (newChild._ownerDocument !== this._ownerDocument) { + throw new core.DOMException(WRONG_DOCUMENT_ERR); + } + */ + + if ( newChild.nodeType && newChild.nodeType === ATTRIBUTE_NODE ) { + throw new core.DOMException( HIERARCHY_REQUEST_ERR ); + } + + // search for parents matching the newChild + let current = this; + do { + if ( current === newChild ) { + throw new core.DOMException( HIERARCHY_REQUEST_ERR ); + } + } while ( ( current = current._parentNode ) ); + + // fragments are merged into the element + if ( newChild.nodeType === DOCUMENT_FRAGMENT_NODE ) { + let tmpNode, + i = newChild._childNodes.length; + while ( i-- > 0 ) { + tmpNode = newChild.removeChild( newChild.firstChild ); + this.insertBefore( tmpNode, refChild ); + } + } else if ( newChild === refChild ) { + return newChild; + } else { + // if the newChild is already in the tree elsewhere, remove it first + if ( newChild._parentNode ) { + newChild._parentNode.removeChild( newChild ); + } + + if ( refChild === null ) { + // eslint-disable-next-line no-var + var refChildIndex = this._childNodes.length; + } else { + // eslint-disable-next-line no-redeclare, no-var + var refChildIndex = this._indexOf( refChild ); + if ( refChildIndex === -1 ) { + throw new core.DOMException( NOT_FOUND_ERR ); + } + } + + Array.prototype.splice.call( + this._childNodes, + refChildIndex, + 0, + newChild + ); + + newChild._parentNode = this; + if ( this._attached && newChild._attach ) { + newChild._attach(); + } + + this._modified(); + } + + return newChild; +}; // raises(DOMException); + +/* + * This is merely an alias (polyfill not needed). + * see: https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill + * + * This function is necessary in the mobile environment, because there are code + * paths that make use of functions in the Gutenberg (web) project, which has + * expectation that this is implemented (as it is in the browser environment). + */ +Element.prototype.matches = Element.prototype.matchesSelector; + +/* + * Implementation of Element.prototype.closest that it's missing from the jsdom-jscore fork we're using. + * See https://github.com/wordpress-mobile/gutenberg-mobile/issues/1625 + */ +Element.prototype.closest = function ( selector ) { + let el = this; + while ( el ) { + if ( el.matches( selector ) ) { + return el; + } + el = el.parentElement; + } + return null; +}; + +/** + * Helper function to check if a node implements the NonDocumentTypeChildNode + * interface + * + * @param {Object} node Node to check + * @return {boolean} true if node is a NonDocumentTypeChildNode, false otherwise + * + * This function is needed to implement the previousElementSibling and + * nextElementSibling properties. + * See: https://dom.spec.whatwg.org/#interface-nondocumenttypechildnode + */ +function isNonDocumentTypeChildNode( node ) { + return node instanceof Element || node instanceof CharacterData; +} + +// $FlowFixMe +Object.defineProperties( Node.prototype, { + /* + * This defines parentElement property on the Node prototype using a getter. + * See: https://dom.spec.whatwg.org/#parent-element + */ + parentElement: { + get() { + const parent = this.parentNode; + + if ( parent && parent.nodeType === Node.ELEMENT_NODE ) { + return parent; + } + + return null; + }, + }, + /* + * This defines previousElementSibling property on the Node prototype using a + * getter. + * See: https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-previouselementsibling + */ + previousElementSibling: { + get() { + // Property is undefined if node is not a NonDocumentTypeChildNode + if ( ! isNonDocumentTypeChildNode( this ) ) { + return; + } + + let sibling = this.previousSibling; + + while ( sibling && sibling.nodeType !== Node.ELEMENT_NODE ) { + sibling = sibling.previousSibling; + } + + return sibling; + }, + }, + /* + * This defines nextElementSibling property on the Node prototype using a + * getter. + * See: https://dom.spec.whatwg.org/#dom-nondocumenttypechildnode-nextelementsibling + */ + nextElementSibling: { + get() { + // Property is undefined if node is not a NonDocumentTypeChildNode + if ( ! isNonDocumentTypeChildNode( this ) ) { + return; + } + + let sibling = this.nextSibling; + + while ( sibling && sibling.nodeType !== Node.ELEMENT_NODE ) { + sibling = sibling.nextSibling; + } + + return sibling; + }, + }, +} ); + +class DOMParser { + // This is required for the stripHTML function, but it doesn't necessarily + // conform to the DOM standard. + // See https://github.com/wordpress-mobile/gutenberg-mobile/pull/1771 + parseFromString( string ) { + return jsdom.html( string ); + } +} + +global.DOMParser = DOMParser; diff --git a/packages/react-native-editor/src/parser/block-parser-code.test.js b/packages/react-native-editor/src/parser/block-parser-code.test.js new file mode 100644 index 00000000000000..276e73b6d7d5b7 --- /dev/null +++ b/packages/react-native-editor/src/parser/block-parser-code.test.js @@ -0,0 +1,43 @@ +/** + * Internal dependencies + */ +import '../globals'; + +/** + * WordPress dependencies + */ +import { registerCoreBlocks } from '@wordpress/block-library'; +import { parse } from '@wordpress/blocks'; + +registerCoreBlocks(); + +describe( 'Parser', () => { + const codeContent = ` + if name == "World": + return "Hello World" + else: + return "Hello Pony"`; + + const originalCodeBlockHtml = `
${ codeContent }
`; + + const gbCodeBlockHtml = ` + + ${ originalCodeBlockHtml } + `; + + it( 'parses the code block ok', () => { + const codeBlockInstance = parse( gbCodeBlockHtml )[ 0 ]; + expect( codeBlockInstance ).toBeTruthy(); + } ); + + it( 'parses the code block content ok', () => { + const codeBlockInstance = parse( gbCodeBlockHtml )[ 0 ]; + + expect( codeBlockInstance.isValid ).toEqual( true ); + expect( codeBlockInstance.name ).toEqual( 'core/code' ); + expect( codeBlockInstance.innerBlocks ).toHaveLength( 0 ); + expect( codeBlockInstance.originalContent ).toEqual( + originalCodeBlockHtml + ); + } ); +} ); diff --git a/packages/react-native-editor/src/parser/block-parser-more.test.js b/packages/react-native-editor/src/parser/block-parser-more.test.js new file mode 100644 index 00000000000000..c2f2360fc64a2c --- /dev/null +++ b/packages/react-native-editor/src/parser/block-parser-more.test.js @@ -0,0 +1,37 @@ +/** + * Internal dependencies + */ +import '../globals'; + +/** + * WordPress dependencies + */ +import { registerCoreBlocks } from '@wordpress/block-library'; +import { parse } from '@wordpress/blocks'; + +registerCoreBlocks(); + +describe( 'Parser', () => { + const originalMoreBlockHtml = ''; + + const gbMoreBlockHtml = ` + + ${ originalMoreBlockHtml } + `; + + it( 'parses the more block ok', () => { + const moreBlockInstance = parse( gbMoreBlockHtml )[ 0 ]; + expect( moreBlockInstance ).toBeTruthy(); + } ); + + it( 'parses the more block attributes ok', () => { + const moreBlockInstance = parse( gbMoreBlockHtml )[ 0 ]; + + expect( moreBlockInstance.isValid ).toEqual( true ); + expect( moreBlockInstance.name ).toEqual( 'core/more' ); + expect( moreBlockInstance.innerBlocks ).toHaveLength( 0 ); + expect( moreBlockInstance.originalContent ).toEqual( + originalMoreBlockHtml + ); + } ); +} ); diff --git a/packages/react-native-editor/src/parser/block-parser-paragraph.test.js b/packages/react-native-editor/src/parser/block-parser-paragraph.test.js new file mode 100644 index 00000000000000..d9f451005901a4 --- /dev/null +++ b/packages/react-native-editor/src/parser/block-parser-paragraph.test.js @@ -0,0 +1,41 @@ +/** + * Internal dependencies + */ +import '../globals'; + +/** + * WordPress dependencies + */ +import { registerCoreBlocks } from '@wordpress/block-library'; +import { parse } from '@wordpress/blocks'; + +registerCoreBlocks(); + +describe( 'Parser', () => { + const innerContent = ` + if name == "World": + return "Hello World" + else: + return "Hello Pony"`; + + const originalBlockHtml = `

${ innerContent }

`; + + const gbBlockHtml = ` + + ${ originalBlockHtml } + `; + + it( 'parses the paragraph block ok', () => { + const blockInstance = parse( gbBlockHtml )[ 0 ]; + expect( blockInstance ).toBeTruthy(); + } ); + + it( 'parses the paragraph block content ok', () => { + const blockInstance = parse( gbBlockHtml )[ 0 ]; + + expect( blockInstance.isValid ).toEqual( true ); + expect( blockInstance.name ).toEqual( 'core/paragraph' ); + expect( blockInstance.innerBlocks ).toHaveLength( 0 ); + expect( blockInstance.originalContent ).toEqual( originalBlockHtml ); + } ); +} ); diff --git a/packages/react-native-editor/src/test/api-fetch-setup.test.js b/packages/react-native-editor/src/test/api-fetch-setup.test.js new file mode 100644 index 00000000000000..c7d5b230fbf8fd --- /dev/null +++ b/packages/react-native-editor/src/test/api-fetch-setup.test.js @@ -0,0 +1,31 @@ +/** + * Internal dependencies + */ +import { isPathSupported } from '../api-fetch-setup'; + +const supportedPaths = [ + 'wp/v2/media/54?context=edit&_locale=user', + 'wp/v2/media/5?context=edit', + 'wp/v2/media/54/', + 'wp/v2/media/', + 'wp/v2/media?context=edit&_locale=user', + 'wp/v2/categories/', +]; + +const unsupportedPaths = [ + 'wp/v1/media/', // made up example +]; + +describe( 'isPathSupported', () => { + supportedPaths.forEach( ( path ) => { + it( `supports ${ path }`, () => { + expect( isPathSupported( path ) ).toBe( true ); + } ); + } ); + + unsupportedPaths.forEach( ( path ) => { + it( `does not support ${ path }`, () => { + expect( isPathSupported( path ) ).toBe( false ); + } ); + } ); +} ); diff --git a/packages/rich-text/src/component/index.native.js b/packages/rich-text/src/component/index.native.js index 91fabd4cd2d4be..b3dfc7e1c482a6 100644 --- a/packages/rich-text/src/component/index.native.js +++ b/packages/rich-text/src/component/index.native.js @@ -3,9 +3,12 @@ /** * External dependencies */ -import RCTAztecView from 'react-native-aztec'; +/** + * WordPress dependencies + */ +import RCTAztecView from '@wordpress/react-native-aztec'; import { View, Platform } from 'react-native'; -import { addMention } from 'react-native-gutenberg-bridge'; +import { addMention } from '@wordpress/react-native-bridge'; import { get, pickBy } from 'lodash'; import memize from 'memize'; diff --git a/packages/scripts/scripts/check-licenses.js b/packages/scripts/scripts/check-licenses.js index d03e595b9dfc50..a7f6e1976a7888 100644 --- a/packages/scripts/scripts/check-licenses.js +++ b/packages/scripts/scripts/check-licenses.js @@ -80,6 +80,7 @@ const otherOssLicenses = [ 'Apache License, Version 2.0', 'Apache version 2.0', 'CC-BY-3.0', + 'CC-BY-SA-2.0', 'LGPL', ]; diff --git a/test/native/jest.config.js b/test/native/jest.config.js index f4c49f33a68fed..18ccbb421ea7fe 100644 --- a/test/native/jest.config.js +++ b/test/native/jest.config.js @@ -30,7 +30,10 @@ module.exports = { '/' + configPath + '/enzyme.config.js', ], testEnvironment: 'jsdom', - testMatch: [ '**/test/*.native.[jt]s?(x)' ], + testMatch: [ + '**/test/*.native.[jt]s?(x)', + '/packages/react-native-*/**/?(*.)+(spec|test).[jt]s?(x)', + ], testPathIgnorePatterns: [ '/node_modules/', '/wordpress/', @@ -50,6 +53,9 @@ module.exports = { '|' ) })$` ]: '/packages/$1/src', }, + modulePathIgnorePatterns: [ + '/packages/react-native-editor/node_modules', + ], haste: { defaultPlatform: rnPlatform, platforms: [ 'android', 'ios', 'native' ], diff --git a/test/native/jest_ui.config.js b/test/native/jest_ui.config.js new file mode 100644 index 00000000000000..15855a1a261e0b --- /dev/null +++ b/test/native/jest_ui.config.js @@ -0,0 +1,24 @@ +const defaultPlatform = 'android'; +const rnPlatform = process.env.TEST_RN_PLATFORM || defaultPlatform; +if ( process.env.TEST_RN_PLATFORM ) { + // eslint-disable-next-line no-console + console.log( 'Setting RN platform to: ' + rnPlatform ); +} else { + // eslint-disable-next-line no-console + console.log( 'Setting RN platform to: default (' + defaultPlatform + ')' ); +} + +module.exports = { + verbose: true, + rootDir: '../../', + haste: { + defaultPlatform: rnPlatform, + platforms: [ 'android', 'ios', 'native' ], + }, + transform: { + '^.+\\.(js|ts|tsx)$': 'babel-jest', + }, + timers: 'real', + setupFiles: [], + testMatch: [ '**/__device-tests__/**/*.test.[jt]s?(x)' ], +}; diff --git a/test/native/setup.js b/test/native/setup.js index cb2070555d4bcd..fe5bfe7a05f33c 100644 --- a/test/native/setup.js +++ b/test/native/setup.js @@ -3,7 +3,15 @@ */ import { NativeModules } from 'react-native'; -jest.mock( 'react-native-gutenberg-bridge', () => { +jest.mock( '@wordpress/element', () => { + return { + __esModule: true, + ...jest.requireActual( '@wordpress/element' ), + render: jest.fn(), + }; +} ); + +jest.mock( '@wordpress/react-native-bridge', () => { return { addEventListener: jest.fn(), removeEventListener: jest.fn(), @@ -70,8 +78,6 @@ jest.mock( 'react-native-safe-area', () => { }; } ); -jest.mock( 'react-native-recyclerview-list' ); - jest.mock( '@react-native-community/slider', () => () => 'Slider', { virtual: true, } ); diff --git a/test/unit/jest.config.js b/test/unit/jest.config.js index 0a2624d639015d..c5023a5944366a 100644 --- a/test/unit/jest.config.js +++ b/test/unit/jest.config.js @@ -30,6 +30,7 @@ module.exports = { '/.*/build/', '/.*/build-module/', '/.+.native.js$', + '/packages/react-native-*', ], transform: { '^.+\\.[jt]sx?$': '/test/unit/scripts/babel-transformer.js', diff --git a/tsconfig.base.json b/tsconfig.base.json index afabdbaf82e30d..08e7a57fab1e39 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -5,6 +5,7 @@ "allowSyntheticDefaultImports": true, "jsx": "preserve", "target": "esnext", + "types": ["react", "node", "requestidlecallback"], "module": "esnext", "lib": [ "dom", "esnext" ], "declaration": true, @@ -40,6 +41,7 @@ "**/build-*/**", "**/*.android.js", "**/*.ios.js", - "**/*.native.js" + "**/*.native.js", + "./packages/**/react-native-*/**" ] } diff --git a/webpack.config.js b/webpack.config.js index 84c93c9f4cf661..ec7a7ed42b0bd2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -35,7 +35,8 @@ const gutenbergPackages = Object.keys( dependencies ) .filter( ( packageName ) => ! BUNDLED_PACKAGES.includes( packageName ) && - packageName.startsWith( WORDPRESS_NAMESPACE ) + packageName.startsWith( WORDPRESS_NAMESPACE ) && + ! packageName.startsWith( WORDPRESS_NAMESPACE + 'react-native' ) ) .map( ( packageName ) => packageName.replace( WORDPRESS_NAMESPACE, '' ) );