diff --git a/chrome-extension/background/background.ts b/chrome-extension/background/background.ts index 888440c..8aa6fb5 100644 --- a/chrome-extension/background/background.ts +++ b/chrome-extension/background/background.ts @@ -87,8 +87,8 @@ export class App { await AuthContext.init(new LocalStorageJsonStorage()); app.api.authContext.init('accountId'); console.debug('[APP] Auth Context loaded'); - console.log(`[APP] network status ${window.navigator.onLine ? 'online' : 'offline'}`); - if (!this.state.currentUser && window.navigator.onLine) { + console.log(`[APP] network status ${globalThis.navigator.onLine ? 'online' : 'offline'}`); + if (!this.state.currentUser && globalThis.navigator.onLine) { await app.run(GetCurrentUserBackgroundJob); } app.api.onError.subscribe(e => { diff --git a/chrome-extension/background/jobs/run-sync.tab.job.ts b/chrome-extension/background/jobs/run-sync.tab.job.ts index 2ebdad4..20a72d8 100644 --- a/chrome-extension/background/jobs/run-sync.tab.job.ts +++ b/chrome-extension/background/jobs/run-sync.tab.job.ts @@ -12,6 +12,7 @@ import {App, ExtensionState} from '../background'; import {getExtensionVersion} from '../utils/minimal-version'; import {notify} from '../utils/notifications'; import {IJob} from './job.interface'; +import {CustomEventApiService} from "../../../src/core/admob-api/custom-event.api"; export class RunSyncTabJob implements IJob { @@ -31,7 +32,8 @@ export class RunSyncTabJob implements IJob { percent: 0, lastEvent: null, hasErrors: false, - isTerminated: false + isTerminated: false, + step: null }; @@ -87,6 +89,7 @@ export class RunSyncTabJob implements IJob { const adMobAccount = this.adMobAccount = currentUser.accounts.find( acc => acc.email.toLowerCase() === extractedAdmobAccount.email.toLowerCase()); + const customEventApi = new CustomEventApiService(fetch.bind(globalThis), console); logger.info(`Sync with extension. Version ${getExtensionVersion()}`); @@ -125,6 +128,7 @@ export class RunSyncTabJob implements IJob { adMobAccount, currentUser, logger, + customEventApi, id, SyncRunner.User ); diff --git a/chrome-extension/background/utils/local-storage.proxy.ts b/chrome-extension/background/utils/local-storage.proxy.ts index 7a3ab37..ee38333 100644 --- a/chrome-extension/background/utils/local-storage.proxy.ts +++ b/chrome-extension/background/utils/local-storage.proxy.ts @@ -14,6 +14,15 @@ function loadStoredValues (key, value, exclude: string[]) { } } +function storeValues (key, values) { + try { + localStorage.setItem(key, JSON.stringify(values)); + } catch (e) { + console.warn(e); + } + +} + export function localStorageProxy (storageKey, value, exclude: string[]): T { console.debug('[localStorageProxy] start ', deepClone(value)); @@ -22,7 +31,7 @@ export function localStorageProxy (storageKey, value, exclude: const original = deepClone(value); let timeoutID; - const save = () => localStorage.setItem(storageKey, JSON.stringify(original)); + const save = () => storeValues(storageKey, original); const getter = key => () => original[key]; const setter = key => value => { original[key] = value; diff --git a/chrome-extension/background/utils/notifications.ts b/chrome-extension/background/utils/notifications.ts index 461ec2c..0679fd7 100644 --- a/chrome-extension/background/utils/notifications.ts +++ b/chrome-extension/background/utils/notifications.ts @@ -3,14 +3,13 @@ import uuid from 'uuid'; export function notify (title, message, id?) { id = id || uuid.v4(); - const opt = { + + chrome.notifications.create(id, { type: 'basic', title: title, message: message, iconUrl: 'img/icon/icon-64.png' - }; - - chrome.notifications.create(id, opt); + }); } export function notifyError (e: Error) { diff --git a/chrome-extension/common/initSentry.ts b/chrome-extension/common/initSentry.ts index acaf3f5..94ec34f 100644 --- a/chrome-extension/common/initSentry.ts +++ b/chrome-extension/common/initSentry.ts @@ -40,7 +40,7 @@ export function InitSentry (whereTag, listenStateFromBackground: boolean = false beforeSend (event, hint?) { if (hint && hint.originalException - && !window.navigator.onLine + && !globalThis.navigator.onLine && typeof hint.originalException === 'object' && hint.originalException.message === 'Network error: Failed to fetch') { return null; diff --git a/chrome-extension/content-scripts/admob-content-script.ts b/chrome-extension/content-scripts/admob-content-script.ts index 4c96961..810c9db 100644 --- a/chrome-extension/content-scripts/admob-content-script.ts +++ b/chrome-extension/content-scripts/admob-content-script.ts @@ -56,7 +56,8 @@ $(document).ready(function () { } modal.show( title, - `Syncing ${ + ` + Syncing ${ Number(syncProgress.percent).toFixed(0) }% ${ Math.min(syncProgress.completedApps + syncProgress.failedApps + 1, syncProgress.totalApps) diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json index 60b8b20..a043b07 100644 --- a/chrome-extension/manifest.json +++ b/chrome-extension/manifest.json @@ -1,11 +1,11 @@ { - "manifest_version": 2, + "manifest_version": 3, "name": "Appodeal", "short_name": "Appodeal Admob Sync", "description": "This extension will create and sync Appodeal adunits in your Admob account.", "minimum_chrome_version": "62", - "version": "20.02.00", - "browser_action": { + "version": "20.03.00", + "action": { "default_icon": { "16": "img/icon/icon-16.png" }, @@ -58,22 +58,16 @@ } ], "background": { - "scripts": [ - "background.js" - ], - "persistent": false + "service_worker": "background.js" }, - "web_accessible_resources": [ - "img/*", - "js/vendor/*", - "js/helpers/*" - ], "permissions": [ "tabs", "cookies", "storage", "notifications", - "identity", + "identity" + ], + "host_permissions": [ "*://*.appodeal.com/*", "*://*.admob.com/*" ], diff --git a/chrome-extension/popup/utils/popupClickHandlers.ts b/chrome-extension/popup/utils/popupClickHandlers.ts index 636b5c7..e965924 100644 --- a/chrome-extension/popup/utils/popupClickHandlers.ts +++ b/chrome-extension/popup/utils/popupClickHandlers.ts @@ -1,8 +1,10 @@ import {Actions, TabJobs} from '../../common/actions'; -const ADMOB_HOME = 'https://apps.admob.com/logout?continue=https://apps.admob.com/'; +const ADMOB_HOME_WITH_RELOGIN = 'https://apps.admob.com/logout?continue=https://apps.admob.com/'; const ADMOB_ACCOUNT_ADD_OR_RECONNECT = 'https://app.appodeal.com/apps/linked_networks#AddAdmobAccount'; +const ADMOB_HOME = 'https://apps.admob.com/v2/home'; +const ADMOB_DASHBOARD_ROOT = 'https://apps.admob.com/'; async function navigateCurrentTab (url: string): Promise { return new Promise(resolve => { @@ -38,7 +40,13 @@ export async function onClickStartAdmobAccountSetup () { export async function startSyncAdmobAccount () { - const tab = await navigateCurrentTab(ADMOB_HOME); + const tabs = await chrome.tabs.query({active: true, currentWindow: true}); + const tab = tabs[0]; + if (tab.url && tab.url.startsWith(ADMOB_DASHBOARD_ROOT)) { + await chrome.tabs.update(tab.id, {url: ADMOB_HOME}); + } else { + await chrome.tabs.update(tab.id, {url: ADMOB_HOME_WITH_RELOGIN}); + } await setCurrentJob(TabJobs.syncAdunits, tab.id); } diff --git a/package-lock.json b/package-lock.json index 938d421..d458010 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "admob-sync-app", - "version": "0.1.32", + "version": "0.2.32", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -245,32 +245,6 @@ "requires": { "ajv": "^6.12.0", "ajv-keywords": "^3.4.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - } } }, "@electron/get": { @@ -367,11 +341,6 @@ "url-parse-lax": "^3.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, "http-cache-semantics": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", @@ -451,12 +420,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1132,12 +1095,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1148,12 +1105,6 @@ "universalify": "^2.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1397,11 +1348,12 @@ } }, "@types/chrome": { - "version": "0.0.88", - "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.88.tgz", - "integrity": "sha512-JBsIrBZ2adJhlXvJ+1j0xLbcfOfwee/WAg7Lp2NE+Wf3m0vXMJFWv/PPjqNk5ZUXDeY/qDxPHe+PUjxnl8HWFg==", + "version": "0.0.200", + "resolved": "https://registry.npmjs.org/@types/chrome/-/chrome-0.0.200.tgz", + "integrity": "sha512-oNT2/KHgZECTzj4oavLc20r3D2yFufLwGNaLFAN8YxYyNVJGenX3l3oGBynhoT/Azm3eAfyDynrdca6jB7CNzw==", "requires": { - "@types/filesystem": "*" + "@types/filesystem": "*", + "@types/har-format": "*" } }, "@types/debug": { @@ -1458,6 +1410,11 @@ "integrity": "sha512-lELg5m6eBOmATWyCZl8qULEOvnPIUG6B443yXKj930glXIgwQirIBPp5rthP2amJW0YSzUg2s5sfgba4mRRCNw==", "dev": true }, + "@types/har-format": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/@types/har-format/-/har-format-1.2.12.tgz", + "integrity": "sha512-P20p/YBrqUBmzD6KhIQ8EiY4/RRzlekL4eCvfQnulFPfjmiGxKIoyCeI7qam5I7oKH3P8EU4ptEi0EfyGoLysw==" + }, "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", @@ -1479,6 +1436,12 @@ "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", "dev": true }, + "@types/json-schema": { + "version": "7.0.12", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz", + "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", + "dev": true + }, "@types/json-stable-stringify": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/@types/json-stable-stringify/-/json-stable-stringify-1.0.32.tgz", @@ -1503,6 +1466,12 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, "@types/ms": { "version": "0.7.31", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", @@ -1515,6 +1484,12 @@ "integrity": "sha512-leUNzbFTMX94TWaIKz8N15Chu55F9QSH+INKayQr5xpkasBQBRF3qQXfo3/dOnMU/dEIit+Y/SU8HyOjq++GwA==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, "@types/package-json": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@types/package-json/-/package-json-5.0.1.tgz", @@ -1873,12 +1848,12 @@ } }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" @@ -1891,9 +1866,9 @@ "dev": true }, "ajv-keywords": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", - "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", "dev": true }, "align-text": { @@ -2241,12 +2216,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "hosted-git-info": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.0.2.tgz", @@ -2361,45 +2330,13 @@ } }, "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==", + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz", + "integrity": "sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==", "dev": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "arg": { @@ -3045,47 +2982,6 @@ "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } - } - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", - "dev": true, - "requires": { - "inherits": "~2.0.0" } }, "bluebird": { @@ -3635,12 +3531,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4136,18 +4026,6 @@ } } }, - "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", - "dev": true, - "requires": { - "for-own": "^1.0.0", - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.0", - "shallow-clone": "^1.0.0" - } - }, "clone-response": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", @@ -4330,35 +4208,6 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "config-chain": { @@ -4821,6 +4670,16 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + } + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -5340,12 +5199,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -5570,38 +5423,6 @@ "inherits": "^2.0.1", "readable-stream": "^2.0.0", "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "ecc-jsbn": { @@ -5838,12 +5659,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6024,12 +5839,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -6690,7 +6499,7 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" } } }, @@ -6701,9 +6510,9 @@ "dev": true }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { @@ -6763,7 +6572,7 @@ "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", "requires": { "pend": "~1.2.0" } @@ -7009,38 +6818,6 @@ "requires": { "inherits": "^2.0.3", "readable-stream": "^2.3.6" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "follow-redirects": { @@ -7067,15 +6844,6 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -7122,38 +6890,6 @@ "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "fs-constants": { @@ -7178,6 +6914,32 @@ "universalify": "^0.1.0" } }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -7744,18 +7506,6 @@ } } }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -8079,9 +7829,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" }, "graceful-readlink": { "version": "1.0.1", @@ -8150,6 +7900,12 @@ "har-schema": "^2.0.0" } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -8301,38 +8057,6 @@ "obuf": "^1.0.0", "readable-stream": "^2.0.1", "wbuf": "^1.1.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "html-comment-regex": { @@ -8659,12 +8383,6 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, - "in-publish": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", - "dev": true - }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -8821,6 +8539,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", + "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-cwebp-readable": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-cwebp-readable/-/is-cwebp-readable-2.0.1.tgz", @@ -9104,10 +8831,9 @@ "dev": true }, "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isbinaryfile": { "version": "4.0.8", @@ -10082,9 +9808,9 @@ "dev": true }, "js-base64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz", - "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==", + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", "dev": true }, "js-tokens": { @@ -10159,6 +9885,12 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -10244,9 +9976,9 @@ "dev": true }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "kleur": { @@ -10255,6 +9987,12 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "klona": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true + }, "kuler": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/kuler/-/kuler-1.0.1.tgz", @@ -10315,6 +10053,12 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "load-bmfont": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.4.0.tgz", @@ -10380,9 +10124,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.sortby": { "version": "4.7.0", @@ -10390,12 +10134,6 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "lodash.tail": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", - "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", - "dev": true - }, "lodash.trim": { "version": "4.5.1", "resolved": "https://registry.npmjs.org/lodash.trim/-/lodash.trim-4.5.1.tgz", @@ -10637,38 +10375,6 @@ "requires": { "errno": "^0.1.3", "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "meow": { @@ -10708,38 +10414,6 @@ "dev": true, "requires": { "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "merge2": { @@ -10826,15 +10500,57 @@ "dom-walk": "^0.1.0" } }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "mini-css-extract-plugin": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.5.0.tgz", - "integrity": "sha512-IuaLjruM0vMKhUUT51fQdQzBYTX49dLj8w68ALEAe2A4iYNpIC4eMac67mt3NzycvjOlf07/kYxJDc0RTl1Wqw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.0.tgz", + "integrity": "sha512-4DKmPwFd0XKlwoqvrkLi2X8Mlosh2ey/E/OVAucnPUdzGqrSWHgSqed/p4Ue2Q39JjIvcdSDgmZDO6mir5Ovmw==", "dev": true, "requires": { - "loader-utils": "^1.1.0", - "schema-utils": "^1.0.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", "webpack-sources": "^1.1.0" + }, + "dependencies": { + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } } }, "minimalistic-assert": { @@ -10864,6 +10580,50 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -10882,36 +10642,6 @@ "through2": "^2.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", @@ -10951,24 +10681,6 @@ } } }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", - "dev": true, - "requires": { - "for-in": "^0.1.3", - "is-extendable": "^0.1.1" - }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", - "dev": true - } - } - }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", @@ -11070,9 +10782,9 @@ "dev": true }, "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, "nice-try": { @@ -11110,29 +10822,86 @@ "dev": true }, "node-gyp": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", "dev": true, "requires": { - "fstream": "^1.0.0", - "glob": "^7.0.3", - "graceful-fs": "^4.1.2", - "mkdirp": "^0.5.0", - "nopt": "2 || 3", - "npmlog": "0 || 1 || 2 || 3 || 4", - "osenv": "0", - "request": "^2.87.0", - "rimraf": "2", - "semver": "~5.3.0", - "tar": "^2.0.0", - "which": "1" + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" }, "dependencies": { + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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" + } + }, "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } @@ -11185,12 +10954,6 @@ "isarray": "^1.0.0" } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -11203,39 +10966,13 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "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" - }, - "dependencies": { - "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" - } - } - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" + "safe-buffer": "~5.2.0" }, "dependencies": { "safe-buffer": { @@ -11276,26 +11013,24 @@ } }, "node-sass": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz", - "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-6.0.1.tgz", + "integrity": "sha512-f+Rbqt92Ful9gX0cGtdYwjTrWAaGURgaK5rZCWOgCNyGWusFYHhbqCCBoFBeat+HKETOU02AyTxNhJV0YZf2jQ==", "dev": true, "requires": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", - "cross-spawn": "^3.0.0", + "cross-spawn": "^7.0.3", "gaze": "^1.0.0", "get-stdin": "^4.0.1", "glob": "^7.0.3", - "in-publish": "^2.0.0", - "lodash": "^4.17.11", - "meow": "^3.7.0", - "mkdirp": "^0.5.1", + "lodash": "^4.17.15", + "meow": "^9.0.0", "nan": "^2.13.2", - "node-gyp": "^3.8.0", + "node-gyp": "^7.1.0", "npmlog": "^4.0.0", "request": "^2.88.0", - "sass-graph": "^2.2.4", + "sass-graph": "2.2.5", "stdout-stream": "^1.4.0", "true-case-path": "^1.0.2" }, @@ -11306,6 +11041,23 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "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 + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -11328,13 +11080,234 @@ } }, "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.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" + } + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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 + }, + "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" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "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" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "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-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 + }, + "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": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "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" + } + }, + "semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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 + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" } }, "supports-color": { @@ -11342,6 +11315,39 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, + "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" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } }, @@ -11380,9 +11386,9 @@ } }, "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", "dev": true, "requires": { "abbrev": "1" @@ -11708,12 +11714,6 @@ "arch": "^2.1.0" } }, - "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 - }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", @@ -11770,22 +11770,6 @@ } } }, - "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 - }, - "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" - } - }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", @@ -12005,38 +11989,6 @@ "cyclist": "~0.2.2", "inherits": "^2.0.3", "readable-stream": "^2.1.5" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "param-case": { @@ -12658,6 +12610,12 @@ "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", "dev": true }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -12851,15 +12809,17 @@ } }, "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "requires": { "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "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" } }, "readdirp": { @@ -12871,38 +12831,6 @@ "graceful-fs": "^4.1.11", "micromatch": "^3.1.10", "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "realpath-native": { @@ -13036,9 +12964,9 @@ "dev": true }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "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", @@ -13048,7 +12976,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -13058,7 +12986,7 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } @@ -13312,138 +13240,86 @@ } }, "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", "dev": true, "requires": { "glob": "^7.0.0", "lodash": "^4.0.0", "scss-tokenizer": "^0.2.3", - "yargs": "^7.0.0" + "yargs": "^13.3.2" + } + }, + "sass-loader": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.4.1.tgz", + "integrity": "sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==", + "dev": true, + "requires": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" }, "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "cliui": { - "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", - "wrap-ansi": "^2.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==", + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true }, - "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=", + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", "dev": true, "requires": { - "invert-kv": "^1.0.0" + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" } }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "requires": { - "lcid": "^1.0.0" + "yallist": "^4.0.0" } }, - "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 - }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { - "camelcase": "^3.0.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.2", - "which-module": "^1.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { - "camelcase": "^3.0.0" + "lru-cache": "^6.0.0" } - } - } - }, - "sass-loader": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-7.1.0.tgz", - "integrity": "sha512-+G+BKGglmZM2GUSfT9TLuEp6tzehHPjAMoRRItOojWIqIGPloVCMhNIQuG639eJ+y033PaGTSjLaTHts8Kw79w==", - "dev": true, - "requires": { - "clone-deep": "^2.0.1", - "loader-utils": "^1.0.1", - "lodash.tail": "^4.1.1", - "neo-async": "^2.5.0", - "pify": "^3.0.0", - "semver": "^5.5.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } @@ -13547,7 +13423,7 @@ "semver-compare": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", "optional": true }, "semver-diff": { @@ -13744,25 +13620,6 @@ "safe-buffer": "^5.0.1" } }, - "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", - "dev": true, - "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^5.0.0", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -14312,38 +14169,6 @@ "dev": true, "requires": { "readable-stream": "^2.0.1" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "stealthy-require": { @@ -14360,38 +14185,6 @@ "requires": { "inherits": "~2.0.1", "readable-stream": "^2.0.2" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - } } }, "stream-each": { @@ -14417,36 +14210,6 @@ "xtend": "^4.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -14532,10 +14295,12 @@ } }, "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 + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } }, "strip-ansi": { "version": "3.0.1", @@ -14674,14 +14439,37 @@ "dev": true }, "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", + "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", "dev": true, "requires": { - "block-stream": "*", - "fstream": "^1.0.2", - "inherits": "2" + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "tar-stream": { @@ -14699,36 +14487,6 @@ "xtend": "^4.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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" - } - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", @@ -14764,12 +14522,6 @@ "universalify": "^2.0.0" } }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", - "dev": true - }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -14898,16 +14650,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } - }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", @@ -15160,21 +14902,13 @@ "dev": true }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, "tr46": { @@ -15568,12 +15302,6 @@ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true } } }, @@ -15940,46 +15668,6 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", "dev": true - }, - "ajv": { - "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", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "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 - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - } } } }, @@ -16299,9 +15987,9 @@ } }, "webpack-sources": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.3.0.tgz", - "integrity": "sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", "dev": true, "requires": { "source-list-map": "^2.0.0", @@ -16374,12 +16062,12 @@ "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==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" + "string-width": "^1.0.2 || 2 || 3 || 4" } }, "widest-line": { @@ -16480,35 +16168,6 @@ "requires": { "readable-stream": "^2.3.6", "triple-beam": "^1.2.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "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" - } - }, - "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==", - "requires": { - "safe-buffer": "~5.1.0" - } - } } }, "wordwrap": { @@ -16638,22 +16297,21 @@ "dev": true }, "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", "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": "^13.1.0" + "yargs-parser": "^13.1.2" }, "dependencies": { "ansi-regex": { @@ -16722,9 +16380,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -16742,7 +16400,7 @@ "yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", "requires": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" diff --git a/package.json b/package.json index 442428f..a677ed8 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "repository": "https://github.com/appodeal/admob-sync-app", "description": "Appodeal AdMob Sync application", "private": true, - "version": "0.1.32", + "version": "0.1.43", "scripts": { "start": "npm run start:app", "start:app": "node --max_old_space_size=4096 node_modules/.bin/webpack --watch --progress --config=webpack/development.ts", @@ -140,10 +140,10 @@ "github": "~0.2.4", "html-webpack-plugin": "^3.2.0", "jest": "^24.1.0", - "mini-css-extract-plugin": "^0.5.0", + "mini-css-extract-plugin": "1.3.0", "moment": "^2.22.2", - "node-sass": "^4.12.0", - "sass-loader": "^7.1.0", + "node-sass": "^6.0.1", + "sass-loader": "^10.4.1", "script-ext-html-webpack-plugin": "^2.1.3", "ts-jest": "^24.0.0", "ts-loader": "^5.3.3", @@ -157,7 +157,7 @@ }, "dependencies": { "@sentry/electron": "^2.5.3", - "@types/chrome": "0.0.88", + "@types/chrome": "0.0.200", "apollo-cache-inmemory": "^1.5.1", "apollo-client": "^2.5.1", "apollo-link-batch-http": "^1.2.8", diff --git a/schema.graphql b/schema.graphql index 83524e4..083e9c5 100644 --- a/schema.graphql +++ b/schema.graphql @@ -30,10 +30,19 @@ type AppPaginatableCollection { totalCount: Int! } +type CustomEvent { + className: String! + label: String! + params: String! + price: String! +} + type EcpmFloors { adType: AdType! + customEvents: [CustomEvent!] ecpmFloor: [Float!]! format: Format! + isThirdPartyBidding: Boolean } type Mutations { @@ -74,7 +83,7 @@ type Session { type User { account( - #Admob AccountId - `pub-\\d+` + "Admob AccountId - `pub-\\d+`" id: ID! ): AdmobAccount! accounts: [AdmobAccount!] @@ -85,43 +94,43 @@ type User { } enum AdType { - #Banners + "Banners" BANNER - #Interstitials + "Interstitials" INTERSTITIAL - #MREC + "MREC" MREC - #Native Ads + "Native Ads" NATIVE - #Rewarded Videos + "Rewarded Videos" REWARDED_VIDEO - #Videos + "Videos" VIDEO } enum Format { - #Image + "Image" IMAGE - #Image and text + "Image and text" IMAGE_AND_TEXT - #Rewarded + "Rewarded" REWARDED - #Rich media + "Rich media" RICHMEDIA - #Simple video + "Simple video" SIMPLE_VIDEO - #Text + "Text" TEXT - #Undefined + "Undefined" UNDEFINED } enum Platform { - #Amazon + "Amazon" AMAZON - #Android + "Android" ANDROID - #iOS + "iOS" IOS } @@ -132,4 +141,5 @@ input AdUnit { "Ad unit's eCPM" ecpmFloor: Float! format: Format! + isThirdPartyBidding: Boolean } diff --git a/src/core/admob-api/admob.api.ts b/src/core/admob-api/admob.api.ts index eecd7e6..695c290 100644 --- a/src/core/admob-api/admob.api.ts +++ b/src/core/admob-api/admob.api.ts @@ -28,7 +28,7 @@ export class AdmobApiService { // updated api version isCamApi (serviceName: string, method: string) { - return serviceName === 'AppService' && method === 'Create'; + return serviceName === 'AppService' && method === 'Create' || serviceName === 'AppService' && method === 'Update'; } private getPostApiEndpoint (serviceName: string, method: string) { diff --git a/src/core/admob-api/custom-event.api.ts b/src/core/admob-api/custom-event.api.ts new file mode 100644 index 0000000..dbe8315 --- /dev/null +++ b/src/core/admob-api/custom-event.api.ts @@ -0,0 +1,92 @@ +import {InternalError} from 'core/error-factory/errors/internal-error'; +import trim from 'lodash.trim'; + +export class RefreshXsrfTokenError extends Error {} + +export class CustomEventApiService { + + private host = trim(environment.services.ad_mob, '/'); + private xsrfToken: string; + + public onError: (e: InternalError) => void; + + private static serviceName(name: string): string { + return `${name.charAt(0).toUpperCase() + name.slice(1)}Service` + } + + private getPostMediationApiEndpoint(mediation: string, method: string) { + return [this.host, `${mediation}/_/rpc`, CustomEventApiService.serviceName(mediation), method].join('/'); + } + + constructor(private fetcher = fetch, private logger: Partial) { + } + + private setXrfToken(xsrfToken) { + this.xsrfToken = xsrfToken; + } + + refreshXsrfToken (body: string) { + const mathResult = body.match(/xsrfToken: '([^\']*)'/); + if (!mathResult || !mathResult[1]) { + throw new RefreshXsrfTokenError('failed to refresh xsrfToken'); + } + this.setXrfToken(mathResult[1]); + } + + private async fetch(url: string, contentType: string, body: string): Promise { + return this.fetcher( + url, + { + 'credentials': 'include', + 'headers': { + 'accept': 'application/json, text/plain, */*', + 'content-type': contentType, + 'x-framework-xsrf-token': this.xsrfToken + }, + 'referrerPolicy': 'no-referrer-when-downgrade', + 'body': body, + 'method': 'POST', + 'mode': 'cors' + } + ) + .then(async r => { + try { + return await r.json(); + } catch (e) { + this.logger.info(await r.text()); + throw e; + } + }); + } + + private handleError(e: InternalError) { + if (e && this.onError) { + return this.onError(e); + } + } + + /** + * post requests to Admob + * @param mediation + * @param method + * @param payload + * @param idx + */ + postRaw(mediation: string, method: string, payload: any, idx: number = 0) { + return this.fetch( + this.getPostMediationApiEndpoint(mediation, method), + 'application/x-www-form-urlencoded', + `f.req=${encodeURIComponent(JSON.stringify(payload))}` + ) + .then((data) => { + return data; + }) + .catch(e => { + this.logger.error(`Failed to Post to AdMob '${mediation}Service' '${method}'`); + this.logger.info(`payload`, payload); + this.logger.error(e); + this.handleError(e); + throw e; + }); + } +} diff --git a/src/core/admob-api/extract-admob-account-info.ts b/src/core/admob-api/extract-admob-account-info.ts index ad070f5..7f0e0b6 100644 --- a/src/core/admob-api/extract-admob-account-info.ts +++ b/src/core/admob-api/extract-admob-account-info.ts @@ -2,6 +2,23 @@ import {ExtractedAdmobAccount} from '../../interfaces/common.interfaces'; import {decodeOctString} from '../../lib/oct-decode'; +function extractObjectFromJsonString (str) { + let open = 0; + let close = 0; + for (let i = 0; i < str.length; i++) { + if (str[i] === '{') { + open++; + } + if (str[i] === '}') { + close++; + } + if (open > 0 && close === open) { + return str.substr(0, i+1); + } + } + return false; +} + export function extractAccountInfo (responseBody: string): ExtractedAdmobAccount { let amrpdSource; try { @@ -14,8 +31,11 @@ export function extractAccountInfo (responseBody: string): ExtractedAdmobAccount let email; result = /var amrpd = '(?.*?)';/.exec(responseBody); amrpdSource = decodeOctString(result.groups.emailSource); - const amrpd = JSON.parse(amrpdSource); - email = amrpd[32][3][1]; + + const shortObj = extractObjectFromJsonString(/(.*)"32":(?.*)/.exec(amrpdSource).groups.emailSource) + + const amrpd = JSON.parse(shortObj); + email = amrpd[3][1]; return { id, diff --git a/src/core/appdeal-api/appodeal-api.service.ts b/src/core/appdeal-api/appodeal-api.service.ts index 52e923f..07dc96e 100644 --- a/src/core/appdeal-api/appodeal-api.service.ts +++ b/src/core/appdeal-api/appodeal-api.service.ts @@ -260,7 +260,13 @@ export class AppodealApiService { syncSessionId: syncId, admobAppId: adMobApp.appId, admobAccountId, - adUnits: adUnits + adUnits: adUnits.map(v => ({ + adType: v.adType, + code: v.code, + ecpmFloor: v.ecpmFloor, + format: v.format, + isThirdPartyBidding: v.isThirdPartyBidding + })) } }); } diff --git a/src/core/appdeal-api/graphql/admob-account-details.graphql b/src/core/appdeal-api/graphql/admob-account-details.graphql index f6d2551..0c3980b 100644 --- a/src/core/appdeal-api/graphql/admob-account-details.graphql +++ b/src/core/appdeal-api/graphql/admob-account-details.graphql @@ -12,8 +12,15 @@ query currentUser ($id: ID!, $page: Int, $pageSize: Int) { isDeleted ecpmFloors { adType - format + customEvents { + className + label + params + price + } ecpmFloor + format + isThirdPartyBidding } } pageInfo { @@ -25,4 +32,4 @@ query currentUser ($id: ID!, $page: Int, $pageSize: Int) { } } } -} \ No newline at end of file +} diff --git a/src/core/appdeal-api/interfaces/appodeal-app.interface.ts b/src/core/appdeal-api/interfaces/appodeal-app.interface.ts index 42bf3b6..5806db9 100644 --- a/src/core/appdeal-api/interfaces/appodeal-app.interface.ts +++ b/src/core/appdeal-api/interfaces/appodeal-app.interface.ts @@ -15,13 +15,23 @@ export interface AppodealApp { platform: AppodealPlatform; admobAppId: string; ecpmFloors: EcpmFloors[] + customEventsList: any[] } export interface EcpmFloors { - adType: AdType; - format: Format; + adType: AdType + customEvents: CustomEvent[] ecpmFloor: number[] + format: Format + isThirdPartyBidding: boolean +} + +export interface CustomEvent { + className: string + label: string + params: string + price: string } export enum AdType { @@ -30,7 +40,8 @@ export enum AdType { BANNER = 'BANNER', NATIVE = 'NATIVE', MREC = 'MREC', - REWARDED_VIDEO = 'REWARDED_VIDEO' + REWARDED_VIDEO = 'REWARDED_VIDEO', + REWARDED_INTERSTITIAL = 'REWARDED_INTERSTITIAL' } export enum Format { @@ -48,4 +59,8 @@ export interface AppodealAdUnit { adType: AdType; format: Format; ecpmFloor: number; + isThirdPartyBidding: boolean; + internalAdmobAdUnitId: string; + adUnitId: string; + name: string; } diff --git a/src/core/json-storage/local-storage.json-storage.ts b/src/core/json-storage/local-storage.json-storage.ts index a273f37..2ff95fa 100644 --- a/src/core/json-storage/local-storage.json-storage.ts +++ b/src/core/json-storage/local-storage.json-storage.ts @@ -4,7 +4,11 @@ import {JsonStorage} from './json-storage.interface'; export class LocalStorageJsonStorage implements JsonStorage { async save (key: string, value: any): Promise { - localStorage.setItem(key, JSON.stringify(value)); + try { + localStorage.setItem(key, JSON.stringify(value)); + } catch (e) { + console.warn(`[LocalStorageJsonStorage] failed to save json`, e); + } } async load (key: string, defaultValue?: any): Promise { diff --git a/src/core/store.ts b/src/core/store.ts index 1024936..8606f89 100644 --- a/src/core/store.ts +++ b/src/core/store.ts @@ -232,7 +232,7 @@ export class Store { switch (event.type) { case SyncEventsTypes.Started: this.pushLogs(account); - case SyncEventsTypes.CalculatingProgress: + case SyncEventsTypes.CalculatingProgress: this.state.syncProgress[event.accountId] = { id: event.id, totalApps: 0, @@ -250,7 +250,7 @@ export class Store { completedApps: pEvent.synced, failedApps: pEvent.failed, percent: pEvent.percent, - lastEvent: event.type + lastEvent: event.type, }; this.pushLogs(account); return this.fireSyncUpdated(); diff --git a/src/core/sync-apps/sync.events.ts b/src/core/sync-apps/sync.events.ts index 79dfe69..7540540 100644 --- a/src/core/sync-apps/sync.events.ts +++ b/src/core/sync-apps/sync.events.ts @@ -20,7 +20,8 @@ export interface SyncReportProgressEvent extends SyncEvent { percent: number; adUnitsCurrent: number; adUnitsTotal: number; - failed?: number + failed?: number; + step: number } export interface SyncStopEvent extends SyncEvent { diff --git a/src/core/sync-apps/sync.service.ts b/src/core/sync-apps/sync.service.ts index 4484a7d..b814ae0 100644 --- a/src/core/sync-apps/sync.service.ts +++ b/src/core/sync-apps/sync.service.ts @@ -13,6 +13,7 @@ import {createFetcher} from 'lib/fetch'; import {createSyncLogger, getLogContent, LoggerInstance, rotateSyncLogs} from 'lib/sync-logs/logger'; import uuid from 'uuid'; import {SyncRunner} from './sync-runner'; +import {CustomEventApiService} from "../admob-api/custom-event.api"; type FinishPromise = Promise; @@ -78,6 +79,7 @@ export class SyncService { const logger = await createSyncLogger(admobAccount, id); const adMobApi = new AdmobApiService(await createFetcher(admobSession), logger); + const customEventApi = new CustomEventApiService(await createFetcher(admobSession), logger); const sync = new Sync( adMobApi, @@ -85,8 +87,9 @@ export class SyncService { admobAccount, appodealAccount, logger, + customEventApi, id, - runner + runner, ); logger.info(`Sync started by ${runner === SyncRunner.User ? 'User' : 'Schedule'}`); diff --git a/src/core/sync-apps/sync.ts b/src/core/sync-apps/sync.ts index afe8d52..2365d86 100644 --- a/src/core/sync-apps/sync.ts +++ b/src/core/sync-apps/sync.ts @@ -1,16 +1,37 @@ import {captureMessage} from '@sentry/core'; import {AdmobApiService, RefreshXsrfTokenError, UpdateRequest, UpdateResponse} from 'core/admob-api/admob.api'; import {AppodealApiService} from 'core/appdeal-api/appodeal-api.service'; -import {AdType, AppodealAdUnit, AppodealApp, AppodealPlatform, Format} from 'core/appdeal-api/interfaces/appodeal-app.interface'; +import { + AdType, + AppodealAdUnit, + AppodealApp, + AppodealPlatform, CustomEvent, + Format +} from 'core/appdeal-api/interfaces/appodeal-app.interface'; import {getAdUnitTemplate} from 'core/sync-apps/ad-unit-templates'; import {SyncStats} from 'core/sync-apps/sync-stats'; import stringify from 'json-stable-stringify'; import {retryProxy} from 'lib/retry'; -import {AppCreateRequestTranslator, AppCreateResponseTranslator, AppTranslator} from 'lib/translators/admob-app.translator'; +import { + AppCreateRequestTranslator, + AppCreateResponseTranslator, + AppTranslator +} from 'lib/translators/admob-app.translator'; import {AdMobPlatform} from 'lib/translators/admob.constants'; import {AdUnitTranslator} from 'lib/translators/admop-ad-unit.translator'; -import {AdMobAdUnit, CpmFloorMode, CpmFloorSettings} from 'lib/translators/interfaces/admob-ad-unit.interface'; -import {AdMobApp, AppCreateRequest, AppCreateResponse, Host, UserMetricsStatus} from 'lib/translators/interfaces/admob-app.interface'; +import { + AdMobAdFormat, + AdMobAdUnit, + CpmFloorMode, + CpmFloorSettings +} from 'lib/translators/interfaces/admob-ad-unit.interface'; +import { + AdMobApp, + AppCreateRequest, + AppCreateResponse, + Host, + UserMetricsStatus +} from 'lib/translators/interfaces/admob-app.interface'; import {getTranslator} from 'lib/translators/translator.helpers'; import uuid from 'uuid'; import {decodeOctString} from '../../lib/oct-decode'; @@ -23,6 +44,7 @@ import {SyncEventEmitter} from './sync-event.emitter'; import {SyncRunner} from './sync-runner'; import {SyncErrorEvent, SyncEvent, SyncEventsTypes, SyncReportProgressEvent, SyncStopEvent} from './sync.events'; import escapeStringRegexp = require('escape-string-regexp'); +import {CustomEventApiService} from "core/admob-api/custom-event.api"; const isObject = (v) => v !== null && typeof v === 'object'; @@ -49,9 +71,20 @@ interface AdUnitTemplate extends Partial { ecpmFloor: number; adType: AdType; format: Format; + customEvents?: CustomEvent[], } } +enum CustomEventPlatform { + 'ANDROID' = '12', + 'IOS' = '13' +} + +enum PlatformGroup { + 'IOS' = 1, + 'ANDROID' = 2, +} + const defaultAdUnitPrefix = 'Appodeal'; export class Sync { @@ -78,7 +111,7 @@ export class Sync { */ private skipNativeAdUnits = false; - constructor ( + constructor( // With retry proxy // each failed request will be retried 3 times automatically private adMobApi: AdmobApiService, @@ -86,6 +119,7 @@ export class Sync { public adMobAccount: AdMobAccount, private appodealAccount: AppodealAccount, private logger: Partial, + private customEventApi: CustomEventApiService, // some uniq syncId public readonly id: string, public readonly runner: SyncRunner @@ -94,7 +128,7 @@ export class Sync { this.beforeRun(); } - async stop (reason: string) { + async stop(reason: string) { if (this.terminated) { this.logger.info(`Sync already stopped. New Stop Reason: ${reason}`); return; @@ -104,7 +138,7 @@ export class Sync { this.logger.info(`Stopping Sync Reason: ${reason}`); } - beforeRun () { + beforeRun() { const retryCondition = e => e.message.substring(0, 'net::ERR'.length) === 'net::ERR' @@ -121,7 +155,7 @@ export class Sync { this.appodealApi = retryProxy(this.appodealApi, retryCondition, 3, 5000, terminateIfConnectionLost); } - async run () { + async run() { this.logger.info(`Sync started`); this.terminated = false; try { @@ -141,13 +175,13 @@ export class Sync { } } - finish () { + finish() { this.stats.end(); this.emitStop(); this.appodealApi.reportSyncEnd(this.id); } - emit (event: SyncEvent | SyncEventsTypes) { + emit(event: SyncEvent | SyncEventsTypes) { if (isObject(event)) { (event).id = this.id; (event).accountId = this.adMobAccount.id; @@ -156,7 +190,7 @@ export class Sync { return this.events.emit({type: event, id: this.id, accountId: this.adMobAccount.id}); } - emitProgress () { + emitProgress() { const progress: Partial = {}; progress.synced = this.syncedAppCount; progress.failed = this.failedAppCount; @@ -174,7 +208,7 @@ export class Sync { return this.emit(progress); } - emitError (error: Error) { + emitError(error: Error) { this.hasErrors = true; return this.emit({ type: SyncEventsTypes.Error, @@ -186,7 +220,7 @@ export class Sync { return this.emit({type: SyncEventsTypes.Stopped, terminated: this.terminated, hasErrors: this.hasErrors}); } - async* doSync () { + async* doSync() { this.stats.start(); this.emit(SyncEventsTypes.Started); this.logger.info(`Sync Params @@ -217,7 +251,7 @@ export class Sync { } } - async* fetchDataToSync () { + async* fetchDataToSync() { yield `refrech Admob xsrf Token`; @@ -225,10 +259,12 @@ export class Sync { try { pageBody = await this.adMobApi.fetchHomePage().then(response => response.text()); this.adMobApi.refreshXsrfToken(pageBody); + this.customEventApi.refreshXsrfToken(pageBody); const body = await this.adMobApi.fetchCamApiAppsSettings(this.adMobAccount.id).then(response => response.text()); this.adMobApi.setCamApiXsrfToken(this.adMobApi.ejectCamApiXsrfToken(body)); + } catch (e) { if (e instanceof RefreshXsrfTokenError) { // this error is not supposed to be emitted and handler further @@ -275,7 +311,7 @@ export class Sync { } - ejectAppsAppsFromAdmob (body: string) { + ejectAppsAppsFromAdmob(body: string) { const mathResult = body.match(/var apd = '(?[^\']*)';/); @@ -295,7 +331,7 @@ export class Sync { } } - ejectAdUnitsFromAdmob (body: string) { + ejectAdUnitsFromAdmob(body: string) { const mathResult = body.match(/var aupd = '(?[^\']*)';/); if (!mathResult || !mathResult.groups || !mathResult.groups.appsJson) { @@ -314,7 +350,7 @@ export class Sync { } } - prepareApps (apps) { + prepareApps(apps) { const prepareAppDataToSync = (app: AppodealAppToSync) => { @@ -327,6 +363,8 @@ export class Sync { app.adUnitsToUpdateName = []; app.adUnitTemplatesToCreate = new Map(); + app.customEventsList = []; + if (app.isDeleted) { return app; } @@ -352,6 +390,9 @@ export class Sync { app.adUnitsToUpdateName = app.oldGoodAdUnits.filter( adMobAdUnit => adMobAdUnit.name.substr(0, this.adUnitNamePrefix.length) !== this.adUnitNamePrefix ); + + // fill customEventsList + return app; }; @@ -366,7 +407,7 @@ export class Sync { .map(calculateTotal); } - async* syncApps () { + async* syncApps() { const apps = this.apps = this.prepareApps(this.context.getAppodealApps()); @@ -391,14 +432,14 @@ export class Sync { } - static toAdMobPlatform (app: AppodealApp): AdMobPlatform { + static toAdMobPlatform(app: AppodealApp): AdMobPlatform { if (app.platform === AppodealPlatform.IOS) { return AdMobPlatform.IOS; } return AdMobPlatform.Android; } - async* syncDeletedApp (app: AppodealApp, adMobApp: AdMobApp) { + async* syncDeletedApp(app: AppodealApp, adMobApp: AdMobApp) { if (!adMobApp) { this.logger.info('deleted App not found in admob'); return; @@ -427,7 +468,7 @@ export class Sync { } - async* syncApp (app: AppodealAppToSync) { + async* syncApp(app: AppodealAppToSync) { yield `Start Sync App [${app.id}] ${app.name}`; let adMobApp = this.findAdMobApp(app, this.context.getActiveAdmobApps()); @@ -490,21 +531,253 @@ export class Sync { const actualAdUnits = yield* this.syncAdUnits(app, adMobApp); yield `AdUnits actualized`; + yield* this.syncCustomEvents(app); + yield `CustomEvents actualized`; + await this.appodealApi.reportAppSynced(app, this.id, this.adMobAccount.id, adMobApp, actualAdUnits); yield `End Sync App [${app.id}] ${app.name}`; } + async* syncCustomEvents(app: AppodealAppToSync) { + let adUnitsForCustomEvents = this.adUnitsForCustomEvents(app); + + // create events + for (const adUnit of adUnitsForCustomEvents) { + + if (adUnit.customEvents.length > 0) { + // split to chunks by 50 event in each request + let splitCustomEventsList = this.slicingListCustomEvents(adUnit.customEvents); + for (const itemEvents of splitCustomEventsList) { + let payload = { + ...adUnit, + adUnitId: adUnit.internalAdmobAdUnitId, + customEvents: [...itemEvents] + }; + + this.prepareAdUnitForCreateGroup( + await this.createCustomEvents(payload), + adUnit + ); + } + } + } - async* syncAdUnits (app: AppodealAppToSync, adMobApp: AdMobApp) { - const templatesToCreate = app.adUnitTemplatesToCreate; - const {adUnitsToDelete, appodealAdUnits, oldGoodAdUnits} = app; + // create groups + await this.createGroups(app, adUnitsForCustomEvents); + } - this.emitProgress(); + async createGroups (app, adUnitsForCustomEvents) { + for (const adUnit of adUnitsForCustomEvents) { + if (adUnit.customEvents.length) { + let groupList = await this.getCreatedMediationGroup(); + let adMobMediationGroup = groupList[1].find(e => e['2'] === adUnit.name); + if (!adMobMediationGroup) { + let resp = await this.createMediationGroup(app, adUnit); + adMobMediationGroup = resp['1']; + } - this.logger.info(`AdUnits to create ${templatesToCreate.size}. AdUnit to Delete ${adUnitsToDelete.length}. Unchanged AdUnits ${appodealAdUnits.length}`); + await this.updateMediationGroup(app, adUnit, adMobMediationGroup); + } + } + } + + slicingListCustomEvents (array: any[]): any[] { + let size = 37; + let subarray = []; + for (let i = 0; i < Math.ceil(array.length / size); i++){ + subarray[i] = array.slice((i*size), (i*size) + size); + } + return subarray; + } + + adUnitsForCustomEvents(app: AppodealAppToSync): Array> { + return app.appodealAdUnits.filter(u=>u.customEvents ).map((adUnit) => { + return { + ...adUnit, + isDeleted: false, + platform: CustomEventPlatform[app.platform], + } as (AppodealAdUnit & Record) + }); + } + + async getCreatedBiddingAdUnits(admobAppId: string): Promise { + if (!admobAppId) { + return; + } + return await this.adMobApi.postRaw('AdUnitService', 'ListGoogleBiddingAdUnits', { + 1: admobAppId + }); + } + + async getCreatedMediationGroup() { + return await this.customEventApi.postRaw( + 'mediationGroup', + 'List', + {} + ) + } + + async createCustomEvents(adUnit) { + return await this.customEventApi.postRaw( + 'mediationAllocation', + 'Update', + this.adUnitPayload(adUnit) + ); + } + + async createMediationGroup(app, adUnit) { + return await this.customEventApi.postRaw( + 'mediationGroup', + 'V2Create', + this.createV2Param(app, adUnit) + ) + } + + async updateMediationGroup(app, adUnit, responseV2Params) { + return await this.customEventApi.postRaw( + 'mediationGroup', + 'V2Update', + this.createV2UpdateParam(app, adUnit, responseV2Params) + ) + } + + createV2Param(app: AppodealApp, adUnit: any) { + return { + "1": adUnit.name, + "2": 1, + "3": { + "1": PlatformGroup[app.platform], + "2": this.getAdUnitType(adUnit.adType), + "3": [adUnit.adUnitId], + "6": 1 + }, + "4": [ + { + "2": "1", + "3": 1, + "4": 1, + "5": {"1": "10000", "2": "USD"}, + "6": false, + "9": "AdMob+Network", + "11": 1, + "14": "2" + }, + ] + } + } + + // save response v2Param + createV2UpdateParam(app: AppodealApp, adUnit: any, responseV2Param) { + let map = new Map(); + responseV2Param['5'].forEach(e => map.set(e['9'], e)); + + adUnit.customEvents.forEach(event => { + if (!map.has(event.label)) { + map.set(event.label, { + "2": "7", + "3": 1, + "4": 2, + "5": {"1": event.price, "2": "USD"}, + "7": [{ + "1": adUnit.adUnitId, + "2": {"1": [ + {"1": "class_name", "2": event.className}, + {"1": "parameter", "2": event.params}, + {"1": "label", "2": event.label} + ]} + }], + "9": event.label, + "11": 1, + "12": {"1": 0}, + "13": [event.eventId], + "14": adUnit.platform, + "15": 0 + }) + } + }); + + return { + "1": { + ...responseV2Param, + "5": [...map.values()], + } + } + } + prepareAdUnitForCreateGroup(resp, adUnit) { + if (!resp[1]) { + return; + } + resp[1].forEach(createdEvent => { + adUnit.customEvents.forEach(event => { + if (createdEvent['15'] !== event.label) { + return; + } + + if (event['eventId']) { + return; + } + + event['eventId'] = createdEvent['1']; + event['removeId'] = createdEvent['11']; + event.price = String(event.price * 1000000); + }) + }); + } + + adUnitPayload(adUnit: any) { + return { + "1": adUnit.isDeleted ? this.removeCustomEvent(adUnit) : this.createCustomEvent(adUnit), + "2": [] + } + } + + createCustomEvent(adUnit): any[] { + return adUnit.customEvents.map(event => ({ + "1": '-1', + "2": adUnit.isDeleted, + "3": "7", + "4": [ + {"1": "class_name", "2": event.className}, + {"1": "parameter", "2": event.params}, + {"1": "label", "2": event.label} + ], + "10": 1, + "12": adUnit.adUnitId, + "15": event.label, + "16": adUnit.platform + })) + } + + removeCustomEvent(adUnit): any[] { + return adUnit.customEvents.map(event => ({ + "1": adUnit.eventId, + "2": adUnit.isDeleted, + "3": "7", + "4": [ + {"1": "class_name", "2": event.className}, + {"1": "parameter", "2": event.params}, + {"1": "label", "2": event.label} + ], + "7": false, + "9": false, + "10": 1, + "11": adUnit.removeId, + "12": adUnit.adUnitId, + "14": 7, + "15": event.label, + "16": adUnit.platform + })); + } + + async* syncAdUnits(app: AppodealAppToSync, adMobApp: AdMobApp) { + const templatesToCreate = app.adUnitTemplatesToCreate; + const {adUnitsToDelete, appodealAdUnits, oldGoodAdUnits} = app; + + this.emitProgress(); + this.logger.info(`AdUnits to create ${templatesToCreate.size}. AdUnit to Delete ${adUnitsToDelete.length}. Unchanged AdUnits ${appodealAdUnits.length}`); for (const adUnitTemplate of templatesToCreate.values()) { app.subProgressCurrent++; @@ -537,12 +810,12 @@ export class Sync { // delete bad AdUnits if (adUnitsToDelete.length) { - await this.deleteAdMobAdUnits(adUnitsToDelete); + // await this.deleteAdMobAdUnits(adUnitsToDelete); this.context.removeAdMobAdUnits(adUnitsToDelete); yield `Bad AdUnits (${adUnitsToDelete}) was deleted`; } - // rename adunits if needed + // rename adUnits if needed for (let adMobAdUnit of oldGoodAdUnits) { if (adMobAdUnit.name.substr(0, this.adUnitNamePrefix.length) !== this.adUnitNamePrefix) { app.subProgressCurrent++; @@ -558,16 +831,20 @@ export class Sync { return appodealAdUnits; } - convertToAppodealAdUnit (adMobAdUnit: AdMobAdUnit, template: AdUnitTemplate): AppodealAdUnit { + convertToAppodealAdUnit(adMobAdUnit: AdMobAdUnit, template: AdUnitTemplate): AppodealAdUnit { return { + isThirdPartyBidding: template.isThirdPartyBidding, code: this.adUnitCode(adMobAdUnit), + internalAdmobAdUnitId: adMobAdUnit.adUnitId, + adUnitId: adMobAdUnit.adUnitId, + name:adMobAdUnit.name, ...template.__metadata }; } // filter adUnits which user created manually // we should work only adUnits created automatically during sync - getActiveAdmobAdUnitsCreatedByApp (app: AppodealApp, adMobApp: AdMobApp) { + getActiveAdmobAdUnitsCreatedByApp(app: AppodealApp, adMobApp: AdMobApp) { return this.filterAppAdUnits(app, this.context.getAdMobAppActiveAdUnits(adMobApp)); } @@ -578,7 +855,7 @@ export class Sync { // to // "Appodeal/157197/interstitial/image_and_text/25.00" - static normalizeAdmobAdUnitName (adUnitName: string) { + static normalizeAdmobAdUnitName(adUnitName: string) { if (/\/image$/.test(adUnitName)) { return adUnitName.replace(/\/(image)$/, '/image_and_text'); @@ -602,7 +879,7 @@ export class Sync { } - filterAppAdUnits (app: AppodealApp, adUnits: AdMobAdUnit[]) { + filterAppAdUnits(app: AppodealApp, adUnits: AdMobAdUnit[]) { const pattern = new RegExp('^' + [ `(${escapeStringRegexp(defaultAdUnitPrefix)}|${escapeStringRegexp(this.adUnitNamePrefix)})`, app.id, @@ -614,29 +891,50 @@ export class Sync { return adUnits.filter(adUnit => pattern.test(adUnit.name)); } - adUnitCode (adUnit: AdMobAdUnit) { + adUnitCode(adUnit: AdMobAdUnit) { return `ca-app-${this.adMobAccount.id}/${adUnit.adUnitId}`; } - adUnitName (app: AppodealApp, adType: AdType, format: Format, cpmFloor?: number) { + adUnitName(app: AppodealApp, adType: AdType, format: Format, cpmFloor?: number, customName: string = '') { return [ this.adUnitNamePrefix, app.id, adType.toLowerCase(), format.toLowerCase(), - cpmFloor ? cpmFloor.toFixed(2) : undefined + cpmFloor ? cpmFloor.toFixed(2) : undefined, + customName ] // to remove empty values .filter(v => v) .join('/'); } + getAdUnitType(adType: AdType) { + // 0 - banner or mrec, 1 - interstital, 3 - native advanced, 5 - revarded, 8 - rewarded interstitial + switch (adType) { + // Mrec & banner have same template + case AdType.BANNER: + case AdType.MREC: + return 0; + case AdType.INTERSTITIAL: + return 1; + case AdType.NATIVE: + return 3; + case AdType.REWARDED_VIDEO: + return 5; + case AdType.REWARDED_INTERSTITIAL: + return 8; + default: + return null; + } + } + /** * Build map of AdUnits which is supposed to be created * @param app */ - buildAdUnitsSchema (app: AppodealApp): Map { + buildAdUnitsSchema(app: AppodealApp): Map { return app.ecpmFloors .map(floor => ({floor, template: getAdUnitTemplate(floor.adType)})) @@ -647,25 +945,19 @@ export class Sync { } return true; }) - .map(({floor, template}) => { + .map(({floor, template}, i) => { return [ // default adUnit with no ecpm - { - ...template, - __metadata: { - adType: floor.adType, - ecpmFloor: 0, - format: floor.format - }, - name: this.adUnitName(app, floor.adType, floor.format) - }, + this.buildDefaultAdUnitForMediationGroup(app, floor, template), // AdUnits for sent ecpm Floors ...floor.ecpmFloor.filter(v => v > 0).map(ecpmFloor => ({ ...template, - name: this.adUnitName(app, floor.adType, floor.format, ecpmFloor), + name: this.buildAdUnitName(app, floor, ecpmFloor), + isThirdPartyBidding: floor.isThirdPartyBidding, __metadata: { adType: floor.adType, ecpmFloor: ecpmFloor, + customEvents: floor.customEvents, format: floor.format }, cpmFloorSettings: { @@ -693,6 +985,41 @@ export class Sync { }, new Map()); } + buildAdUnitName (app, floor, ecpmFloor = null): string { + switch (floor.isThirdPartyBidding) { + case true: + return this.adUnitName(app, floor.adType, floor.format, ecpmFloor, 'partner_bidding'); + case false: + return this.adUnitName(app, floor.adType, floor.format, ecpmFloor, 'mediation_group'); + default: + return this.adUnitName(app, floor.adType, floor.format, ecpmFloor); + } + } + + // build options to create a default ad unit to add to mediation group or options without ecpm + buildDefaultAdUnitForMediationGroup (app, floor, template) { + let adUnitParams = { + ...template, + __metadata: { + adType: floor.adType, + ecpmFloor: 0, + customEvents: floor.customEvents, + format: floor.format + }, + name: this.buildAdUnitName(app, floor), + isThirdPartyBidding: floor.isThirdPartyBidding, + } + + return floor.isThirdPartyBidding === false ? { + ...adUnitParams, + googleOptimizedRefreshRate: true, + cpmFloorSettings: { + floorMode: CpmFloorMode.OptimizedByGoogle, + optimized: 3 + } + } : adUnitParams + } + /** * build Template ID from which adUnit is created @@ -701,7 +1028,7 @@ export class Sync { * that is why we match adunit only by AdFormat which can not be changed and its name * @param adUnit */ - static getAdUnitTemplateId (adUnit: AdMobAdUnit): AdUnitTemplateId { + static getAdUnitTemplateId(adUnit: AdMobAdUnit): AdUnitTemplateId { return stringify([ // extract prefix. it has no power here @@ -710,17 +1037,17 @@ export class Sync { ]); } - patchNamePrefix (name: string): string { + patchNamePrefix(name: string): string { const chunks = name.split('/'); chunks[0] = this.adUnitNamePrefix; return chunks.join('/'); } - get adUnitNamePrefix () { + get adUnitNamePrefix() { return this.appodealAccount.adUnitNamePrefix || defaultAdUnitPrefix; } - validateAdmobApp (app: AppodealApp, adMobApp: AdMobApp) { + validateAdmobApp(app: AppodealApp, adMobApp: AdMobApp) { if (!adMobApp) { return null; } @@ -744,11 +1071,11 @@ export class Sync { return adMobApp; } - appNameRegExp (app: AppodealApp) { + appNameRegExp(app: AppodealApp) { return new RegExp(`^(${escapeStringRegexp(defaultAdUnitPrefix)}|${escapeStringRegexp(this.adUnitNamePrefix)})/${app.id}/.*$`); } - findAdMobApp (app: AppodealApp, apps: AdMobApp[]): AdMobApp { + findAdMobApp(app: AppodealApp, apps: AdMobApp[]): AdMobApp { const adMobPlatform = Sync.toAdMobPlatform(app); let adMobApp = app.platform !== AppodealPlatform.AMAZON && app.bundleId @@ -784,7 +1111,7 @@ export class Sync { } - async createAdMobApp (app: AppodealApp, admobAccountId: string): Promise { + async createAdMobApp(app: AppodealApp, admobAccountId: string): Promise { const adMobApp: Partial = { name: [this.adUnitNamePrefix, app.id, app.name].join('/').substr(0, MAX_APP_NAME_LENGTH), @@ -803,7 +1130,7 @@ export class Sync { .then(res => (getTranslator(AppCreateResponseTranslator).decode(res) as AppCreateResponse).app); } - async updateAdMobAppName (adMobApp: AdMobApp, newName: string): Promise { + async updateAdMobAppName(adMobApp: AdMobApp, newName: string): Promise { adMobApp.name = newName; return await this.adMobApi.postRaw('AppService', 'Update', { 1: getTranslator(AppTranslator).encode(adMobApp), @@ -812,17 +1139,17 @@ export class Sync { } - async showAdMobApp (adMobApp: AdMobApp): Promise { + async showAdMobApp(adMobApp: AdMobApp): Promise { return this.adMobApi.postRaw('AppService', 'BulkUpdateVisibility', {1: [adMobApp.appId], 2: true}) .then(() => ({...adMobApp, hidden: false})); } - async hideAdMobApp (adMobApp: AdMobApp): Promise { + async hideAdMobApp(adMobApp: AdMobApp): Promise { return this.adMobApi.postRaw('AppService', 'BulkUpdateVisibility', {1: [adMobApp.appId], 2: false}) .then(() => ({...adMobApp, hidden: true})); } - async linkAppWithStore (app: AppodealApp, adMobApp: AdMobApp): Promise { + async linkAppWithStore(app: AppodealApp, adMobApp: AdMobApp): Promise { interface SearchAppRequest { 1: string; // query @@ -843,26 +1170,38 @@ export class Sync { 4: Sync.toAdMobPlatform(app) }).then((response: SearchAppResponse) => response[1] ? response[2].map(getTranslator(AppTranslator).decode) : []); - const publishedApp = searchAppResponse.find(publishedApp => publishedApp.applicationStoreId === app.bundleId); + + const publishedApp = searchAppResponse.find(publishedApp => { + return app.platform === AppodealPlatform.IOS ? publishedApp.applicationPackageName === app.bundleId : publishedApp.applicationStoreId === app.bundleId; + }); if (publishedApp) { this.logger.info(`App found in store`); this.stats.appUpdated(app); adMobApp = {...adMobApp, ...publishedApp}; - return await this.adMobApi.postRaw('AppService', 'Update', { - 1: getTranslator(AppTranslator).encode(adMobApp), - 2: {1: ['application_store_id', 'vendor']} - }).then((res: UpdateResponse) => getTranslator(AppTranslator).decode(res[1])); + let copyAdmobApp = {...adMobApp} + delete copyAdmobApp.appId; + return await this.adMobApi.postRaw( + 'AppService', + 'Update', + { + "1": {"1": {"1": 1, "3": this.adMobAccount.id}}, + "2": [{ + "1": getTranslator(AppTranslator).encode(copyAdmobApp), + "2": ["stores", "application_store_id", "name"] + }] + } + ).then((res: UpdateResponse) => getTranslator(AppTranslator).decode(res[2][0])); } this.logger.info(`App NOT found in store`); return adMobApp; } - async createAdMobAdUnit (adUnit: Partial): Promise { + async createAdMobAdUnit(adUnit: Partial): Promise { return this.adMobApi.post('AdUnitService', 'Create', getTranslator(AdUnitTranslator).encode(adUnit)) .then(res => getTranslator(AdUnitTranslator).decode(res)); } - async updateAdMobAdUnitName (adMobAdUnit: AdMobAdUnit, newName: string): Promise { + async updateAdMobAdUnitName(adMobAdUnit: AdMobAdUnit, newName: string): Promise { adMobAdUnit.name = newName; return await this.adMobApi.postRaw('AdUnitService', 'Update', { @@ -871,7 +1210,7 @@ export class Sync { }).then((res: UpdateResponse) => getTranslator(AdUnitTranslator).decode(res[1])); } - async deleteAdMobAdUnits (ids: string[]) { + async deleteAdMobAdUnits(ids: string[]) { return this.adMobApi.post('AdUnitService', 'BulkRemove', ids); } diff --git a/src/lib/translators/admop-ad-unit.translator.ts b/src/lib/translators/admop-ad-unit.translator.ts index 653eb36..72c008b 100644 --- a/src/lib/translators/admop-ad-unit.translator.ts +++ b/src/lib/translators/admop-ad-unit.translator.ts @@ -3,6 +3,7 @@ import {MicrosToUSDTranslator} from './base-translators/micros-to-usd.translator import {ObjectTranslator} from './base-translators/object.translator'; import {AdMobAdUnit, CpmFloorSettings, CpmValue, ManualFloorSettings, RewardsSettings} from './interfaces/admob-ad-unit.interface'; +import {BiddingTranslator} from "./base-translators/bidding.translator"; export class RewardsSettingsTranslator extends ObjectTranslator { @@ -70,9 +71,10 @@ export class AdUnitTranslator extends ObjectTranslator { 17: ['enableRewardsAds', BooleanTranslator], 18: ['rewardsSettings', RewardsSettingsTranslator], 19: 'frequencyCap', - 21: ['googleOptimizedRefreshRate', BooleanTranslator], + 21: 'googleOptimizedRefreshRate', 22: 'usageSummary', - 23: ['cpmFloorSettings', CpmFloorSettingsTranslator] + 23: ['cpmFloorSettings', CpmFloorSettingsTranslator], + 27: ['isThirdPartyBidding', BiddingTranslator], }); } diff --git a/src/lib/translators/base-translators/bidding.translator.ts b/src/lib/translators/base-translators/bidding.translator.ts new file mode 100644 index 0000000..87de8a7 --- /dev/null +++ b/src/lib/translators/base-translators/bidding.translator.ts @@ -0,0 +1,23 @@ +import {ITranslator} from './translator.interface'; + +interface BiddingState { + 1: number +} + +export class BiddingTranslator implements ITranslator { + + decode (v: BiddingState): boolean { + return v[1] === 2; + } + + encode (v: boolean): BiddingState { + if (v === null) { + return this.formatting(1); + } + return v ? this.formatting(2) : this.formatting(1); + } + + formatting (state: number): BiddingState { + return {1: state}; + } +} diff --git a/src/lib/translators/interfaces/admob-ad-unit.interface.ts b/src/lib/translators/interfaces/admob-ad-unit.interface.ts index 4bcd678..bcce935 100644 --- a/src/lib/translators/interfaces/admob-ad-unit.interface.ts +++ b/src/lib/translators/interfaces/admob-ad-unit.interface.ts @@ -16,6 +16,7 @@ export interface AdMobAdUnit { googleOptimizedRefreshRate: boolean, usageSummary: any, cpmFloorSettings: CpmFloorSettings, + isThirdPartyBidding: boolean, } export enum AdMobAdFormat { diff --git a/tsconfig.json b/tsconfig.json index e00b7c9..edca714 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,8 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "resolveJsonModule": true, + "skipLibCheck": true, + "skipDefaultLibCheck": true, "target": "es2018", "module": "commonjs", "jsx": "react", diff --git a/webpack/tsconfig.json b/webpack/tsconfig.json index b151747..6b09370 100644 --- a/webpack/tsconfig.json +++ b/webpack/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { - "esModuleInterop": false + "esModuleInterop": false, + "skipLibCheck": true } }