From ab81f4be4092c207353679dfa5318c97b7eb09af Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Thu, 19 Mar 2020 17:02:37 +0200 Subject: [PATCH] WIP --- .env | 2 +- client/package-lock.json | 1402 +++++++++++++++++ client/src/components/DataTable.js | 6 +- client/src/config/sidebarMenu.js | 4 + .../FinancialStatements.connector.js | 21 +- .../src/connectors/ProfitLossSheet.connect.js | 23 + .../connectors/TrialBalanceSheet.connect.js | 21 + .../FinancialStatements/BalanceSheet.js | 48 - .../BalanceSheet/BalanceSheet.js | 86 + .../BalanceSheet/BalanceSheetHeader.js | 134 +- .../BalanceSheet/BalanceSheetTable.js | 111 +- .../GeneralLedger.js} | 0 .../GeneralLedger/GeneralLedgerHeader.js | 0 .../GeneralLedger/GeneralLedgerTable.js | 0 .../ProfitLossSheet/ProfitLossSheet.js | 78 + .../ProfitLossSheet/ProfitLossSheetHeader.js | 227 +++ .../ProfitLossSheet/ProfitLossSheetTable.js | 0 .../TrialBalanceSheet/TrialBalanceSheet.js | 75 + .../TrialBalanceSheetHeader.js | 113 ++ .../TrialBalanceSheetTable.js | 80 + client/src/routes/dashboard.js | 23 +- .../financialStatements.actions.js | 25 + .../financialStatements.reducer.js | 33 +- .../financialStatements.selectors.js | 91 ++ .../financialStatements.types.js | 1 + client/src/utils.js | 37 +- server/.env | 2 +- server/.env.test | 2 +- server/dist/bundle.js | 322 +++- server/package-lock.json | 117 +- server/package.json | 2 + server/src/app.js | 15 + server/src/database/manager.js | 17 + ...90822214244_create_user_has_roles_table.js | 4 +- ...0190822214247_create_oauth_tokens_table.js | 2 +- .../20190822214302_create_settings_table.js | 2 +- ...0822214905_create_resource_fields_table.js | 2 +- ...20190822214905_create_role_has_accounts.js | 4 +- ...90822214905_create_role_has_permissions.js | 6 +- ...20190822214905_create_views_roles_table.js | 2 +- ...2647_create_accounts_transactions_table.js | 4 +- .../20200105014405_create_expenses_table.js | 6 +- ...0105195823_create_manual_journals_table.js | 2 +- ...00120145342_create_budget_entries_table.js | 4 +- ...e_resource_custom_fields_metadata_table.js | 4 +- server/src/database/seeds/account_types.js | 9 + server/src/http/controllers/Accounting.js | 38 +- server/src/http/controllers/Customers.js | 61 + server/src/http/controllers/Expenses.js | 6 + .../http/controllers/FinancialStatements.js | 362 +++-- server/src/models/Account.js | 5 + .../src/services/Accounting/JournalPoster.js | 7 +- server/src/utils/index.js | 7 + server/tests/routes/accounting.test.js | 119 +- .../tests/routes/financial_statements.test.js | 464 ++++-- server/tests/routes/views.test.js | 2 +- server/tests/testInit.js | 9 +- 57 files changed, 3734 insertions(+), 515 deletions(-) create mode 100644 client/src/connectors/ProfitLossSheet.connect.js create mode 100644 client/src/connectors/TrialBalanceSheet.connect.js delete mode 100644 client/src/containers/Dashboard/FinancialStatements/BalanceSheet.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheet.js rename client/src/containers/Dashboard/FinancialStatements/{TrialBalanceSheet.js => GeneralLedger/GeneralLedger.js} (100%) create mode 100644 client/src/containers/Dashboard/FinancialStatements/GeneralLedger/GeneralLedgerHeader.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/GeneralLedger/GeneralLedgerTable.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheet.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheetHeader.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeader.js create mode 100644 client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.js create mode 100644 client/src/store/financialStatement/financialStatements.selectors.js create mode 100644 server/src/database/manager.js diff --git a/.env b/.env index e5b4a00f9..56cbd483a 100644 --- a/.env +++ b/.env @@ -10,5 +10,5 @@ MAIL_FROM_NAME= DB_CLIENT=mysql DB_HOST=127.0.0.1 DB_USER=root -DB_PASSWORD=123123123 +DB_PASSWORD=root DB_NAME=ratteb diff --git a/client/package-lock.json b/client/package-lock.json index d0046898c..1da8e3346 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -5504,6 +5504,44 @@ } } }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + } + } + }, "expect": { "version": "24.9.0", "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", @@ -5808,6 +5846,11 @@ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", "optional": true }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, "filesize": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.0.1.tgz", @@ -6268,6 +6311,38 @@ "path-is-absolute": "^1.0.0" } }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, "glob-parent": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", @@ -6943,6 +7018,11 @@ "ipaddr.js": "^1.9.0" } }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" + }, "intl-format-cache": { "version": "4.2.21", "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-4.2.21.tgz", @@ -7100,6 +7180,19 @@ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==" }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -7180,6 +7273,16 @@ "isobject": "^3.0.1" } }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -8677,6 +8780,11 @@ "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -8811,6 +8919,11 @@ "object-visit": "^1.0.0" } }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -9251,6 +9364,1215 @@ } } }, + "mocha-webpack": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mocha-webpack/-/mocha-webpack-1.1.0.tgz", + "integrity": "sha512-brmE0tR6G5JbEzZXspJmF/uZm2J/YM/69M3VS6ND76i6wXbebFpE+bQDaehilK8CZanNSsTCcqTTLh1PZuRKJw==", + "requires": { + "babel-runtime": "^6.18.0", + "chalk": "^2.3.0", + "chokidar": "^1.6.1", + "glob-parent": "^3.1.0", + "globby": "^6.1.0", + "interpret": "^1.0.1", + "is-glob": "^4.0.0", + "loader-utils": "^1.1.0", + "lodash": "^4.3.0", + "memory-fs": "^0.4.1", + "nodent-runtime": "^3.0.3", + "normalize-path": "^2.0.1", + "progress": "^2.0.0", + "source-map-support": "^0.5.0", + "strip-ansi": "^4.0.0", + "toposort": "^1.0.0", + "yargs": "^4.8.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "anymatch": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", + "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + }, + "chokidar": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", + "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "requires": { + "anymatch": "^1.3.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "fsevents": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.11.tgz", + "integrity": "sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw==", + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.3", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.4.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.7", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "optional": 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" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "optional": true + } + } + }, + "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==" + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "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=" + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "requires": { + "kind-of": "^6.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "requires": { + "kind-of": "^6.0.0" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "dependencies": { + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "dependencies": { + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "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==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "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=" + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "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" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=" + }, + "which-module": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "requires": { + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", + "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.1", + "which-module": "^1.0.0", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.1" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + } + } + }, "moment": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", @@ -9599,6 +10921,11 @@ } } }, + "nodent-runtime": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/nodent-runtime/-/nodent-runtime-3.2.1.tgz", + "integrity": "sha512-7Ws63oC+215smeKJQCxzrK21VFVlCFBkwl0MOObt0HOpVQXs3u483sAmtkF33nNqZ5rSOQjB76fgyPBmAUrtCA==" + }, "nopt": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", @@ -9801,6 +11128,15 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -10082,6 +11418,32 @@ "safe-buffer": "^5.1.1" } }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -11219,6 +12581,11 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, "pretty-bytes": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.3.0.tgz", @@ -11422,6 +12789,28 @@ "performance-now": "^2.1.0" } }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + } + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -11952,6 +13341,14 @@ "private": "^0.1.6" } }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -16104,6 +17501,11 @@ } } }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", diff --git a/client/src/components/DataTable.js b/client/src/components/DataTable.js index 16c984034..e8e25e85e 100644 --- a/client/src/components/DataTable.js +++ b/client/src/components/DataTable.js @@ -1,5 +1,5 @@ import React from 'react'; -import { useTable, usePagination } from 'react-table' +import { useTable, useExpanded, usePagination } from 'react-table' export default function DataTable({ columns, @@ -32,8 +32,10 @@ export default function DataTable({ // This means we'll also have to provide our own // pageCount. // pageCount: controlledPageCount, + getSubRows: row => row.children, }, - usePagination + useExpanded, + usePagination, ); return ( diff --git a/client/src/config/sidebarMenu.js b/client/src/config/sidebarMenu.js index bee0a5a8d..8e215cc65 100644 --- a/client/src/config/sidebarMenu.js +++ b/client/src/config/sidebarMenu.js @@ -116,6 +116,10 @@ export default [ text: 'Balance Sheet', href: '/dashboard/accounting/balance-sheet', }, + { + text: 'Trial Balance Sheet', + href: '/dashboard/accounting/trial-balance-sheet', + }, { divider: true, }, diff --git a/client/src/connectors/FinancialStatements.connector.js b/client/src/connectors/FinancialStatements.connector.js index 1a40ccc2f..1791e25de 100644 --- a/client/src/connectors/FinancialStatements.connector.js +++ b/client/src/connectors/FinancialStatements.connector.js @@ -3,10 +3,29 @@ import { fetchGeneralLedger, fetchBalanceSheet, } from 'store/financialStatement/financialStatements.actions'; -import t from 'store/types'; +import { + getBalanceSheetByQuery, + getBalanceSheetColumns, + getBalanceSheetIndexByQuery, + getBalanceSheetByIndex, + getBalanceSheetAssetsAccounts, + getBalanceSheetLiabilitiesAccounts, + getBalanceSheetQuery, +} from 'store/financialStatement/financialStatements.selectors'; export const mapStateToProps = (state, props) => ({ generalLedeger: state.financialStatements.generalLedger, + balanceSheets: state.financialStatements.balanceSheets, + + getBalanceSheetByQuery: (query) => getBalanceSheetByQuery(state.financialStatements.balanceSheets, query), + getBalanceSheetColumns: (sheetIndex) => getBalanceSheetColumns(state.financialStatements.balanceSheets, sheetIndex), + getBalanceSheetIndexByQuery: (query) => getBalanceSheetIndexByQuery(state.financialStatements.balanceSheets, query), + getBalanceSheetByIndex: (sheetIndex) => getBalanceSheetByIndex(state.financialStatements.balanceSheets, sheetIndex), + + getBalanceSheetAssetsAccounts: (sheetIndex) => getBalanceSheetAssetsAccounts(state.financialStatements.balanceSheets, sheetIndex), + getBalanceSheetLiabilitiesAccounts: (sheetIndex) => getBalanceSheetLiabilitiesAccounts(state.financialStatements.balanceSheets, sheetIndex), + + getBalanceSheetQuery: (sheetIndex) => getBalanceSheetQuery(state.financialStatements.balanceSheets, sheetIndex), }); export const mapDispatchToProps = (dispatch) => ({ diff --git a/client/src/connectors/ProfitLossSheet.connect.js b/client/src/connectors/ProfitLossSheet.connect.js new file mode 100644 index 000000000..2624086f3 --- /dev/null +++ b/client/src/connectors/ProfitLossSheet.connect.js @@ -0,0 +1,23 @@ +import {connect} from 'react-redux'; +import { + fetchProfitLossSheet, +} from 'store/financialStatement/financialStatements.actions'; +import { + getProfitLossSheetIndex, + getProfitLossSheet, + getProfitLossSheetColumns, + getProfitLossSheetAccounts, +} from 'store/financialStatement/financialStatements.selectors'; + +export const mapStateToProps = (state, props) => ({ + getProfitLossSheetIndex: (query) => getProfitLossSheetIndex(state.financialStatements.profitLossSheets, query), + getProfitLossSheet: (index) => getProfitLossSheet(state.financialStatements.profitLossSheets, index), + getProfitLossSheetColumns: (index) => getProfitLossSheetColumns(state.financialStatements.profitLossSheets, index), + getProfitLossSheetAccounts: (index) => getProfitLossSheetAccounts(state.financialStatements.profitLossSheets, index), +}); + +export const mapDispatchToProps = (dispatch) => ({ + fetchProfitLossSheet: (query = {}) => dispatch(fetchProfitLossSheet({ query })), +}); + +export default connect(mapStateToProps, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/connectors/TrialBalanceSheet.connect.js b/client/src/connectors/TrialBalanceSheet.connect.js new file mode 100644 index 000000000..493bc4003 --- /dev/null +++ b/client/src/connectors/TrialBalanceSheet.connect.js @@ -0,0 +1,21 @@ +import {connect} from 'react-redux'; +import { + fetchTrialBalanceSheet +} from 'store/financialStatement/financialStatements.actions'; +import { + getTrialBalanceSheetIndex, + getTrialBalanceAccounts, + getTrialBalanceQuery, +} from 'store/financialStatement/financialStatements.selectors'; + +export const mapStateToProps = (state, props) => ({ + getTrialBalanceSheetIndex: (query) => getTrialBalanceSheetIndex(state.financialStatements.trialBalanceSheets, query), + getTrialBalanceAccounts: (sheetIndex) => getTrialBalanceAccounts(state.financialStatements.trialBalanceSheets, sheetIndex), + getTrialBalanceQuery: (sheetIndex) => getTrialBalanceQuery(state.financialStatements.trialBalanceSheets, sheetIndex), +}); + +export const mapDispatchToProps = (dispatch) => ({ + fetchTrialBalanceSheet: (query = {}) => dispatch(fetchTrialBalanceSheet({ query })), +}); + +export default connect(mapStateToProps, mapDispatchToProps); \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/BalanceSheet.js b/client/src/containers/Dashboard/FinancialStatements/BalanceSheet.js deleted file mode 100644 index b4c782cc2..000000000 --- a/client/src/containers/Dashboard/FinancialStatements/BalanceSheet.js +++ /dev/null @@ -1,48 +0,0 @@ -import React, {useEffect} from 'react'; -import DashboardConnect from 'connectors/Dashboard.connector'; -import {compose} from 'utils'; -import useAsync from 'hooks/async'; -import FinancialStatementConnect from 'connectors/FinancialStatements.connector'; -import {useIntl} from 'react-intl'; -import BalanceSheetHeader from './BalanceSheet/BalanceSheetHeader'; -import LoadingIndicator from 'components/LoadingIndicator'; -import BalanceSheetTable from './BalanceSheet/BalanceSheetTable'; - -function BalanceSheet({ - fetchBalanceSheet, - changePageTitle, -}) { - const intl = useIntl(); - const handleDateChange = () => {}; - - const fetchHook = useAsync(async () => { - await Promise.all([ - fetchBalanceSheet({}), - ]); - }); - - useEffect(() => { - changePageTitle('Balance Sheet'); - }, []); - - const handleFilterSubmit = (filter) => { - - }; - - return ( -
- - -
- - - -
-
- ); -} - -export default compose( - DashboardConnect, - FinancialStatementConnect, -)(BalanceSheet); \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheet.js b/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheet.js new file mode 100644 index 000000000..970d8c235 --- /dev/null +++ b/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheet.js @@ -0,0 +1,86 @@ +import React, {useEffect, useMemo, useState} from 'react'; +import DashboardConnect from 'connectors/Dashboard.connector'; +import {compose} from 'utils'; +import useAsync from 'hooks/async'; +import FinancialStatementConnect from 'connectors/FinancialStatements.connector'; +import {useIntl} from 'react-intl'; +import BalanceSheetHeader from './BalanceSheetHeader'; +import LoadingIndicator from 'components/LoadingIndicator'; +import BalanceSheetTable from './BalanceSheetTable'; +import moment from 'moment'; + +function BalanceSheet({ + fetchBalanceSheet, + changePageTitle, + getBalanceSheetByQuery, + getBalanceSheetIndexByQuery, + getBalanceSheetByIndex, + balanceSheets +}) { + const intl = useIntl(); + const [filter, setFilter] = useState({ + from_date: moment().startOf('year').format('YYYY-MM-DD'), + to_date: moment().endOf('year').format('YYYY-MM-DD'), + basis: 'cash', + display_columns_by: 'total', + none_zero: false, + }); + + const [reload, setReload] = useState(false); + + const fetchHook = useAsync(async () => { + await Promise.all([ + fetchBalanceSheet(filter), + ]); + setReload(false); + }); + + useEffect(() => { + if (!reload) { return; } + fetchHook.execute(); + }, [reload]); + + useEffect(() => { + changePageTitle('Balance Sheet'); + }, []); + + // Retrieve balance sheet index by the given filter query. + const balanceSheetIndex = useMemo(() => { + return getBalanceSheetIndexByQuery(filter); + }, [filter, balanceSheets]); + + // Retreive balance sheet by the given sheet index. + const balanceSheet = useMemo(() => { + return getBalanceSheetByIndex(balanceSheetIndex); + }, [balanceSheetIndex, balanceSheets]); + + // Handle re-fetch balance sheet after filter change. + const handleFilterSubmit = (filter) => { + setFilter({ + ...filter, + from_date: moment(filter.from_date).format('YYYY-MM-DD'), + to_date: moment(filter.to_date).format('YYYY-MM-DD'), + }); + setReload(true); + }; + return ( +
+ + +
+ + + +
+
+ ); +} + +export default compose( + DashboardConnect, + FinancialStatementConnect, +)(BalanceSheet); \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheetHeader.js b/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheetHeader.js index cfa083112..595655f31 100644 --- a/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheetHeader.js +++ b/client/src/containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheetHeader.js @@ -1,4 +1,4 @@ -import React, {useState, useMemo} from 'react'; +import React, {useState, useMemo, useEffect} from 'react'; import FinancialStatementHeader from 'containers/Dashboard/FinancialStatements/FinancialStatementHeader'; import {Row, Col} from 'react-grid-system'; import { @@ -10,44 +10,53 @@ import { Radio, HTMLSelect, Intent, + Popover, } from "@blueprintjs/core"; import {Select} from '@blueprintjs/select'; import {DateInput} from '@blueprintjs/datetime'; import {useIntl} from 'react-intl'; -import {momentFormatter, handleStringChange} from 'utils'; +import { + momentFormatter, + handleStringChange, + parseDateRangeQuery, +} from 'utils'; import moment from 'moment'; export default function BalanceSheetHeader({ onSubmitFilter, + pageFilter, }) { const intl = useIntl(); - const [filter, setFilter] = useState({ - from_date: null, - to_date: null, - accounting_basis: 'cash', - display_columns_by: 'total', - }); - - const setFilterByName = (name, value) => { - setFilter({ - ...filter, - [name]: value, - }); - }; - - const handleFieldChange = (event) => { - setFilterByName(event.target.name, event.target.value); - }; - const displayColumnsByOptions = [ {key: 'total', name: 'Total'}, {key: 'year', name: 'Year'}, {key: 'month', name: 'Month'}, {key: 'week', name: 'Week'}, {key: 'day', name: 'Day'}, - {key: 'quarter', name: 'Quarter'} + {key: 'quarter', name: 'Quarter'}, ]; + const [filter, setFilter] = useState({ + ...pageFilter, + from_date: moment(pageFilter.from_date).toDate(), + to_date: moment(pageFilter.to_date).toDate() + }); + + const setFilterByKey = (name, value) => { + setFilter({ ...filter, [name]: value }); + }; + + const [reportDateRange, setReportDateRange] = useState('this_year'); + + useEffect(() => { + if (reportDateRange === 'custom') { return; } + const dateRange = parseDateRangeQuery(reportDateRange); + + if (dateRange) { + setFilter((filter) => ({ ...filter, ...dateRange, })); + } + }, [reportDateRange]) + const selectedDisplayColumnOpt = useMemo(() => { return displayColumnsByOptions.find(o => o.key === filter.display_columns_by); }, [filter.display_columns_by, displayColumnsByOptions]); @@ -56,31 +65,56 @@ export default function BalanceSheetHeader({ const accountTypeItem = (item, { handleClick, modifiers, query }) => { return (); }; - + + // Handle item select of `display columns by` field. const onItemSelectDisplayColumns = (item) => { - setFilterByName('display_columns_by', item.key); + setFilterByKey('display_columns_by', item.key); }; + // Handle any date change. const handleDateChange = (name) => (date) => { - setFilterByName(name, moment(date).format('YYYY-MM-DD')); + setReportDateRange('custom'); + setFilterByKey(name, date); }; + // handle submit filter submit button. const handleSubmitClick = () => { onSubmitFilter(filter); }; - const dateRangeOptions = [ {value: 'today', label: 'Today', }, {value: 'this_week', label: 'This Week'}, {value: 'this_month', label: 'This Month'}, {value: 'this_quarter', label: 'This Quarter'}, {value: 'this_year', label: 'This Year'}, + {value: 'custom', label: 'Custom Range'}, ]; + const [activeRowsColumns, setActiveRowsColumns] = useState(false); + + const onClickActiveRowsColumnsBtn = () => { + setActiveRowsColumns(!activeRowsColumns); + }; + + const activeRowsColumnsPopover = ( +
+
Columns
+ { + setFilterByKey('none_zero', value); + })} + > + + + +
+ ); return ( - + + options={dateRangeOptions} + value={reportDateRange} + onChange={(event) => setReportDateRange(event.target.value)} /> - + - + @@ -124,11 +160,11 @@ export default function BalanceSheetHeader({ - + + inline={false}> } + filterable={false} + itemRenderer={accountTypeItem} + popoverProps={{ minimal: true }} + onItemSelect={onItemSelectDisplayColumns}> + + + + + ) +} \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.js b/client/src/containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheetTable.js new file mode 100644 index 000000000..e69de29bb diff --git a/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.js b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.js new file mode 100644 index 000000000..bf54bd2bb --- /dev/null +++ b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet.js @@ -0,0 +1,75 @@ +import React, { useEffect, useState, useMemo } from 'react'; +import TrialBalanceSheetHeader from "./TrialBalanceSheetHeader"; +import LoadingIndicator from 'components/LoadingIndicator'; +import TrialBalanceSheetTable from './TrialBalanceSheetTable'; +import { useAsync } from 'react-use'; +import moment from 'moment'; +import {compose} from 'utils'; +import TrialBalanceSheetConnect from 'connectors/TrialBalanceSheet.connect'; +import DashboardConnect from 'connectors/Dashboard.connector'; + +function TrialBalanceSheet({ + changePageTitle, + fetchTrialBalanceSheet, + getTrialBalanceSheetIndex, + getTrialBalanceAccounts, +}) { + const [filter, setFilter] = useState({ + from_date: moment().startOf('year').format('YYYY-MM-DD'), + to_date: moment().endOf('year').format('YYYY-MM-DD'), + basis: 'cash', + none_zero: false, + }); + const [reload, setReload] = useState(false); + + const fetchHook = useAsync(async () => { + await Promise.all([ + fetchTrialBalanceSheet(), + ]); + }); + + // Retrieve balance sheet index by the given filter query. + const trialBalanceSheetIndex = useMemo(() => { + return getTrialBalanceSheetIndex(filter); + }, [getTrialBalanceSheetIndex, filter]); + + // Retrieve balance sheet accounts bu the given sheet index. + const trialBalanceAccounts = useMemo(() => { + return getTrialBalanceAccounts(trialBalanceSheetIndex); + }, [trialBalanceSheetIndex]); + + // Change page title of the dashboard. + useEffect(() => { + changePageTitle('Trial Balance Sheet'); + }, []); + + const handleFilterSubmit = (filter) => { + setFilter({ + ...filter, + from_date: moment(filter.from_date).format('YYYY-MM-DD'), + to_date: moment(filter.to_date).format('YYYY-MM-DD'), + }); + setReload(true); + }; + + return ( +
+ + +
+ + + +
+
+ ) +} + +export default compose( + DashboardConnect, + TrialBalanceSheetConnect, +)(TrialBalanceSheet); \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeader.js b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeader.js new file mode 100644 index 000000000..257a49a23 --- /dev/null +++ b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetHeader.js @@ -0,0 +1,113 @@ +import React, {useState} from 'react'; +import FinancialStatementHeader from 'containers/Dashboard/FinancialStatements/FinancialStatementHeader'; +import {Row, Col} from 'react-grid-system'; +import { + Button, + FormGroup, + Position, + MenuItem, + RadioGroup, + Radio, + HTMLSelect, + Intent, + Popover, +} from "@blueprintjs/core"; +import {DateInput} from '@blueprintjs/datetime'; +import moment from 'moment'; +import {momentFormatter} from 'utils'; +import {useIntl} from 'react-intl'; + +export default function TrialBalanceSheetHeader({ + pageFilter, + onSubmitFilter, +}) { + const intl = useIntl(); + const [filter, setFilter] = useState({ + ...pageFilter, + from_date: moment(pageFilter.from_date).toDate(), + to_date: moment(pageFilter.to_date).toDate() + }) + + const setFilterByKey = (name, value) => { + setFilter({ ...filter, [name]: value }); + }; + + const [reportDateRange, setReportDateRange] = useState('this_year'); + + const dateRangeOptions = [ + {value: 'today', label: 'Today', }, + {value: 'this_week', label: 'This Week'}, + {value: 'this_month', label: 'This Month'}, + {value: 'this_quarter', label: 'This Quarter'}, + {value: 'this_year', label: 'This Year'}, + {value: 'custom', label: 'Custom Range'}, + ]; + + const handleDateChange = (name) => (date) => { + setReportDateRange('custom'); + setFilterByKey(name, date); + }; + + const handleSubmitClick = () => { onSubmitFilter(filter); }; + + return ( + + + + + + setReportDateRange(event.target.value)} /> + + + + + + + + + + + + + + + + + + + + + + + + + ); +} \ No newline at end of file diff --git a/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.js b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.js new file mode 100644 index 000000000..46c5379b2 --- /dev/null +++ b/client/src/containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheetTable.js @@ -0,0 +1,80 @@ +import React, {useEffect, useState, useMemo} from 'react'; +import FinancialSheet from 'components/FinancialSheet'; +import DataTable from 'components/DataTable'; + + +export default function TrialBalanceSheetTable({ + trialBalanceSheetAccounts, + trialBalanceSheetIndex, +}) { + const [data, setData] = useState([]); + + const columns = useMemo(() => [ + { + // Build our expander column + id: 'expander', // Make sure it has an ID + Header: ({ + getToggleAllRowsExpandedProps, + isAllRowsExpanded + }) => ( + + {isAllRowsExpanded ? '👇' : '👉'} + + ), + Cell: ({ row }) => + // Use the row.canExpand and row.getToggleRowExpandedProps prop getter + // to build the toggle for expanding a row + row.canExpand ? ( + + {row.isExpanded ? '👇' : '👉'} + + ) : null, + }, + { + Header: 'Account Name', + accessor: 'name', + className: "actions", + }, + { + Header: 'Code', + accessor: 'code', + className: "note", + }, + { + Header: 'Credit', + accessor: 'credit', + className: 'credit', + }, + { + Header: 'debit', + accessor: 'debit', + className: 'debit', + }, + { + Header: 'Balance', + accessor: 'balance', + className: 'balance', + } + ], []); + + return ( + + + + + ); +} \ No newline at end of file diff --git a/client/src/routes/dashboard.js b/client/src/routes/dashboard.js index db9d76079..67c08d661 100644 --- a/client/src/routes/dashboard.js +++ b/client/src/routes/dashboard.js @@ -75,18 +75,25 @@ export default [ loader: () => import('containers/Dashboard/FinancialStatements/LedgerSheet') }), }, - { - path: `${BASE_URL}/accounting/trial-balance`, - name: 'dashboard.accounting.trial.balance', - component: LazyLoader({ - loader: () => import('containers/Dashboard/FinancialStatements/TrialBalanceSheet') - }), - }, { path: `${BASE_URL}/accounting/balance-sheet`, name: 'dashboard.accounting.balance.sheet', component: LazyLoader({ - loader: () => import('containers/Dashboard/FinancialStatements/BalanceSheet') + loader: () => import('containers/Dashboard/FinancialStatements/BalanceSheet/BalanceSheet') + }), + }, + { + path: `${BASE_URL}/accounting/trial-balance-sheet`, + name: 'dashboard.accounting.trial.balance', + component: LazyLoader({ + loader: () => import('containers/Dashboard/FinancialStatements/TrialBalanceSheet/TrialBalanceSheet') + }), + }, + { + path: `${BASE_URL}/accounting/profit-loss-sheet`, + name: 'dashboard.accounting.profit.loss.sheet', + component: LazyLoader({ + loader: () => import('containers/Dashboard/FinancialStatements/ProfitLossSheet/ProfitLossSheet') }), } ]; \ No newline at end of file diff --git a/client/src/store/financialStatement/financialStatements.actions.js b/client/src/store/financialStatement/financialStatements.actions.js index c2822b390..32673c09e 100644 --- a/client/src/store/financialStatement/financialStatements.actions.js +++ b/client/src/store/financialStatement/financialStatements.actions.js @@ -19,8 +19,33 @@ export const fetchBalanceSheet = ({ query }) => { dispatch({ type: t.BALANCE_SHEET_STATEMENT_SET, data: response.data, + query: query, }); resolve(response); }).catch((error) => { reject(error); }); }); +}; + +export const fetchTrialBalanceSheet = ({ query }) => { + return (dispatch) => new Promise((resolve, reject) => { + ApiService.get('/financial_statements/trial_balance_sheet').then((response) => { + dispatch({ + type: t.TRAIL_BALANCE_STATEMENT_SET, + data: response.data, + }); + resolve(response.data); + }).catch((error) => { reject(error); }) + }) +}; + +export const fetchProfitLossSheet = ({ query }) => { + return (dispatch) => new Promise((resolve, reject) => { + ApiService.get('/financial_statements/profit_loss_sheet').then((response) => { + dispatch({ + type: t.PROFIT_LOSS_STATEMENT_SET, + data: response.data, + }); + resolve(response.data); + }).catch((error) => { reject(error); }); + }) }; \ No newline at end of file diff --git a/client/src/store/financialStatement/financialStatements.reducer.js b/client/src/store/financialStatement/financialStatements.reducer.js index afce617a9..fbbb64744 100644 --- a/client/src/store/financialStatement/financialStatements.reducer.js +++ b/client/src/store/financialStatement/financialStatements.reducer.js @@ -1,14 +1,41 @@ import { createReducer } from '@reduxjs/toolkit'; import t from 'store/types'; +import {getBalanceSheetIndexByQuery, getTrialBalanceSheetIndex} from './financialStatements.selectors'; +import { actionComplete } from '@syncfusion/ej2-react-grids'; const initialState = { - balanceSheet: [], + balanceSheets: [], + trialBalanceSheets: [], generalLedger: [], - trialBalance: [], }; export default createReducer(initialState, { [t.BALANCE_SHEET_STATEMENT_SET]: (state, action) => { - state.balanceSheet.push(action.data); + const index = getBalanceSheetIndexByQuery(state.balanceSheets, action.query); + + const balanceSheet = { + balances: action.data.balance_sheet, + columns: Object.values(action.data.columns), + query: action.data.query, + }; + if (index !== -1) { + state.balanceSheets[index] = balanceSheet; + } else { + state.balanceSheets.push(balanceSheet); + } }, + + [t.TRAIL_BALANCE_STATEMENT_SET]: (state, action) => { + const index = getTrialBalanceSheetIndex(state.trialBalanceSheets, action.query); + + const trailBalanceSheet = { + accounts: action.data.accounts, + query: action.data.query, + }; + if (index !== -1) { + state.trialBalanceSheets[index] = trailBalanceSheet; + } else { + state.trailBalanceSheet.push(trailBalanceSheet); + } + } }); \ No newline at end of file diff --git a/client/src/store/financialStatement/financialStatements.selectors.js b/client/src/store/financialStatement/financialStatements.selectors.js new file mode 100644 index 000000000..d0ba0ec59 --- /dev/null +++ b/client/src/store/financialStatement/financialStatements.selectors.js @@ -0,0 +1,91 @@ +import {getObjectDiff} from 'utils'; + + +// Balance Sheet. +export const getBalanceSheetByQuery = (balanceSheets, query) => { + return balanceSheets.find(balanceSheet => { + return getObjectDiff(query, balanceSheet.query).length === 0; + }); +}; + +export const getBalanceSheetIndexByQuery = (balanceSheets, query) => { + return balanceSheets.findIndex((balanceSheet) => { + return getObjectDiff(query, balanceSheet.query).length === 0; + }); +}; + +export const getBalanceSheetByIndex = (balanceSheets, sheetIndex) => { + return balanceSheets[sheetIndex]; +}; + +export const getBalanceSheetQuery = (balanceSheets, sheetIndex) => { + if (typeof balanceSheets[sheetIndex] === 'object') { + return balanceSheets[sheetIndex].query || {}; + } + return {}; +}; + +export const getBalanceSheetAssetsAccounts = (balanceSheets, sheetIndex) => { + if (typeof balanceSheets[sheetIndex] === 'object') { + return balanceSheets[sheetIndex].balances.assets.accounts || []; + } + return []; +}; + +export const getBalanceSheetLiabilitiesAccounts = (balanceSheets, sheetIndex) => { + if (typeof balanceSheets[sheetIndex] === 'object') { + return balanceSheets[sheetIndex].balances.liabilities_equity.accounts || []; + } + return []; +}; + +export const getBalanceSheetColumns = (balanceSheets, sheetIndex) => { + if (typeof balanceSheets[sheetIndex] === 'object') { + return balanceSheets[sheetIndex].columns; + } + return []; +}; + + +// Trial Balance Sheet. +export const getTrialBalanceSheetIndex = (trialBalanceSheets, query) => { + return trialBalanceSheets.find((trialBalanceSheet) => { + return getObjectDiff(query, trialBalanceSheet.query).length === 0; + }); +}; + +export const getTrialBalanceAccounts = (trialBalanceSheets, sheetIndex) => { + if (typeof trialBalanceSheets[sheetIndex] === 'object') { + return trialBalanceSheets[sheetIndex].accounts; + } + return []; +}; + +export const getTrialBalanceQuery = (trialBalanceSheets, sheetIndex) => { + if (typeof trialBalanceSheets[sheetIndex] === 'object') { + return trialBalanceSheets[sheetIndex].query; + } + return []; +}; + +// Profit/Loss Sheet selectors. +export const getProfitLossSheetIndex = (profitLossSheets, query) => { + return profitLossSheets.find((profitLossSheet) => { + return getObjectDiff(query, profitLossSheet.query).length === 0; + }); +} + +export const getProfitLossSheet = (profitLossSheets, index) => { + return (typeof profitLossSheets[index] !== 'undefined') ? + profitLossSheets[index] : null; +}; + +export const getProfitLossSheetColumns = (profitLossSheets, index) => { + const sheet = getProfitLossSheet(profitLossSheets, index); + return (sheet) ? sheet.columns : []; +}; + +export const getProfitLossSheetAccounts = (profitLossSheets, index) => { + const sheet = getProfitLossSheet(profitLossSheets, index); + return (sheet) ? sheet.accounts : []; +}; \ No newline at end of file diff --git a/client/src/store/financialStatement/financialStatements.types.js b/client/src/store/financialStatement/financialStatements.types.js index d73a21887..8cd91f95c 100644 --- a/client/src/store/financialStatement/financialStatements.types.js +++ b/client/src/store/financialStatement/financialStatements.types.js @@ -3,4 +3,5 @@ export default { GENERAL_LEDGER_STATEMENT_SET: 'GENERAL_LEDGER_STATEMENT_SET', BALANCE_SHEET_STATEMENT_SET: 'BALANCE_SHEET_STATEMENT_SET', + TRAIL_BALANCE_STATEMENT_SET: 'TRAIL_BALANCE_STATEMENT_SET', } \ No newline at end of file diff --git a/client/src/utils.js b/client/src/utils.js index c993bab14..8f6f0936b 100644 --- a/client/src/utils.js +++ b/client/src/utils.js @@ -1,4 +1,5 @@ import moment from 'moment'; +import _ from 'lodash'; export function removeEmptyFromObject(obj) { obj = Object.assign({}, obj); @@ -76,4 +77,38 @@ export const objectKeysTransform = (obj, transform) => { }; export const compose = (...funcs) => - funcs.reduce((a, b) => (...args) => a(b(...args)), arg => arg); \ No newline at end of file + funcs.reduce((a, b) => (...args) => a(b(...args)), arg => arg); + +export const getObjectDiff = (a, b) => { + return _.reduce(a, (result, value, key) => { + return _.isEqual(value, b[key]) ? + result : result.concat(key); + }, []); +} + +export const parseDateRangeQuery = (keyword) => { + const queries = { + 'today': { + range: 'day', + }, + 'this_year': { + range: 'year', + }, + 'this_month': { + range: 'month' + }, + 'this_week': { + range: 'week' + } + }; + + if (typeof queries[keyword] === 'undefined') { + throw new Error(`The date range query ${keyword} is not defined.`); + } + const query = queries[keyword]; + + return { + from_date: moment().startOf(query.range).toDate(), + to_date: moment().endOf(query.range).toDate(), + }; +}; \ No newline at end of file diff --git a/server/.env b/server/.env index e5b4a00f9..56cbd483a 100644 --- a/server/.env +++ b/server/.env @@ -10,5 +10,5 @@ MAIL_FROM_NAME= DB_CLIENT=mysql DB_HOST=127.0.0.1 DB_USER=root -DB_PASSWORD=123123123 +DB_PASSWORD=root DB_NAME=ratteb diff --git a/server/.env.test b/server/.env.test index bfeba6ac6..4963c9f58 100644 --- a/server/.env.test +++ b/server/.env.test @@ -10,7 +10,7 @@ MAIL_FROM_NAME= DB_CLIENT=mysql DB_HOST=127.0.0.1 DB_USER=root -DB_PASSWORD=123123123 +DB_PASSWORD=root DB_NAME=ratteb JWT_SECRET_KEY=ahmedmohamked diff --git a/server/dist/bundle.js b/server/dist/bundle.js index 5ba6242b0..50daa6324 100644 --- a/server/dist/bundle.js +++ b/server/dist/bundle.js @@ -181,9 +181,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var helmet__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(helmet__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var express_boom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! express-boom */ "express-boom"); /* harmony import */ var express_boom__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(express_boom__WEBPACK_IMPORTED_MODULE_2__); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../config */ "./config/index.js"); -/* harmony import */ var _http__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/http */ "./src/http/index.js"); -/* harmony import */ var _models__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/models */ "./src/models/index.js"); +/* harmony import */ var i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! i18n */ "i18n"); +/* harmony import */ var i18n__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(i18n__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../config */ "./config/index.js"); +/* harmony import */ var _http__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/http */ "./src/http/index.js"); +/* harmony import */ var _models__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/models */ "./src/models/index.js"); + @@ -193,6 +196,20 @@ __webpack_require__.r(__webpack_exports__); var app = express__WEBPACK_IMPORTED_MODULE_0___default()(); +// i18n.configure({ +// // setup some locales - other locales default to en silently +// locales: ['en'], + +// // sets a custom cookie name to parse locale settings from. +// cookie: 'yourcookiename', + +// // where to store json files - defaults to './locales' +// directory: `${__dirname}/resources/locale`, +// }); + +// i18n init parses req for language headers, cookies, etc. +// app.use(i18n.init); + // Express configuration app.set('port', process.env.PORT || 3000); @@ -200,7 +217,7 @@ app.use(helmet__WEBPACK_IMPORTED_MODULE_1___default()()); app.use(express_boom__WEBPACK_IMPORTED_MODULE_2___default()()); app.use(express__WEBPACK_IMPORTED_MODULE_0___default.a.json()); -Object(_http__WEBPACK_IMPORTED_MODULE_4__["default"])(app); +Object(_http__WEBPACK_IMPORTED_MODULE_5__["default"])(app); /* harmony default export */ __webpack_exports__["default"] = (app); @@ -726,12 +743,14 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var express__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(express__WEBPACK_IMPORTED_MODULE_4__); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lodash */ "lodash"); /* harmony import */ var lodash__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(lodash__WEBPACK_IMPORTED_MODULE_5__); -/* harmony import */ var _models_Account__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/models/Account */ "./src/models/Account.js"); -/* harmony import */ var _http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/http/middleware/asyncMiddleware */ "./src/http/middleware/asyncMiddleware.js"); -/* harmony import */ var _http_middleware_jwtAuth__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/http/middleware/jwtAuth */ "./src/http/middleware/jwtAuth.js"); -/* harmony import */ var _services_Accounting_JournalPoster__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/services/Accounting/JournalPoster */ "./src/services/Accounting/JournalPoster.js"); -/* harmony import */ var _services_Accounting_JournalEntry__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/services/Accounting/JournalEntry */ "./src/services/Accounting/JournalEntry.js"); -/* harmony import */ var _models_JournalEntry__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/models/JournalEntry */ "./src/models/JournalEntry.js"); +/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! moment */ "moment"); +/* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(moment__WEBPACK_IMPORTED_MODULE_6__); +/* harmony import */ var _models_Account__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/models/Account */ "./src/models/Account.js"); +/* harmony import */ var _http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/http/middleware/asyncMiddleware */ "./src/http/middleware/asyncMiddleware.js"); +/* harmony import */ var _http_middleware_jwtAuth__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/http/middleware/jwtAuth */ "./src/http/middleware/jwtAuth.js"); +/* harmony import */ var _services_Accounting_JournalPoster__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/services/Accounting/JournalPoster */ "./src/services/Accounting/JournalPoster.js"); +/* harmony import */ var _services_Accounting_JournalEntry__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @/services/Accounting/JournalEntry */ "./src/services/Accounting/JournalEntry.js"); +/* harmony import */ var _models_JournalEntry__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @/models/JournalEntry */ "./src/models/JournalEntry.js"); function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Object.getOwnPropertySymbols) {var symbols = Object.getOwnPropertySymbols(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return Object.getOwnPropertyDescriptor(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function _objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {ownKeys(source, true).forEach(function (key) {_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_1___default()(target, key, source[key]);});} else if (Object.getOwnPropertyDescriptors) {Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));} else {ownKeys(source).forEach(function (key) {Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));});}}return target;} @@ -742,25 +761,26 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj + /* harmony default export */ __webpack_exports__["default"] = ({ /** * Router constructor. */ router: function router() { var router = express__WEBPACK_IMPORTED_MODULE_4___default.a.Router(); - router.use(_http_middleware_jwtAuth__WEBPACK_IMPORTED_MODULE_8__["default"]); + router.use(_http_middleware_jwtAuth__WEBPACK_IMPORTED_MODULE_9__["default"]); router.post('/make-journal-entries', this.makeJournalEntries.validation, - Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_7__["default"])(this.makeJournalEntries.handler)); + Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_8__["default"])(this.makeJournalEntries.handler)); router.post('/recurring-journal-entries', this.recurringJournalEntries.validation, - Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_7__["default"])(this.recurringJournalEntries.handler)); + Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_8__["default"])(this.recurringJournalEntries.handler)); router.post('quick-journal-entries', this.quickJournalEntries.validation, - Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_7__["default"])(this.quickJournalEntries.handler)); + Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_8__["default"])(this.quickJournalEntries.handler)); return router; }, @@ -772,13 +792,14 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj validation: [ Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('date').isISO8601(), Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('reference').exists(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('memo').optional().trim().escape(), Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries').isArray({ min: 1 }), - Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.credit').isNumeric().toInt(), - Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.debit').isNumeric().toInt(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.credit').optional({ nullable: true }).isNumeric().toInt(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.debit').optional({ nullable: true }).isNumeric().toInt(), Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.account_id').isNumeric().toInt(), Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('entries.*.note').optional()], - handler: function () {var _handler = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee(req, res) {var validationErrors, form, errorReasons, totalCredit, totalDebit, accountsIds, accounts, storedAccountsIds, journalReference, journalPoster;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0: + handler: function () {var _handler = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_2___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee(req, res) {var validationErrors, form, totalCredit, totalDebit, user, errorReasons, entries, formattedDate, accountsIds, accounts, storedAccountsIds, journalReference, manualJournal, journalPoster;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0: validationErrors = Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["validationResult"])(req);if ( validationErrors.isEmpty()) {_context.next = 3;break;}return _context.abrupt("return", @@ -790,11 +811,16 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj date: new Date() }, req.body); - errorReasons = []; + totalCredit = 0; totalDebit = 0; - form.entries.forEach(function (entry) { + user = req.user; + errorReasons = []; + entries = form.entries.filter(function (entry) {return entry.credit || entry.debit;}); + formattedDate = moment__WEBPACK_IMPORTED_MODULE_6___default()(form.date).format('YYYY-MM-DD'); + + entries.forEach(function (entry) { if (entry.credit > 0) { totalCredit += entry.credit; } @@ -802,6 +828,7 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj totalDebit += entry.debit; } }); + if (totalCredit <= 0 || totalDebit <= 0) { errorReasons.push({ type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', @@ -811,36 +838,48 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj if (totalCredit !== totalDebit) { errorReasons.push({ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 100 }); } - accountsIds = form.entries.map(function (entry) {return entry.account_id;});_context.next = 13;return ( - _models_Account__WEBPACK_IMPORTED_MODULE_6__["default"].query().whereIn('id', accountsIds). - withGraphFetched('type'));case 13:accounts = _context.sent; + accountsIds = entries.map(function (entry) {return entry.account_id;});_context.next = 16;return ( + _models_Account__WEBPACK_IMPORTED_MODULE_7__["default"].query().whereIn('id', accountsIds). + withGraphFetched('type'));case 16:accounts = _context.sent; storedAccountsIds = accounts.map(function (account) {return account.id;}); if (Object(lodash__WEBPACK_IMPORTED_MODULE_5__["difference"])(accountsIds, storedAccountsIds).length > 0) { errorReasons.push({ type: 'ACCOUNTS.IDS.NOT.FOUND', code: 200 }); - }_context.next = 18;return ( + }_context.next = 21;return ( - _models_JournalEntry__WEBPACK_IMPORTED_MODULE_11__["default"].query().where('reference', form.reference));case 18:journalReference = _context.sent; + _models_JournalEntry__WEBPACK_IMPORTED_MODULE_12__["default"].query().where('reference', form.reference));case 21:journalReference = _context.sent; if (journalReference.length > 0) { errorReasons.push({ type: 'REFERENCE.ALREADY.EXISTS', code: 300 }); }if (!( - errorReasons.length > 0)) {_context.next = 22;break;}return _context.abrupt("return", - res.status(400).send({ errors: errorReasons }));case 22: + errorReasons.length > 0)) {_context.next = 25;break;}return _context.abrupt("return", + res.status(400).send({ errors: errorReasons }));case 25:_context.next = 27;return ( - journalPoster = new _services_Accounting_JournalPoster__WEBPACK_IMPORTED_MODULE_9__["default"](); - form.entries.forEach(function (entry) { + + _models_JournalEntry__WEBPACK_IMPORTED_MODULE_12__["default"].query().insert({ + reference: form.reference, + transaction_type: 'Journal', + amount: totalCredit, + date: formattedDate, + note: form.memo, + user_id: user.id }));case 27:manualJournal = _context.sent; + + journalPoster = new _services_Accounting_JournalPoster__WEBPACK_IMPORTED_MODULE_10__["default"](); + + entries.forEach(function (entry) { var account = accounts.find(function (a) {return a.id === entry.account_id;}); - var jouranlEntry = new _services_Accounting_JournalEntry__WEBPACK_IMPORTED_MODULE_10__["default"]({ - date: entry.date, + var jouranlEntry = new _services_Accounting_JournalEntry__WEBPACK_IMPORTED_MODULE_11__["default"]({ debit: entry.debit, credit: entry.credit, account: account.id, + transactionType: 'Journal', accountNormal: account.type.normal, - note: entry.note }); + note: entry.note, + date: formattedDate, + userId: user.id }); if (entry.debit) { journalPoster.debit(jouranlEntry); @@ -850,17 +889,17 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj }); // Saves the journal entries and accounts balance changes. - _context.next = 26;return Promise.all([ + _context.next = 32;return Promise.all([ journalPoster.saveEntries(), - journalPoster.saveBalance()]);case 26:return _context.abrupt("return", + journalPoster.saveBalance()]);case 32:return _context.abrupt("return", - res.status(200).send());case 27:case "end":return _context.stop();}}}, _callee);}));function handler(_x, _x2) {return _handler.apply(this, arguments);}return handler;}() }, + res.status(200).send({ id: manualJournal.id }));case 33:case "end":return _context.stop();}}}, _callee);}));function handler(_x, _x2) {return _handler.apply(this, arguments);}return handler;}() }, /** - * Saves recurring journal entries template. - */ + * Saves recurring journal entries template. + */ recurringJournalEntries: { validation: [ Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('template_name').exists(), @@ -921,7 +960,7 @@ function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Obj errorReasons = []; form = _objectSpread({}, req.body);_context4.next = 7;return ( - _models_Account__WEBPACK_IMPORTED_MODULE_6__["default"].query(). + _models_Account__WEBPACK_IMPORTED_MODULE_7__["default"].query(). where('id', form.credit_account_id). orWhere('id', form.debit_account_id));case 7:foundAccounts = _context4.sent; @@ -2146,17 +2185,77 @@ __webpack_require__.r(__webpack_exports__); "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! express */ "express"); -/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(express__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/regenerator */ "@babel/runtime/regenerator"); +/* harmony import */ var _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/asyncToGenerator */ "@babel/runtime/helpers/asyncToGenerator"); +/* harmony import */ var _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! express */ "express"); +/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(express__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var express_validator__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! express-validator */ "express-validator"); +/* harmony import */ var express_validator__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(express_validator__WEBPACK_IMPORTED_MODULE_3__); +/* harmony import */ var _http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/http/middleware/asyncMiddleware */ "./src/http/middleware/asyncMiddleware.js"); + + /* harmony default export */ __webpack_exports__["default"] = ({ router: function router() { - var router = express__WEBPACK_IMPORTED_MODULE_0___default.a.Router(); + var router = express__WEBPACK_IMPORTED_MODULE_2___default.a.Router(); + + router.post('/', + this.newCustomer.validation, + Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_4__["default"])(this.newCustomer.handler)); + + router.post('/:id', + this.editCustomer.validation, + Object(_http_middleware_asyncMiddleware__WEBPACK_IMPORTED_MODULE_4__["default"])(this.editCustomer.handler)); return router; - } }); + }, + + newCustomer: { + validation: [ + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('custom_type').exists().trim().escape(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('first_name').exists().trim().escape(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('last_name'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('company_name'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('email'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('work_phone'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('personal_phone'), + + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('billing_address.country'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('billing_address.address'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('billing_address.city'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('billing_address.phone'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('billing_address.zip_code'), + + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('shiping_address.country'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('shiping_address.address'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('shiping_address.city'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('shiping_address.phone'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('shiping_address.zip_code'), + + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('contact.additional_phone'), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('contact.additional_email'), + + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('custom_fields').optional().isArray({ min: 1 }), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('custom_fields.*.key').exists().trim().escape(), + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('custom_fields.*.value').exists(), + + Object(express_validator__WEBPACK_IMPORTED_MODULE_3__["check"])('inactive').optional().isBoolean().toBoolean()], + + + handler: function () {var _handler = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee(req, res) {return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee$(_context) {while (1) {switch (_context.prev = _context.next) {case 0:case "end":return _context.stop();}}}, _callee);}));function handler(_x, _x2) {return _handler.apply(this, arguments);}return handler;}() }, + + + + + editCustomer: { + validation: [], + + + handler: function () {var _handler2 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_1___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.mark(function _callee2(req, res) {return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_0___default.a.wrap(function _callee2$(_context2) {while (1) {switch (_context2.prev = _context2.next) {case 0:case "end":return _context2.stop();}}}, _callee2);}));function handler(_x3, _x4) {return _handler2.apply(this, arguments);}return handler;}() } }); /***/ }), @@ -3179,25 +3278,25 @@ var formatNumberClosure = function formatNumberClosure(filter) {return function res.status(200).send({ meta: _objectSpread({}, filter), - items: items }));case 20:case "end":return _context2.stop();}}}, _callee2);}));function handler(_x3, _x4) {return _handler2.apply(this, arguments);}return handler;}() }, + accounts: items }));case 20:case "end":return _context2.stop();}}}, _callee2);}));function handler(_x3, _x4) {return _handler2.apply(this, arguments);}return handler;}() }, /** - * Retrieve the balance sheet. - */ + * Retrieve the balance sheet. + */ balanceSheet: { validation: [ Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('accounting_method').optional().isIn(['cash', 'accural']), Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('from_date').optional(), Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('to_date').optional(), - Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('display_columns_by').optional().isIn(['year', 'month', 'week', 'day', 'quarter']), + Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('display_columns_by').optional().isIn(['total', 'year', 'month', 'week', 'day', 'quarter']), Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('number_format.no_cents').optional().isBoolean().toBoolean(), Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('number_format.divide_1000').optional().isBoolean().toBoolean(), Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('none_zero').optional().isBoolean().toBoolean()], - handler: function () {var _handler3 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_3___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.mark(function _callee3(req, res) {var validationErrors, filter, balanceSheetTypes, accounts, journalEntriesCollected, journalEntries, balanceFormatter, dateRangeSet, assets, liabilitiesEquity;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0: + handler: function () {var _handler3 = _babel_runtime_helpers_asyncToGenerator__WEBPACK_IMPORTED_MODULE_3___default()( /*#__PURE__*/_babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.mark(function _callee3(req, res) {var validationErrors, filter, balanceSheetTypes, accounts, journalEntriesCollected, journalEntries, balanceFormatter, filterDateType, dateRangeSet, assets, liabilitiesEquity;return _babel_runtime_regenerator__WEBPACK_IMPORTED_MODULE_1___default.a.wrap(function _callee3$(_context3) {while (1) {switch (_context3.prev = _context3.next) {case 0: validationErrors = Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["validationResult"])(req);if ( validationErrors.isEmpty()) {_context3.next = 3;break;}return _context3.abrupt("return", @@ -3206,19 +3305,19 @@ var formatNumberClosure = function formatNumberClosure(filter) {return function filter = _objectSpread({ - display_columns_by: 'year', + display_columns_by: 'total', from_date: moment__WEBPACK_IMPORTED_MODULE_6___default()().startOf('year').format('YYYY-MM-DD'), to_date: moment__WEBPACK_IMPORTED_MODULE_6___default()().endOf('year').format('YYYY-MM-DD'), number_format: { no_cents: false, divide_1000: false }, - none_zero: false }, + none_zero: false, + basis: 'cash' }, req.query);_context3.next = 6;return ( - _models_AccountType__WEBPACK_IMPORTED_MODULE_11__["default"].query(). - where('balance_sheet', true));case 6:balanceSheetTypes = _context3.sent;_context3.next = 9;return ( + _models_AccountType__WEBPACK_IMPORTED_MODULE_11__["default"].query().where('balance_sheet', true));case 6:balanceSheetTypes = _context3.sent;_context3.next = 9;return ( _models_Account__WEBPACK_IMPORTED_MODULE_12__["default"].query(). @@ -3235,59 +3334,100 @@ var formatNumberClosure = function formatNumberClosure(filter) {return function // Account balance formmatter based on the given query. balanceFormatter = formatNumberClosure(filter.number_format); + filterDateType = filter.display_columns_by === 'total' ? + 'day' : filter.display_columns_by; // Gets the date range set from start to end date. dateRangeSet = Object(_utils__WEBPACK_IMPORTED_MODULE_14__["dateRangeCollection"])( filter.from_date, filter.to_date, - filter.display_columns_by); + filterDateType); + // Retrieve the asset balance sheet. - assets = _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()( - accounts. + assets = accounts. filter(function (account) {return ( account.type.normal === 'debit' && ( account.transactions.length > 0 || !filter.none_zero));}). - map(function (account) {return _objectSpread({}, - Object(lodash__WEBPACK_IMPORTED_MODULE_7__["pick"])(account, ['id', 'index', 'name', 'code']), { - transactions: dateRangeSet.map(function (date) { - var type = filter.display_columns_by; - var balance = journalEntries.getClosingBalance(account.id, date, type); - return { date: date, balance: balanceFormatter(balance) }; - }) });})); + map(function (account) { + // Calculates the closing balance to the given date. + var closingBalance = journalEntries.getClosingBalance(account.id, filter.to_date); + var type = filter.display_columns_by; + return _objectSpread({}, + Object(lodash__WEBPACK_IMPORTED_MODULE_7__["pick"])(account, ['id', 'index', 'name', 'code']), {}, + type !== 'total' ? { + periods_balance: dateRangeSet.map(function (date) { + var balance = journalEntries.getClosingBalance(account.id, date, filterDateType); + + return { + date: date, + formatted_amount: balanceFormatter(balance), + amount: balance }; + + }) } : + {}, { + balance: { + formatted_amount: balanceFormatter(closingBalance), + amount: closingBalance, + date: filter.to_date } }); + + + }); // Retrieve liabilities and equity balance sheet. - liabilitiesEquity = _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()( - accounts. + liabilitiesEquity = accounts. filter(function (account) {return ( account.type.normal === 'credit' && ( account.transactions.length > 0 || !filter.none_zero));}). - map(function (account) {return _objectSpread({}, - Object(lodash__WEBPACK_IMPORTED_MODULE_7__["pick"])(account, ['id', 'index', 'name', 'code']), { - transactions: dateRangeSet.map(function (date) { - var type = filter.display_columns_by; - var balance = journalEntries.getClosingBalance(account.id, date, type); - return { date: date, balance: balanceFormatter(balance) }; - }) });}));return _context3.abrupt("return", + map(function (account) { + // Calculates the closing balance to the given date. + var closingBalance = journalEntries.getClosingBalance(account.id, filter.to_date); + var type = filter.display_columns_by; + return _objectSpread({}, + Object(lodash__WEBPACK_IMPORTED_MODULE_7__["pick"])(account, ['id', 'index', 'name', 'code']), {}, + type !== 'total' ? { + periods_balance: dateRangeSet.map(function (date) { + var balance = journalEntries.getClosingBalance(account.id, date, filterDateType); + + return { + date: date, + formatted_amount: balanceFormatter(balance), + amount: balance }; + + }) } : + {}, { + balance: { + formattedAmount: balanceFormatter(closingBalance), + amount: closingBalance, + date: filter.to_date } }); + + + });return _context3.abrupt("return", res.status(200).send({ query: _objectSpread({}, filter), columns: _objectSpread({}, dateRangeSet), balance_sheet: { - assets: assets, - liabilities_equity: liabilitiesEquity } }));case 18:case "end":return _context3.stop();}}}, _callee3);}));function handler(_x5, _x6) {return _handler3.apply(this, arguments);}return handler;}() }, + assets: { + title: 'Assets', + accounts: _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(assets) }, + + liabilities_equity: { + title: 'Liabilities & Equity', + accounts: _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(liabilitiesEquity) } } }));case 19:case "end":return _context3.stop();}}}, _callee3);}));function handler(_x5, _x6) {return _handler3.apply(this, arguments);}return handler;}() }, + /** - * Retrieve the trial balance sheet. - */ + * Retrieve the trial balance sheet. + */ trialBalanceSheet: { validation: [ Object(express_validator__WEBPACK_IMPORTED_MODULE_5__["query"])('basis').optional(), @@ -3349,7 +3489,7 @@ var formatNumberClosure = function formatNumberClosure(filter) {return function });return _context4.abrupt("return", res.status(200).send({ - meta: _objectSpread({}, filter), + query: _objectSpread({}, filter), items: _babel_runtime_helpers_toConsumableArray__WEBPACK_IMPORTED_MODULE_0___default()(items) }));case 13:case "end":return _context4.stop();}}}, _callee4);}));function handler(_x7, _x8) {return _handler4.apply(this, arguments);}return handler;}() }, @@ -7969,10 +8109,12 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _services_Accounting_JournalEntry__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/services/Accounting/JournalEntry */ "./src/services/Accounting/JournalEntry.js"); /* harmony import */ var _models_AccountTransaction__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/models/AccountTransaction */ "./src/models/AccountTransaction.js"); /* harmony import */ var _models_AccountBalance__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/models/AccountBalance */ "./src/models/AccountBalance.js"); +/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @/utils */ "./src/utils/index.js"); function ownKeys(object, enumerableOnly) {var keys = Object.keys(object);if (Object.getOwnPropertySymbols) {var symbols = Object.getOwnPropertySymbols(object);if (enumerableOnly) symbols = symbols.filter(function (sym) {return Object.getOwnPropertyDescriptor(object, sym).enumerable;});keys.push.apply(keys, symbols);}return keys;}function _objectSpread(target) {for (var i = 1; i < arguments.length; i++) {var source = arguments[i] != null ? arguments[i] : {};if (i % 2) {ownKeys(source, true).forEach(function (key) {_babel_runtime_helpers_defineProperty__WEBPACK_IMPORTED_MODULE_0___default()(target, key, source[key]);});} else if (Object.getOwnPropertyDescriptors) {Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));} else {ownKeys(source).forEach(function (key) {Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));});}}return target;} + var JournalPoster = /*#__PURE__*/function () { @@ -8096,17 +8238,17 @@ JournalPoster = /*#__PURE__*/function () { this.entries.forEach(function (entry) { var oper = _models_AccountTransaction__WEBPACK_IMPORTED_MODULE_8__["default"].query().insert(_objectSpread({ accountId: entry.account }, - Object(lodash__WEBPACK_IMPORTED_MODULE_5__["pick"])(entry, ['credit', 'debit', 'transactionType', + Object(lodash__WEBPACK_IMPORTED_MODULE_5__["pick"])(entry, ['credit', 'debit', 'transactionType', 'date', 'userId', 'referenceType', 'referenceId', 'note']))); - saveOperations.push(oper); + saveOperations.push(function () {return oper;}); });_context2.next = 4;return ( - Promise.all(saveOperations));case 4:case "end":return _context2.stop();}}}, _callee2, this);}));function saveEntries() {return _saveEntries.apply(this, arguments);}return saveEntries;}() + Object(_utils__WEBPACK_IMPORTED_MODULE_10__["promiseSerial"])(saveOperations));case 4:case "end":return _context2.stop();}}}, _callee2, this);}));function saveEntries() {return _saveEntries.apply(this, arguments);}return saveEntries;}() /** - * Reverses the stacked journal entries. - */ }, { key: "reverseEntries", value: function reverseEntries() + * Reverses the stacked journal entries. + */ }, { key: "reverseEntries", value: function reverseEntries() { var reverseEntries = []; @@ -8444,7 +8586,7 @@ var transporter = nodemailer__WEBPACK_IMPORTED_MODULE_0___default.a.createTransp /*!****************************!*\ !*** ./src/utils/index.js ***! \****************************/ -/*! exports provided: hashPassword, origin, dateRangeCollection, dateRangeFormat, mapValuesDeep, mapKeysDeep */ +/*! exports provided: hashPassword, origin, dateRangeCollection, dateRangeFormat, mapValuesDeep, mapKeysDeep, promiseSerial */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -8455,6 +8597,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "dateRangeFormat", function() { return dateRangeFormat; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapValuesDeep", function() { return mapValuesDeep; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapKeysDeep", function() { return mapKeysDeep; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "promiseSerial", function() { return promiseSerial; }); /* harmony import */ var bcryptjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! bcryptjs */ "bcryptjs"); /* harmony import */ var bcryptjs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(bcryptjs__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var moment__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! moment */ "moment"); @@ -8530,6 +8673,12 @@ var mapValuesDeep = function mapValuesDeep(v, callback) {return ( callback(v));}; +var promiseSerial = function promiseSerial(funcs) { + return funcs.reduce(function (promise, func) {return promise.then(function (result) {return func().then(Array.prototype.concat.bind(result));});}, + Promise.resolve([])); +}; + + /***/ }), @@ -8766,6 +8915,17 @@ module.exports = require("helmet"); /***/ }), +/***/ "i18n": +/*!***********************!*\ + !*** external "i18n" ***! + \***********************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +module.exports = require("i18n"); + +/***/ }), + /***/ "jsonwebtoken": /*!*******************************!*\ !*** external "jsonwebtoken" ***! @@ -8866,4 +9026,4 @@ module.exports = require("path"); /***/ }) /******/ }); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrL2Jvb3RzdHJhcCIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9jb25maWcvaW5kZXguanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIva25leGZpbGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2FwcC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvY29sbGVjdGlvbi9CdWRnZXRFbnRyaWVzU2V0LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9jb2xsZWN0aW9uL05lc3RlZFNldC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvY29sbGVjdGlvbi9SZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9kYXRhL1Jlc291cmNlRmllbGRzS2V5cy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvZGF0YWJhc2Uva25leC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9BY2NvdW50T3BlbmluZ0JhbGFuY2UuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudFR5cGVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRpbmcuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQXV0aGVudGljYXRpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQmlsbHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQnVkZ2V0LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0J1ZGdldFJlcG9ydHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQ3VycmVuY2llcy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9DdXJyZW5jeUFkanVzdG1lbnQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQ3VzdG9tZXJzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0V4cGVuc2VzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0ZpZWxkcy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9GaW5hbmNpYWxTdGF0ZW1lbnRzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0l0ZW1DYXRlZ29yaWVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0l0ZW1zLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL09wdGlvbnMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvUmVzb3VyY2VzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL1JvbGVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL1N1cHBsaWVycy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9Vc2Vycy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9WaWV3cy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9taWRkbGV3YXJlL2F1dGhvcml6YXRpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9saWIvTG9naWNFdmFsdWF0aW9uL0xleGVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9saWIvTG9naWNFdmFsdWF0aW9uL1BhcnNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbGliL0xvZ2ljRXZhbHVhdGlvbi9RdWVyeVBhcnNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbGliL01ldGFibGUvTWV0YWJsZUNvbGxlY3Rpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2xpYi9WaWV3Um9sZXNCdWlsZGVyL2luZGV4LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL0FjY291bnRCYWxhbmNlLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudFR5cGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9CdWRnZXQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9CdWRnZXRFbnRyeS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL0V4cGVuc2UuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9JdGVtLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvSXRlbUNhdGVnb3J5LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvSm91cm5hbEVudHJ5LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvTWFudWFsSm91cm5hbC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL01vZGVsLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvT3B0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvUGFzc3dvcmRSZXNldC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1Blcm1pc3Npb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9SZXNvdXJjZS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1Jlc291cmNlRmllbGQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9SZXNvdXJjZUZpZWxkTWV0YWRhdGEuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9Sb2xlLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvVXNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1ZpZXcuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9WaWV3Q29sdW1uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvVmlld1JvbGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxFbnRyeS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsUG9zdGVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9zZXJ2aWNlcy9DdXN0b21GaWVsZHMvUmVzb3VyY2VDdXN0b21GaWVsZFJlcG9zaXRvcnkuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL3NlcnZpY2VzL01vbWVudC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmljZXMvbWFpbC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvdXRpbHMvaW5kZXguanMiLCJleHRlcm5hbCBcIkBiYWJlbC9wbHVnaW4tdHJhbnNmb3JtLXJ1bnRpbWVcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzc1wiIiwiZXh0ZXJuYWwgXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2ZcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0c1wiIiwiZXh0ZXJuYWwgXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXlcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIiIsImV4dGVybmFsIFwiYmNyeXB0anNcIiIsImV4dGVybmFsIFwiZG90ZW52XCIiLCJleHRlcm5hbCBcImVycm9yaGFuZGxlclwiIiwiZXh0ZXJuYWwgXCJleHByZXNzXCIiLCJleHRlcm5hbCBcImV4cHJlc3MtYm9vbVwiIiwiZXh0ZXJuYWwgXCJleHByZXNzLXZhbGlkYXRvclwiIiwiZXh0ZXJuYWwgXCJmc1wiIiwiZXh0ZXJuYWwgXCJoZWxtZXRcIiIsImV4dGVybmFsIFwianNvbndlYnRva2VuXCIiLCJleHRlcm5hbCBcImtuZXhcIiIsImV4dGVybmFsIFwibG9kYXNoXCIiLCJleHRlcm5hbCBcIm1vbWVudFwiIiwiZXh0ZXJuYWwgXCJtb21lbnQtcmFuZ2VcIiIsImV4dGVybmFsIFwibXVzdGFjaGVcIiIsImV4dGVybmFsIFwibm9kZW1haWxlclwiIiwiZXh0ZXJuYWwgXCJvYmplY3Rpb25cIiIsImV4dGVybmFsIFwicGF0aFwiIl0sInNvdXJjZXNDb250ZW50IjpbIiBcdC8vIFRoZSBtb2R1bGUgY2FjaGVcbiBcdHZhciBpbnN0YWxsZWRNb2R1bGVzID0ge307XG5cbiBcdC8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG4gXHRmdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cbiBcdFx0Ly8gQ2hlY2sgaWYgbW9kdWxlIGlzIGluIGNhY2hlXG4gXHRcdGlmKGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdKSB7XG4gXHRcdFx0cmV0dXJuIGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdLmV4cG9ydHM7XG4gXHRcdH1cbiBcdFx0Ly8gQ3JlYXRlIGEgbmV3IG1vZHVsZSAoYW5kIHB1dCBpdCBpbnRvIHRoZSBjYWNoZSlcbiBcdFx0dmFyIG1vZHVsZSA9IGluc3RhbGxlZE1vZHVsZXNbbW9kdWxlSWRdID0ge1xuIFx0XHRcdGk6IG1vZHVsZUlkLFxuIFx0XHRcdGw6IGZhbHNlLFxuIFx0XHRcdGV4cG9ydHM6IHt9XG4gXHRcdH07XG5cbiBcdFx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG4gXHRcdG1vZHVsZXNbbW9kdWxlSWRdLmNhbGwobW9kdWxlLmV4cG9ydHMsIG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG4gXHRcdC8vIEZsYWcgdGhlIG1vZHVsZSBhcyBsb2FkZWRcbiBcdFx0bW9kdWxlLmwgPSB0cnVlO1xuXG4gXHRcdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG4gXHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbiBcdH1cblxuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZXMgb2JqZWN0IChfX3dlYnBhY2tfbW9kdWxlc19fKVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5tID0gbW9kdWxlcztcblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGUgY2FjaGVcbiBcdF9fd2VicGFja19yZXF1aXJlX18uYyA9IGluc3RhbGxlZE1vZHVsZXM7XG5cbiBcdC8vIGRlZmluZSBnZXR0ZXIgZnVuY3Rpb24gZm9yIGhhcm1vbnkgZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5kID0gZnVuY3Rpb24oZXhwb3J0cywgbmFtZSwgZ2V0dGVyKSB7XG4gXHRcdGlmKCFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywgbmFtZSkpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgbmFtZSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGdldHRlciB9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZGVmaW5lIF9fZXNNb2R1bGUgb24gZXhwb3J0c1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yID0gZnVuY3Rpb24oZXhwb3J0cykge1xuIFx0XHRpZih0eXBlb2YgU3ltYm9sICE9PSAndW5kZWZpbmVkJyAmJiBTeW1ib2wudG9TdHJpbmdUYWcpIHtcbiBcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgU3ltYm9sLnRvU3RyaW5nVGFnLCB7IHZhbHVlOiAnTW9kdWxlJyB9KTtcbiBcdFx0fVxuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ19fZXNNb2R1bGUnLCB7IHZhbHVlOiB0cnVlIH0pO1xuIFx0fTtcblxuIFx0Ly8gY3JlYXRlIGEgZmFrZSBuYW1lc3BhY2Ugb2JqZWN0XG4gXHQvLyBtb2RlICYgMTogdmFsdWUgaXMgYSBtb2R1bGUgaWQsIHJlcXVpcmUgaXRcbiBcdC8vIG1vZGUgJiAyOiBtZXJnZSBhbGwgcHJvcGVydGllcyBvZiB2YWx1ZSBpbnRvIHRoZSBuc1xuIFx0Ly8gbW9kZSAmIDQ6IHJldHVybiB2YWx1ZSB3aGVuIGFscmVhZHkgbnMgb2JqZWN0XG4gXHQvLyBtb2RlICYgOHwxOiBiZWhhdmUgbGlrZSByZXF1aXJlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnQgPSBmdW5jdGlvbih2YWx1ZSwgbW9kZSkge1xuIFx0XHRpZihtb2RlICYgMSkgdmFsdWUgPSBfX3dlYnBhY2tfcmVxdWlyZV9fKHZhbHVlKTtcbiBcdFx0aWYobW9kZSAmIDgpIHJldHVybiB2YWx1ZTtcbiBcdFx0aWYoKG1vZGUgJiA0KSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICYmIHZhbHVlLl9fZXNNb2R1bGUpIHJldHVybiB2YWx1ZTtcbiBcdFx0dmFyIG5zID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiBcdFx0X193ZWJwYWNrX3JlcXVpcmVfXy5yKG5zKTtcbiBcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KG5zLCAnZGVmYXVsdCcsIHsgZW51bWVyYWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xuIFx0XHRpZihtb2RlICYgMiAmJiB0eXBlb2YgdmFsdWUgIT0gJ3N0cmluZycpIGZvcih2YXIga2V5IGluIHZhbHVlKSBfX3dlYnBhY2tfcmVxdWlyZV9fLmQobnMsIGtleSwgZnVuY3Rpb24oa2V5KSB7IHJldHVybiB2YWx1ZVtrZXldOyB9LmJpbmQobnVsbCwga2V5KSk7XG4gXHRcdHJldHVybiBucztcbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiZGlzdC9cIjtcblxuXG4gXHQvLyBMb2FkIGVudHJ5IG1vZHVsZSBhbmQgcmV0dXJuIGV4cG9ydHNcbiBcdHJldHVybiBfX3dlYnBhY2tfcmVxdWlyZV9fKF9fd2VicGFja19yZXF1aXJlX18ucyA9IDApO1xuIiwiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgZG90ZW52IGZyb20gJ2RvdGVudic7XG5cbmRvdGVudi5jb25maWcoe1xuICBwYXRoOiBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgJy5lbnYudGVzdCcpLFxufSk7XG4iLCJyZXF1aXJlKCdkb3RlbnYnKS5jb25maWcoKTtcblxuY29uc3QgTUlHUkFUSU9OU19ESVIgPSAnLi9zcmMvZGF0YWJhc2UvbWlncmF0aW9ucyc7XG5jb25zdCBTRUVEU19ESVIgPSAnLi9zcmMvZGF0YWJhc2Uvc2VlZHMnO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgdGVzdDoge1xuICAgIGNsaWVudDogcHJvY2Vzcy5lbnYuREJfQ0xJRU5ULFxuICAgIG1pZ3JhdGlvbnM6IHtcbiAgICAgIGRpcmVjdG9yeTogTUlHUkFUSU9OU19ESVIsXG4gICAgfSxcbiAgICBjb25uZWN0aW9uOiB7XG4gICAgICBob3N0OiBwcm9jZXNzLmVudi5EQl9IT1NULFxuICAgICAgdXNlcjogcHJvY2Vzcy5lbnYuREJfVVNFUixcbiAgICAgIHBhc3N3b3JkOiBwcm9jZXNzLmVudi5EQl9QQVNTV09SRCxcbiAgICAgIGRhdGFiYXNlOiBwcm9jZXNzLmVudi5EQl9OQU1FLFxuICAgICAgY2hhcnNldDogJ3V0ZjgnLFxuICAgIH0sXG4gIH0sXG4gIGRldmVsb3BtZW50OiB7XG4gICAgY2xpZW50OiBwcm9jZXNzLmVudi5EQl9DTElFTlQsXG4gICAgY29ubmVjdGlvbjoge1xuICAgICAgaG9zdDogcHJvY2Vzcy5lbnYuREJfSE9TVCxcbiAgICAgIHVzZXI6IHByb2Nlc3MuZW52LkRCX1VTRVIsXG4gICAgICBwYXNzd29yZDogcHJvY2Vzcy5lbnYuREJfUEFTU1dPUkQsXG4gICAgICBkYXRhYmFzZTogcHJvY2Vzcy5lbnYuREJfTkFNRSxcbiAgICAgIGNoYXJzZXQ6ICd1dGY4JyxcbiAgICB9LFxuICAgIG1pZ3JhdGlvbnM6IHtcbiAgICAgIGRpcmVjdG9yeTogTUlHUkFUSU9OU19ESVIsXG4gICAgfSxcbiAgICBzZWVkczoge1xuICAgICAgZGlyZWN0b3J5OiBTRUVEU19ESVIsXG4gICAgfSxcbiAgfSxcbiAgcHJvZHVjdGlvbjoge1xuICAgIGNsaWVudDogcHJvY2Vzcy5lbnYuREJfQ0xJRU5ULFxuICAgIGNvbm5lY3Rpb246IHtcbiAgICAgIGhvc3Q6IHByb2Nlc3MuZW52LkRCX0hPU1QsXG4gICAgICB1c2VyOiBwcm9jZXNzLmVudi5EQl9VU0VSLFxuICAgICAgcGFzc3dvcmQ6IHByb2Nlc3MuZW52LkRCX1BBU1NXT1JELFxuICAgICAgZGF0YWJhc2U6IHByb2Nlc3MuZW52LkRCX05BTUUsXG4gICAgICBjaGFyc2V0OiAndXRmOCcsXG4gICAgfSxcbiAgICBtaWdyYXRpb25zOiB7XG4gICAgICBkaXJlY3Rvcnk6IE1JR1JBVElPTlNfRElSLFxuICAgIH0sXG4gICAgc2VlZHM6IHtcbiAgICAgIGRpcmVjdG9yeTogU0VFRFNfRElSLFxuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgaGVsbWV0IGZyb20gJ2hlbG1ldCc7XG5pbXBvcnQgYm9vbSBmcm9tICdleHByZXNzLWJvb20nO1xuaW1wb3J0ICcuLi9jb25maWcnO1xuaW1wb3J0IHJvdXRlcyBmcm9tICdAL2h0dHAnO1xuaW1wb3J0ICdAL21vZGVscyc7XG5cbmNvbnN0IGFwcCA9IGV4cHJlc3MoKTtcblxuLy8gRXhwcmVzcyBjb25maWd1cmF0aW9uXG5hcHAuc2V0KCdwb3J0JywgcHJvY2Vzcy5lbnYuUE9SVCB8fCAzMDAwKTtcblxuYXBwLnVzZShoZWxtZXQoKSk7XG5hcHAudXNlKGJvb20oKSk7XG5hcHAudXNlKGV4cHJlc3MuanNvbigpKTtcblxucm91dGVzKGFwcCk7XG5cbmV4cG9ydCBkZWZhdWx0IGFwcDtcbiIsIlxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdWRnZXRFbnRyaWVzU2V0IHtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmFjY291bnRzID0ge307IFxuICAgIHRoaXMudG90YWxTdW1tYXJ5ID0ge31cbiAgICB0aGlzLm9yZGVyU2l6ZSA9IG51bGw7XG4gIH1cblxuICBzZXRaZXJvUGxhY2Vob2xkZXIoKSB7XG4gICAgaWYgKCF0aGlzLm9yZGVyU2l6ZSkgeyByZXR1cm47IH1cblxuICAgIE9iamVjdC52YWx1ZXModGhpcy5hY2NvdW50cykuZm9yRWFjaCgoYWNjb3VudCkgPT4ge1xuXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8PSB0aGlzLm9yZGVyU2l6ZS5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAodHlwZW9mIGFjY291bnRbaV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgYWNjb3VudFtpXSA9IHsgYW1vdW50OiAwIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBmcm9tKGFjY291bnRzLCBjb25maWdzKSB7XG4gICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyB0aGlzKGNvbmZpZ3MpO1xuXG4gICAgYWNjb3VudHMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5hY2NvdW50c1tlbnRyeS5hY2NvdW50SWRdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICBjb2xsZWN0aW9uLmFjY291bnRzW2VudHJ5LmFjY291bnRJZF0gPSB7fTtcbiAgICAgIH1cbiAgICAgIGlmIChlbnRyeS5vcmRlcikge1xuICAgICAgICBjb2xsZWN0aW9uLmFjY291bnRzW2VudHJ5LmFjY291bnRJZF1bZW50cnkub3JkZXJdID0gZW50cnk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gIH1cblxuICB0b0FycmF5KCkge1xuICAgIGNvbnN0IG91dHB1dCA9IFtdO1xuXG4gICAgT2JqZWN0LmtleSh0aGlzLmFjY291bnRzKS5mb3JFYWNoKChhY2NvdW50SWQpID0+IHtcbiAgICAgIGNvbnN0IGVudHJpZXMgPSB0aGlzLmFjY291bnRzW2FjY291bnRJZF07XG4gICAgICBvdXRwdXQucHVzaCh7XG4gICAgICAgIGFjY291bnRfaWQ6IGFjY291bnRJZCxcbiAgICAgICAgZW50cmllczogW1xuICAgICAgICAgIC4uLk9iamVjdC5rZXkoZW50cmllcykubWFwKChvcmRlcikgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50cnkgPSBlbnRyaWVzW29yZGVyXTtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIG9yZGVyLFxuICAgICAgICAgICAgICBhbW91bnQ6IGVudHJ5LmFtb3VudCxcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSksXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGNhbGNUb3RhbFN1bW1hcnkoKSB7XG4gICAgY29uc3QgdG90YWxTdW1tYXJ5ID0ge307XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMub3JkZXJTaXplLmxlbmd0aDsgaSsrKSB7XG4gICAgICBPYmplY3QudmFsdWUodGhpcy5hY2NvdW50cykuZm9yRWFjaCgoYWNjb3VudCkgPT4ge1xuICAgICAgICBpZiAodHlwZW9mIHRvdGFsU3VtbWFyeVtpXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICB0b3RhbFN1bW1hcnlbaV0gPSB7IGFtb3VudDogMCwgb3JkZXI6IGkgfTtcbiAgICAgICAgfVxuICAgICAgICB0b3RhbFN1bW1hcnlbaV0uYW1vdW50ICs9IGFjY291bnRbaV0uYW1vdW50O1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMudG90YWxTdW1tYXJ5ID0gdG90YWxTdW1tYXJ5O1xuICB9XG5cbiAgdG9BcnJheVRvdGFsU3VtbWFyeSgpIHtcbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0aGlzLnRvdGFsU3VtbWFyeSk7XG4gIH1cblxufVxuIiwiXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBOZXN0ZWRTZXQge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IgbWV0aG9kLlxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtXG4gICAqL1xuICBjb25zdHJ1Y3RvcihpdGVtcywgb3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IHtcbiAgICAgIHBhcmVudElkOiAncGFyZW50X2lkJyxcbiAgICAgIGlkOiAnaWQnLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9O1xuICAgIHRoaXMuaXRlbXMgPSBpdGVtcztcbiAgICB0aGlzLmNvbGxlY3Rpb24gPSB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaW5rIG5vZGVzIGNoaWxkcmVuLlxuICAgKi9cbiAgbGlua0NoaWxkcmVuKCkge1xuICAgIGlmICh0aGlzLml0ZW1zLmxlbmd0aCA8PSAwKSByZXR1cm4gZmFsc2U7XG5cbiAgICBjb25zdCBtYXAgPSB7fTtcbiAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIG1hcFtpdGVtLmlkXSA9IGl0ZW07XG4gICAgICBtYXBbaXRlbS5pZF0uY2hpbGRyZW4gPSBbXTtcbiAgICB9KTtcblxuICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgcGFyZW50Tm9kZUlkID0gaXRlbVt0aGlzLm9wdGlvbnMucGFyZW50SWRdO1xuICAgICAgaWYgKHBhcmVudE5vZGVJZCkge1xuICAgICAgICBtYXBbcGFyZW50Tm9kZUlkXS5jaGlsZHJlbi5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiBtYXA7XG4gIH1cblxuICB0b1RyZWUoKSB7XG4gICAgY29uc3QgbWFwID0gdGhpcy5saW5rQ2hpbGRyZW4oKTtcbiAgICBjb25zdCB0cmVlID0ge307XG5cbiAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0pID0+IHtcbiAgICAgIGNvbnN0IHBhcmVudE5vZGVJZCA9IGl0ZW1bdGhpcy5vcHRpb25zLnBhcmVudElkXTtcbiAgICAgIGlmICghcGFyZW50Tm9kZUlkKSB7XG4gICAgICAgIHRyZWVbaXRlbS5pZF0gPSBtYXBbaXRlbS5pZF07XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5jb2xsZWN0aW9uID0gT2JqZWN0LnZhbHVlcyh0cmVlKTtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0aW9uO1xuICB9XG5cbiAgZ2V0VHJlZSgpIHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0aW9uO1xuICB9XG5cbiAgZmxhdHRlblRyZWUobm9kZU1hcHBlcikge1xuICAgIGNvbnN0IGZsYXR0ZW5UcmVlID0gW107XG5cbiAgICBjb25zdCB0cmF2ZXJzYWwgPSAobm9kZXMsIHBhcmVudE5vZGUpID0+IHtcbiAgICAgIG5vZGVzLmZvckVhY2goKG5vZGUpID0+IHtcbiAgICAgICAgbGV0IG5vZGVNYXBwZWQgPSBub2RlO1xuXG4gICAgICAgIGlmICh0eXBlb2Ygbm9kZU1hcHBlciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIG5vZGVNYXBwZWQgPSBub2RlTWFwcGVyKG5vZGVNYXBwZWQsIHBhcmVudE5vZGUpO1xuICAgICAgICB9XG4gICAgICAgIGZsYXR0ZW5UcmVlLnB1c2gobm9kZU1hcHBlZCk7XG5cbiAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdHJhdmVyc2FsKG5vZGUuY2hpbGRyZW4sIG5vZGUpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9O1xuICAgIHRyYXZlcnNhbCh0aGlzLmNvbGxlY3Rpb24pO1xuXG4gICAgcmV0dXJuIGZsYXR0ZW5UcmVlO1xuICB9XG59XG4iLCJpbXBvcnQgTWV0YWJsZUNvbGxlY3Rpb24gZnJvbSAnQC9saWIvTWV0YWJsZS9NZXRhYmxlQ29sbGVjdGlvbic7XG5pbXBvcnQgUmVzb3VyY2VGaWVsZE1ldGFkYXRhIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlRmllbGRNZXRhZGF0YSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24gZXh0ZW5kcyBNZXRhYmxlQ29sbGVjdGlvbiB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvciBtZXRob2QuXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgdGhpcy5zZXRNb2RlbChSZXNvdXJjZUZpZWxkTWV0YWRhdGEpO1xuICAgIHRoaXMuZXh0cmFDb2x1bW5zID0gWydyZXNvdXJjZV9pZCcsICdyZXNvdXJjZV9pdGVtX2lkJ107XG4gIH1cbn1cbiIsIlxuZXhwb3J0IGRlZmF1bHQge1xuICBcImV4cGVuc2VfYWNjb3VudFwiOiAnZXhwZW5zZV9hY2NvdW50X2lkJyxcbiAgXCJwYXltZW50X2FjY291bnRcIjogJ3BheW1lbnRfYWNjb3VudF9pZCcsXG4gIFwiYWNjb3VudF90eXBlXCI6IFwiYWNjb3VudF90eXBlX2lkXCJcbn0iLCJpbXBvcnQgS25leCBmcm9tICdrbmV4JztcbmltcG9ydCB7IGtuZXhTbmFrZUNhc2VNYXBwZXJzIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBrbmV4ZmlsZSBmcm9tICdALy4uL2tuZXhmaWxlJztcblxuY29uc3QgY29uZmlnID0ga25leGZpbGVbcHJvY2Vzcy5lbnYuTk9ERV9FTlZdO1xuY29uc3Qga25leCA9IEtuZXgoe1xuICAuLi5jb25maWcsXG4gIC4uLmtuZXhTbmFrZUNhc2VNYXBwZXJzKHsgdXBwZXJDYXNlOiB0cnVlIH0pLFxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IGtuZXg7XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGNoZWNrLCB2YWxpZGF0aW9uUmVzdWx0LCBvbmVPZiB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCB7IGRpZmZlcmVuY2UgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgand0QXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBBY2NvdW50IGZyb20gJ0AvbW9kZWxzL0FjY291bnQnO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IEpvdXJuYWxFbnRyeSBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbEVudHJ5JztcbmltcG9ydCBNYW51YWxKb3VybmFsIGZyb20gJ0AvbW9kZWxzL01hbnVhbEpvdXJuYWwnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLm9wZW5pbmdCYWxuYWNlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5vcGVuaW5nQmFsbmFjZS5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBPcGVuaW5nIGJhbGFuY2UgdG8gdGhlIGdpdmVuIGFjY291bnQuXG4gICAqIEBwYXJhbSB7UmVxdWVzdH0gcmVxIC1cbiAgICogQHBhcmFtIHtSZXNwb25zZX0gcmVzIC1cbiAgICovXG4gIG9wZW5pbmdCYWxuYWNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ2RhdGUnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ25vdGUnKS5vcHRpb25hbCgpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdiYWxhbmNlX2FkanVzdG1lbnRfYWNjb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnYWNjb3VudHMnKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2FjY291bnRzLiouaWQnKS5leGlzdHMoKS5pc0ludCgpLFxuICAgICAgb25lT2YoW1xuICAgICAgICBjaGVjaygnYWNjb3VudHMuKi5kZWJpdCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgICAgY2hlY2soJ2FjY291bnRzLiouY3JlZGl0JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgXSksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGFjY291bnRzIH0gPSByZXEuYm9keTtcbiAgICAgIGNvbnN0IHsgdXNlciB9ID0gcmVxO1xuICAgICAgY29uc3QgZm9ybSA9IHsgLi4ucmVxLmJvZHkgfTtcbiAgICAgIGNvbnN0IGRhdGUgPSBtb21lbnQoZm9ybS5kYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQnKTtcblxuICAgICAgY29uc3QgYWNjb3VudHNJZHMgPSBhY2NvdW50cy5tYXAoKGFjY291bnQpID0+IGFjY291bnQuaWQpO1xuICAgICAgY29uc3Qgc3RvcmVkQWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KClcbiAgICAgICAgLnNlbGVjdChbJ2lkJ10pLndoZXJlSW4oJ2lkJywgYWNjb3VudHNJZHMpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCd0eXBlJyk7XG5cbiAgICAgIGNvbnN0IGFjY291bnRzQ29sbGVjdGlvbiA9IG5ldyBNYXAoc3RvcmVkQWNjb3VudHMubWFwKGkgPT4gW2kuaWQsIGldKSk7XG5cbiAgICAgIC8vIEdldCB0aGUgc3RvcmVkIGFjY291bnRzIElkcyBhbmQgZGlmZmVyZW5jZSB3aXRoIHN1Ym1pdCBhY2NvdW50cy5cbiAgICAgIGNvbnN0IGFjY291bnRzU3RvcmVkSWRzID0gc3RvcmVkQWNjb3VudHMubWFwKChhY2NvdW50KSA9PiBhY2NvdW50LmlkKTtcbiAgICAgIGNvbnN0IG5vdEZvdW5kQWNjb3VudHNJZHMgPSBkaWZmZXJlbmNlKGFjY291bnRzSWRzLCBhY2NvdW50c1N0b3JlZElkcyk7XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcblxuICAgICAgaWYgKG5vdEZvdW5kQWNjb3VudHNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBpZHMgPSBub3RGb3VuZEFjY291bnRzSWRzLm1hcCgoYSkgPT4gcGFyc2VJbnQoYSwgMTApKTtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnTk9UX0ZPVU5EX0FDQ09VTlQnLCBjb2RlOiAxMDAsIGlkcyB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChmb3JtLmJhbGFuY2VfYWRqdXN0bWVudF9hY2NvdW50KSB7XG4gICAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5iYWxhbmNlX2FkanVzdG1lbnRfYWNjb3VudCk7XG5cbiAgICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQkFMQU5DRS5BREpVU1RNRU5ULkFDQ09VTlQuTk9ULkVYSVNUJywgY29kZTogMzAwIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwgeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgam91cm5hbEVudHJpZXMgPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuXG4gICAgICBhY2NvdW50cy5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHN0b3JlZEFjY291bnQgPSBhY2NvdW50c0NvbGxlY3Rpb24uZ2V0KGFjY291bnQuaWQpO1xuXG4gICAgICAgIC8vIENhbid0IGNvbnRpbnVlIGluIGNhc2UgdGhlIHN0b3JlZCBhY2NvdW50IHdhcyBub3QgZm91bmQuXG4gICAgICAgIGlmICghc3RvcmVkQWNjb3VudCkgeyByZXR1cm47IH1cblxuICAgICAgICBjb25zdCBlbnRyeU1vZGVsID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAgICAgcmVmZXJlbmNlVHlwZTogJ09wZW5pbmdCYWxhbmNlJyxcbiAgICAgICAgICBhY2NvdW50OiBhY2NvdW50LmlkLFxuICAgICAgICAgIGFjY291bnROb3JtYWw6IHN0b3JlZEFjY291bnQudHlwZS5ub3JtYWwsXG4gICAgICAgICAgdXNlcklkOiB1c2VyLmlkLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKGFjY291bnQuY3JlZGl0KSB7XG4gICAgICAgICAgZW50cnlNb2RlbC5lbnRyeS5jcmVkaXQgPSBhY2NvdW50LmNyZWRpdDtcbiAgICAgICAgICBqb3VybmFsRW50cmllcy5jcmVkaXQoZW50cnlNb2RlbCk7XG4gICAgICAgIH0gZWxzZSBpZiAoYWNjb3VudC5kZWJpdCkge1xuICAgICAgICAgIGVudHJ5TW9kZWwuZW50cnkuZGViaXQgPSBhY2NvdW50LmRlYml0O1xuICAgICAgICAgIGpvdXJuYWxFbnRyaWVzLmRlYml0KGVudHJ5TW9kZWwpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIENhbGN1bGF0ZXMgdGhlIGNyZWRpdCBhbmQgZGViaXQgYmFsYW5jZSBvZiBzdGFja2VkIGVudHJpZXMuXG4gICAgICBjb25zdCB0cmlhbCA9IGpvdXJuYWxFbnRyaWVzLmdldFRyaWFsQmFsYW5jZSgpO1xuXG4gICAgICBpZiAodHJpYWwuY3JlZGl0ICE9PSB0cmlhbC5kZWJpdCkge1xuICAgICAgICBjb25zdCBlbnRyeU1vZGVsID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAgICAgcmVmZXJlbmNlVHlwZTogJ09wZW5pbmdCYWxhbmNlJyxcbiAgICAgICAgICBhY2NvdW50OiBmb3JtLmJhbGFuY2VfYWRqdXN0bWVudF9hY2NvdW50LFxuICAgICAgICAgIGFjY291bnROb3JtYWw6ICdjcmVkaXQnLFxuICAgICAgICAgIHVzZXJJZDogdXNlci5pZCxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKHRyaWFsLmNyZWRpdCA+IHRyaWFsLmRlYml0KSB7XG4gICAgICAgICAgZW50cnlNb2RlbC5lbnRyeS5jcmVkaXQgPSBNYXRoLmFicyh0cmlhbC5jcmVkaXQpO1xuICAgICAgICAgIGpvdXJuYWxFbnRyaWVzLmNyZWRpdChlbnRyeU1vZGVsKTtcblxuICAgICAgICB9IGVsc2UgaWYgKHRyaWFsLmNyZWRpdCA8IHRyaWFsLmRlYml0KSB7XG4gICAgICAgICAgZW50cnlNb2RlbC5lbnRyeS5kZWJpdCA9IE1hdGguYWJzKHRyaWFsLmRlYml0KTtcbiAgICAgICAgICBqb3VybmFsRW50cmllcy5kZWJpdChlbnRyeU1vZGVsKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgbWFudWFsSm91cm5hbCA9IGF3YWl0IE1hbnVhbEpvdXJuYWwucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICBhbW91bnQ6IE1hdGgubWF4KHRyaWFsLmNyZWRpdCwgdHJpYWwuZGViaXQpLFxuICAgICAgICB0cmFuc2FjdGlvbl90eXBlOiAnT3BlbmluZ0JhbGFuY2UnLFxuICAgICAgICBkYXRlLFxuICAgICAgICBub3RlOiBmb3JtLm5vdGUsXG4gICAgICAgIHVzZXJfaWQ6IHVzZXIuaWQsXG4gICAgICB9KTtcblxuICAgICAgam91cm5hbEVudHJpZXMuZW50cmllcyA9IGpvdXJuYWxFbnRyaWVzLmVudHJpZXMubWFwKChlbnRyeSkgPT4gKHtcbiAgICAgICAgLi4uZW50cnksXG4gICAgICAgIHJlZmVyZW5jZUlkOiBtYW51YWxKb3VybmFsLmlkLFxuICAgICAgfSkpO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBqb3VybmFsRW50cmllcy5zYXZlRW50cmllcygpLFxuICAgICAgICBqb3VybmFsRW50cmllcy5zYXZlQmFsYW5jZSgpLFxuICAgICAgXSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogbWFudWFsSm91cm5hbC5pZCB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IEpXVEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgQWNjb3VudFR5cGUgZnJvbSAnQC9tb2RlbHMvQWNjb3VudFR5cGUnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIudXNlKEpXVEF1dGgpO1xuXG4gICAgcm91dGVyLmdldCgnLycsXG4gICAgICB0aGlzLmdldEFjY291bnRUeXBlc0xpc3QudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldEFjY291bnRUeXBlc0xpc3QuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgYWNjb3VudHMgdHlwZXMgbGlzdC5cbiAgICovXG4gIGdldEFjY291bnRUeXBlc0xpc3Q6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCBhY2NvdW50VHlwZXMgPSBhd2FpdCBBY2NvdW50VHlwZS5xdWVyeSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBhY2NvdW50X3R5cGVzOiBhY2NvdW50VHlwZXMsXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCB7IGNoZWNrLCBxdWVyeSwgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgQWNjb3VudCBmcm9tICdAL21vZGVscy9BY2NvdW50JztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBKV1RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IEpvdXJuYWxFbnRyeSBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbEVudHJ5JztcbmltcG9ydCBNYW51YWxKb3VybmFsIGZyb20gJ0AvbW9kZWxzL0pvdXJuYWxFbnRyeSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIHJvdXRlci51c2UoSldUQXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnL21ha2Utam91cm5hbC1lbnRyaWVzJyxcbiAgICAgIHRoaXMubWFrZUpvdXJuYWxFbnRyaWVzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5tYWtlSm91cm5hbEVudHJpZXMuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9yZWN1cnJpbmctam91cm5hbC1lbnRyaWVzJyxcbiAgICAgIHRoaXMucmVjdXJyaW5nSm91cm5hbEVudHJpZXMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlY3VycmluZ0pvdXJuYWxFbnRyaWVzLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCdxdWljay1qb3VybmFsLWVudHJpZXMnLFxuICAgICAgdGhpcy5xdWlja0pvdXJuYWxFbnRyaWVzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5xdWlja0pvdXJuYWxFbnRyaWVzLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIE1ha2Ugam91cm5hbCBlbnRyaXJlcy5cbiAgICovXG4gIG1ha2VKb3VybmFsRW50cmllczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdkYXRlJykuaXNJU084NjAxKCksXG4gICAgICBjaGVjaygncmVmZXJlbmNlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnZW50cmllcycpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgICBjaGVjaygnZW50cmllcy4qLmNyZWRpdCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZW50cmllcy4qLmRlYml0JykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLiouYWNjb3VudF9pZCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZW50cmllcy4qLm5vdGUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7XG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIC4uLnJlcS5ib2R5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgbGV0IHRvdGFsQ3JlZGl0ID0gMDtcbiAgICAgIGxldCB0b3RhbERlYml0ID0gMDtcblxuICAgICAgZm9ybS5lbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgIGlmIChlbnRyeS5jcmVkaXQgPiAwKSB7XG4gICAgICAgICAgdG90YWxDcmVkaXQgKz0gZW50cnkuY3JlZGl0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbnRyeS5kZWJpdCA+IDApIHtcbiAgICAgICAgICB0b3RhbERlYml0ICs9IGVudHJ5LmRlYml0O1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmICh0b3RhbENyZWRpdCA8PSAwIHx8IHRvdGFsRGViaXQgPD0gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ0NSRURJVC5ERUJJVC5TVU1BVElPTi5TSE9VTEQuTk9ULkVRVUFMLlpFUk8nLFxuICAgICAgICAgIGNvZGU6IDQwMCxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAodG90YWxDcmVkaXQgIT09IHRvdGFsRGViaXQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQ1JFRElULkRFQklULk5PVC5FUVVBTFMnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBhY2NvdW50c0lkcyA9IGZvcm0uZW50cmllcy5tYXAoKGVudHJ5KSA9PiBlbnRyeS5hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLndoZXJlSW4oJ2lkJywgYWNjb3VudHNJZHMpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCd0eXBlJyk7XG5cbiAgICAgIGNvbnN0IHN0b3JlZEFjY291bnRzSWRzID0gYWNjb3VudHMubWFwKChhY2NvdW50KSA9PiBhY2NvdW50LmlkKTtcblxuICAgICAgaWYgKGRpZmZlcmVuY2UoYWNjb3VudHNJZHMsIHN0b3JlZEFjY291bnRzSWRzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0FDQ09VTlRTLklEUy5OT1QuRk9VTkQnLCBjb2RlOiAyMDAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGpvdXJuYWxSZWZlcmVuY2UgPSBhd2FpdCBNYW51YWxKb3VybmFsLnF1ZXJ5KCkud2hlcmUoJ3JlZmVyZW5jZScsIGZvcm0ucmVmZXJlbmNlKTtcblxuICAgICAgaWYgKGpvdXJuYWxSZWZlcmVuY2UubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdSRUZFUkVOQ0UuQUxSRUFEWS5FWElTVFMnLCBjb2RlOiAzMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBqb3VybmFsUG9zdGVyID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcblxuICAgICAgZm9ybS5lbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgIGNvbnN0IGFjY291bnQgPSBhY2NvdW50cy5maW5kKChhKSA9PiBhLmlkID09PSBlbnRyeS5hY2NvdW50X2lkKTtcblxuICAgICAgICBjb25zdCBqb3VyYW5sRW50cnkgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgICBkYXRlOiBlbnRyeS5kYXRlLFxuICAgICAgICAgIGRlYml0OiBlbnRyeS5kZWJpdCxcbiAgICAgICAgICBjcmVkaXQ6IGVudHJ5LmNyZWRpdCxcbiAgICAgICAgICBhY2NvdW50OiBhY2NvdW50LmlkLFxuICAgICAgICAgIGFjY291bnROb3JtYWw6IGFjY291bnQudHlwZS5ub3JtYWwsXG4gICAgICAgICAgbm90ZTogZW50cnkubm90ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChlbnRyeS5kZWJpdCkge1xuICAgICAgICAgIGpvdXJuYWxQb3N0ZXIuZGViaXQoam91cmFubEVudHJ5KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBqb3VybmFsUG9zdGVyLmNyZWRpdChqb3VyYW5sRW50cnkpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLy8gU2F2ZXMgdGhlIGpvdXJuYWwgZW50cmllcyBhbmQgYWNjb3VudHMgYmFsYW5jZSBjaGFuZ2VzLlxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBqb3VybmFsUG9zdGVyLnNhdmVFbnRyaWVzKCksXG4gICAgICAgIGpvdXJuYWxQb3N0ZXIuc2F2ZUJhbGFuY2UoKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogU2F2ZXMgcmVjdXJyaW5nIGpvdXJuYWwgZW50cmllcyB0ZW1wbGF0ZS5cbiAgICovXG4gIHJlY3VycmluZ0pvdXJuYWxFbnRyaWVzOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ3RlbXBsYXRlX25hbWUnKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdyZWN1cnJlbmNlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnYWN0aXZlJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzJykuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLiouY3JlZGl0JykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLiouZGViaXQnKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2VudHJpZXMuKi5hY2NvdW50X2lkJykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLioubm90ZScpLm9wdGlvbmFsKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgfSxcbiAgfSxcblxuICByZWN1cnJpbmdKb3VybmFsc0xpc3Q6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgncGFnZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdwYWdlX3NpemUnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgndGVtcGxhdGVfbmFtZScpLm9wdGlvbmFsKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gIH0sXG5cbiAgcXVpY2tKb3VybmFsRW50cmllczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdkYXRlJykuZXhpc3RzKCkuaXNJU084NjAxKCksXG4gICAgICBjaGVjaygnYW1vdW50JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgY2hlY2soJ2NyZWRpdF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZWJpdF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCd0cmFuc2FjdGlvbl90eXBlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnbm90ZScpLm9wdGlvbmFsKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuXG4gICAgICBjb25zdCBmb3VuZEFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnaWQnLCBmb3JtLmNyZWRpdF9hY2NvdW50X2lkKVxuICAgICAgICAub3JXaGVyZSgnaWQnLCBmb3JtLmRlYml0X2FjY291bnRfaWQpO1xuXG4gICAgICBjb25zdCBjcmVkaXRBY2NvdW50ID0gZm91bmRBY2NvdW50cy5maW5kKChhKSA9PiBhLmlkID09PSBmb3JtLmNyZWRpdF9hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IGRlYml0QWNjb3VudCA9IGZvdW5kQWNjb3VudHMuZmluZCgoYSkgPT4gYS5pZCA9PT0gZm9ybS5kZWJpdF9hY2NvdW50X2lkKTtcblxuICAgICAgaWYgKCFjcmVkaXRBY2NvdW50KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0NSRURJVF9BQ0NPVU5ULk5PVC5FWElTVCcsIGNvZGU6IDEwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghZGViaXRBY2NvdW50KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0RFQklUX0FDQ09VTlQuTk9ULkVYSVNUJywgY29kZTogMjAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBjb25zdCBqb3VybmFsUG9zdGVyID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIC8vIGNvbnN0IGpvdXJuYWxDcmVkaXQgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgIC8vICAgZGViaXQ6IFxuICAgICAgLy8gICBhY2NvdW50OiBkZWJpdEFjY291bnQuaWQsXG4gICAgICAvLyAgIHJlZmVyZW5jZUlkOiBcbiAgICAgIC8vIH0pXG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgdmFsaWRhdGlvblJlc3VsdCwgcGFyYW0sIHF1ZXJ5IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgQWNjb3VudFR5cGUgZnJvbSAnQC9tb2RlbHMvQWNjb3VudFR5cGUnO1xuaW1wb3J0IEFjY291bnRUcmFuc2FjdGlvbiBmcm9tICdAL21vZGVscy9BY2NvdW50VHJhbnNhY3Rpb24nO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IEFjY291bnRCYWxhbmNlIGZyb20gJ0AvbW9kZWxzL0FjY291bnRCYWxhbmNlJztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICdAL21vZGVscy9SZXNvdXJjZSc7XG5pbXBvcnQgVmlldyBmcm9tICdAL21vZGVscy9WaWV3JztcbmltcG9ydCBKV1RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IE5lc3RlZFNldCBmcm9tICcuLi8uLi9jb2xsZWN0aW9uL05lc3RlZFNldCc7XG5pbXBvcnQge1xuICBtYXBWaWV3Um9sZXNUb0NvbmRpdGlvbmFscyxcbiAgdmFsaWRhdGVWaWV3Um9sZXMsXG59IGZyb20gJ0AvbGliL1ZpZXdSb2xlc0J1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IgbWV0aG9kLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIudXNlKEpXVEF1dGgpO1xuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHRoaXMubmV3QWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubmV3QWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICB0aGlzLmVkaXRBY2NvdW50LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5lZGl0QWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvOmlkJyxcbiAgICAgIHRoaXMuZ2V0QWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0QWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHRoaXMuZ2V0QWNjb3VudHNMaXN0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRBY2NvdW50c0xpc3QuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmRlbGV0ZSgnLzppZCcsXG4gICAgICB0aGlzLmRlbGV0ZUFjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZUFjY291bnQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQvYWN0aXZlJyxcbiAgICAgIHRoaXMuYWN0aXZlQWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuYWN0aXZlQWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZC9pbmFjdGl2ZScsXG4gICAgICB0aGlzLmluYWN0aXZlQWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuaW5hY3RpdmVBY2NvdW50LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmlkL3JlY2FsY3VsYXRlLWJhbGFuY2UnLFxuICAgICAgdGhpcy5yZWNhbGN1YWx0ZUJhbGFuYWNlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5yZWNhbGN1YWx0ZUJhbGFuYWNlLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmlkL3RyYW5zZmVyX2FjY291bnQvOnRvQWNjb3VudCcsXG4gICAgICB0aGlzLnRyYW5zZmVyVG9Bbm90aGVyQWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMudHJhbnNmZXJUb0Fub3RoZXJBY2NvdW50LmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgYWNjb3VudC5cbiAgICovXG4gIG5ld0FjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLmlzTGVuZ3RoKHsgbWluOiAzIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdjb2RlJykuZXhpc3RzKCkuaXNMZW5ndGgoeyBtYXg6IDEwIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50X3R5cGVfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2Rlc2NyaXB0aW9uJykub3B0aW9uYWwoKS50cmltKCkuZXNjYXBlKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZm9ybSA9IHsgLi4ucmVxLmJvZHkgfTtcblxuICAgICAgY29uc3QgZm91bmRBY2NvdW50Q29kZVByb21pc2UgPSBmb3JtLmNvZGVcbiAgICAgICAgPyBBY2NvdW50LnF1ZXJ5KCkud2hlcmUoJ2NvZGUnLCBmb3JtLmNvZGUpIDogbnVsbDtcblxuICAgICAgY29uc3QgZm91bmRBY2NvdW50VHlwZVByb21pc2UgPSBBY2NvdW50VHlwZS5xdWVyeSgpXG4gICAgICAgIC5maW5kQnlJZChmb3JtLmFjY291bnRfdHlwZV9pZCk7XG5cbiAgICAgIGNvbnN0IFtmb3VuZEFjY291bnRDb2RlLCBmb3VuZEFjY291bnRUeXBlXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgZm91bmRBY2NvdW50Q29kZVByb21pc2UsIGZvdW5kQWNjb3VudFR5cGVQcm9taXNlLFxuICAgICAgXSk7XG5cbiAgICAgIGlmIChmb3VuZEFjY291bnRDb2RlUHJvbWlzZSAmJiBmb3VuZEFjY291bnRDb2RlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ05PVF9VTklRVUVfQ09ERScsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIWZvdW5kQWNjb3VudFR5cGUpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ05PVF9FWElTVF9BQ0NPVU5UX1RZUEUnLCBjb2RlOiAyMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgQWNjb3VudC5xdWVyeSgpLmluc2VydCh7IC4uLmZvcm0gfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGl0ZW06IHsgfSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBFZGl0IHRoZSBnaXZlbiBhY2NvdW50IGRldGFpbHMuXG4gICAqL1xuICBlZGl0QWNjb3VudDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLnRvSW50KCksXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLmlzTGVuZ3RoKHsgbWluOiAzIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdjb2RlJykuZXhpc3RzKCkuaXNMZW5ndGgoeyBtYXg6IDEwIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50X3R5cGVfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2Rlc2NyaXB0aW9uJykub3B0aW9uYWwoKS50cmltKCkuZXNjYXBlKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgZm91bmRBY2NvdW50Q29kZVByb21pc2UgPSAoZm9ybS5jb2RlICYmIGZvcm0uY29kZSAhPT0gYWNjb3VudC5jb2RlKVxuICAgICAgICA/IEFjY291bnQucXVlcnkoKS53aGVyZSgnY29kZScsIGZvcm0uY29kZSkud2hlcmVOb3QoJ2lkJywgYWNjb3VudC5pZCkgOiBudWxsO1xuXG4gICAgICBjb25zdCBmb3VuZEFjY291bnRUeXBlUHJvbWlzZSA9IChmb3JtLmFjY291bnRfdHlwZV9pZCAhPT0gYWNjb3VudC5hY2NvdW50X3R5cGVfaWQpXG4gICAgICAgID8gQWNjb3VudFR5cGUucXVlcnkoKS53aGVyZSgnaWQnLCBmb3JtLmFjY291bnRfdHlwZV9pZCkgOiBudWxsO1xuXG4gICAgICBjb25zdCBbZm91bmRBY2NvdW50Q29kZSwgZm91bmRBY2NvdW50VHlwZV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGZvdW5kQWNjb3VudENvZGVQcm9taXNlLCBmb3VuZEFjY291bnRUeXBlUHJvbWlzZSxcbiAgICAgIF0pO1xuICAgICAgaWYgKGZvdW5kQWNjb3VudENvZGUubGVuZ3RoID4gMCAmJiBmb3VuZEFjY291bnRDb2RlUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnTk9UX1VOSVFVRV9DT0RFJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZEFjY291bnRUeXBlLmxlbmd0aCA8PSAwICYmIGZvdW5kQWNjb3VudFR5cGVQcm9taXNlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdOT1RfRVhJU1RfQUNDT1VOVF9UWVBFJywgY29kZTogMTEwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGFjY291bnQucGF0Y2goeyAuLi5mb3JtIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBHZXQgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGdldEFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkud2hlcmUoJ2lkJywgaWQpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghYWNjb3VudCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGFjY291bnQ6IHsgLi4uYWNjb3VudCB9IH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGRlbGV0ZUFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICBjb25zdCBhY2NvdW50VHJhbnNhY3Rpb25zID0gYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdhY2NvdW50X2lkJywgYWNjb3VudC5pZCk7XG5cbiAgICAgIGlmIChhY2NvdW50VHJhbnNhY3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0FDQ09VTlQuSEFTLkFTU09DSUFURUQuVFJBTlNBQ1RJT05TJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IEFjY291bnQucXVlcnkoKS5kZWxldGVCeUlkKGFjY291bnQuaWQpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhY2NvdW50cyBsaXN0LlxuICAgKi9cbiAgZ2V0QWNjb3VudHNMaXN0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcXVlcnkoJ2Rpc3BsYXlfdHlwZScpLm9wdGlvbmFsKCkuaXNJbihbJ3RyZWUnLCAnZmxhdCddKSxcbiAgICAgIHF1ZXJ5KCdhY2NvdW50X3R5cGVzJykub3B0aW9uYWwoKS5pc0FycmF5KCksXG4gICAgICBxdWVyeSgnYWNjb3VudF90eXBlcy4qJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ2N1c3RvbV92aWV3X2lkJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZmlsdGVyID0ge1xuICAgICAgICBhY2NvdW50X3R5cGVzOiBbXSxcbiAgICAgICAgZGlzcGxheV90eXBlOiAndHJlZScsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcbiAgICAgIGNvbnN0IHZpZXdDb25kaXRpb25hbHMgPSBbXTtcbiAgICAgIGNvbnN0IGFjY291bnRzUmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpLndoZXJlKCduYW1lJywgJ2FjY291bnRzJykuZmlyc3QoKTtcblxuICAgICAgaWYgKCFhY2NvdW50c1Jlc291cmNlKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnQUNDT1VOVFNfUkVTT1VSQ0VfTk9UX0ZPVU5EJywgY29kZTogMjAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBWaWV3LnF1ZXJ5KCkub25CdWlsZCgoYnVpbGRlcikgPT4ge1xuICAgICAgICBpZiAoZmlsdGVyLmN1c3RvbV92aWV3X2lkKSB7XG4gICAgICAgICAgYnVpbGRlci53aGVyZSgnaWQnLCBmaWx0ZXIuY3VzdG9tX3ZpZXdfaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1aWxkZXIud2hlcmUoJ2Zhdm91cml0ZScsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGJ1aWxkZXIud2hlcmUoJ3Jlc291cmNlX2lkJywgYWNjb3VudHNSZXNvdXJjZS5pZCk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgncm9sZXMuZmllbGQnKTtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCdjb2x1bW5zJyk7XG4gICAgICAgIGJ1aWxkZXIuZmlyc3QoKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodmlldyAmJiB2aWV3LnJvbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdmlld0NvbmRpdGlvbmFscy5wdXNoKFxuICAgICAgICAgIC4uLm1hcFZpZXdSb2xlc1RvQ29uZGl0aW9uYWxzKHZpZXcucm9sZXMpLFxuICAgICAgICApO1xuICAgICAgICBpZiAoIXZhbGlkYXRlVmlld1JvbGVzKHZpZXdDb25kaXRpb25hbHMsIHZpZXcucm9sZXNMb2dpY0V4cHJlc3Npb24pKSB7XG4gICAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnVklFVy5MT0dJQy5FWFBSRVNTSU9OLklOVkFMSUQnLCBjb2RlOiA0MDAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLm9uQnVpbGQoKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgYnVpbGRlci5tb2RpZnkoJ2ZpbHRlckFjY291bnRUeXBlcycsIGZpbHRlci5hY2NvdW50X3R5cGVzKTtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCd0eXBlJyk7XG5cbiAgICAgICAgaWYgKHZpZXdDb25kaXRpb25hbHMubGVuZ3RoKSB7XG4gICAgICAgICAgYnVpbGRlci5tb2RpZnkoJ3ZpZXdSb2xlc0J1aWxkZXInLCB2aWV3Q29uZGl0aW9uYWxzLCB2aWV3LnJvbGVzTG9naWNFeHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG5lc3RlZEFjY291bnRzID0gbmV3IE5lc3RlZFNldChhY2NvdW50cywgeyBwYXJlbnRJZDogJ3BhcmVudEFjY291bnRJZCcgfSk7XG4gICAgICBjb25zdCBncm91cHNBY2NvdW50cyA9IG5lc3RlZEFjY291bnRzLnRvVHJlZSgpO1xuICAgICAgY29uc3QgYWNjb3VudHNMaXN0ID0gW107XG5cbiAgICAgIGlmIChmaWx0ZXIuZGlzcGxheV90eXBlID09PSAndHJlZScpIHtcbiAgICAgICAgYWNjb3VudHNMaXN0LnB1c2goLi4uZ3JvdXBzQWNjb3VudHMpO1xuICAgICAgfSBlbHNlIGlmIChmaWx0ZXIuZGlzcGxheV90eXBlID09PSAnZmxhdCcpIHtcbiAgICAgICAgY29uc3QgZmxhdHRlbkFjY291bnRzID0gbmVzdGVkQWNjb3VudHMuZmxhdHRlblRyZWUoKGFjY291bnQsIHBhcmVudEFjY291bnQpID0+IHtcbiAgICAgICAgICBpZiAocGFyZW50QWNjb3VudCkge1xuICAgICAgICAgICAgYWNjb3VudC5uYW1lID0gYCR7cGFyZW50QWNjb3VudC5uYW1lfSDigJUgJHthY2NvdW50Lm5hbWV9YDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIGFjY291bnQ7XG4gICAgICAgIH0pO1xuICAgICAgICBhY2NvdW50c0xpc3QucHVzaCguLi5mbGF0dGVuQWNjb3VudHMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgYWNjb3VudHM6IGFjY291bnRzTGlzdCxcbiAgICAgICAgLi4uKHZpZXcpID8ge1xuICAgICAgICAgIGN1c3RvbVZpZXdJZDogdmlldy5pZCxcbiAgICAgICAgfSA6IHt9LFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmUtY2FsY3VsYXRlcyBiYWxhbmNlIG9mIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKi9cbiAgcmVjYWxjdWFsdGVCYWxhbmFjZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IEFjY291bnQuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdBQ0NPVU5ULk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBhY2NvdW50VHJhbnNhY3Rpb25zID0gQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdhY2NvdW50X2lkJywgYWNjb3VudC5pZCk7XG5cbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmxvYWRGcm9tQ29sbGVjdGlvbihhY2NvdW50VHJhbnNhY3Rpb25zKTtcblxuICAgICAgLy8gRGVsZXRlIHRoZSBiYWxhbmNlIG9mIHRoZSBnaXZlbiBhY2NvdW50IGlkLlxuICAgICAgYXdhaXQgQWNjb3VudEJhbGFuY2UucXVlcnkoKS53aGVyZSgnYWNjb3VudF9pZCcsIGFjY291bnQuaWQpLmRlbGV0ZSgpO1xuXG4gICAgICAvLyBTYXZlIGNhbGN1YWx0ZWQgYWNjb3VudCBiYWxhbmNlLlxuICAgICAgYXdhaXQgam91cm5hbEVudHJpZXMuc2F2ZUJhbGFuY2UoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogQWN0aXZlIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKi9cbiAgYWN0aXZlQWNjb3VudDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IEFjY291bnQuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdBQ0NPVU5ULk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBhY2NvdW50LnBhdGNoKHsgYWN0aXZlOiB0cnVlIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogYWNjb3VudC5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBJbmFjdGl2ZSB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGluYWN0aXZlQWNjb3VudDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IEFjY291bnQuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdBQ0NPVU5ULk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBhY2NvdW50LnBhdGNoKHsgYWN0aXZlOiBmYWxzZSB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGFjY291bnQuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogVHJhbnNmZXIgYWxsIGpvdXJuYWwgZW50cmllcyBvZiB0aGUgZ2l2ZW4gYWNjb3VudCB0byBhbm90aGVyIGFjY291bnQuXG4gICAqL1xuICB0cmFuc2ZlclRvQW5vdGhlckFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcGFyYW0oJ3RvQWNjb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBjb25zdCB7IGlkLCB0b0FjY291bnQ6IHRvQWNjb3VudElkIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICAvLyBjb25zdCBbZnJvbUFjY291bnQsIHRvQWNjb3VudF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAvLyAgIEFjY291bnQucXVlcnkoKS5maW5kQnlJZChpZCksXG4gICAgICAvLyAgIEFjY291bnQucXVlcnkoKS5maW5kQnlJZCh0b0FjY291bnRJZCksXG4gICAgICAvLyBdKTtcblxuICAgICAgLy8gY29uc3QgZnJvbUFjY291bnRUcmFuc2FjdGlvbnMgPSBhd2FpdCBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKVxuICAgICAgLy8gICAud2hlcmUoJ2FjY291bnRfaWQnLCBmcm9tQWNjb3VudCk7XG5cbiAgICAgIC8vIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiXG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGNoZWNrLCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgZnMgZnJvbSAnZnMnO1xuaW1wb3J0IE11c3RhY2hlIGZyb20gJ211c3RhY2hlJztcbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IFVzZXIgZnJvbSAnQC9tb2RlbHMvVXNlcic7XG5pbXBvcnQgUGFzc3dvcmRSZXNldCBmcm9tICdAL21vZGVscy9QYXNzd29yZFJlc2V0JztcbmltcG9ydCBtYWlsIGZyb20gJ0Avc2VydmljZXMvbWFpbCc7XG5pbXBvcnQgeyBoYXNoUGFzc3dvcmQgfSBmcm9tICdAL3V0aWxzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogQ29uc3RydWN0b3IgbWV0aG9kLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIucG9zdCgnL2xvZ2luJyxcbiAgICAgIHRoaXMubG9naW4udmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmxvZ2luLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvc2VuZF9yZXNldF9wYXNzd29yZCcsXG4gICAgICB0aGlzLnNlbmRSZXNldFBhc3N3b3JkLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5zZW5kUmVzZXRQYXNzd29yZC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnL3Jlc2V0Lzp0b2tlbicsXG4gICAgICB0aGlzLnJlc2V0UGFzc3dvcmQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlc2V0UGFzc3dvcmQuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogVXNlciBsb2dpbiBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LlxuICAgKi9cbiAgbG9naW46IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnY3JlZGllbnRpYWwnKS5leGlzdHMoKS5pc0VtYWlsKCksXG4gICAgICBjaGVjaygncGFzc3dvcmQnKS5leGlzdHMoKS5pc0xlbmd0aCh7IG1pbjogNCB9KSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGNyZWRpZW50aWFsLCBwYXNzd29yZCB9ID0gcmVxLmJvZHk7XG4gICAgICBjb25zdCB7IEpXVF9TRUNSRVRfS0VZIH0gPSBwcm9jZXNzLmVudjtcblxuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXIucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ2VtYWlsJywgY3JlZGllbnRpYWwpXG4gICAgICAgIC5vcldoZXJlKCdwaG9uZV9udW1iZXInLCBjcmVkaWVudGlhbClcbiAgICAgICAgLmZpcnN0KCk7XG5cbiAgICAgIGlmICghdXNlcikge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnSU5WQUxJRF9ERVRBSUxTJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghdXNlci52ZXJpZnlQYXNzd29yZChwYXNzd29yZCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0lOVkFMSURfREVUQUlMUycsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXIuYWN0aXZlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdVU0VSX0lOQUNUSVZFJywgY29kZTogMTEwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIC8vIHVzZXIudXBkYXRlKHsgbGFzdF9sb2dpbl9hdDogbmV3IERhdGUoKSB9KTtcblxuICAgICAgY29uc3QgdG9rZW4gPSBqd3Quc2lnbih7XG4gICAgICAgIGVtYWlsOiB1c2VyLmVtYWlsLFxuICAgICAgICBfaWQ6IHVzZXIuaWQsXG4gICAgICB9LCBKV1RfU0VDUkVUX0tFWSwge1xuICAgICAgICBleHBpcmVzSW46ICcxZCcsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IHRva2VuLCB1c2VyIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFNlbmQgcmVzZXQgcGFzc3dvcmQgbGluayB2aWEgZW1haWwgb3IgU01TLlxuICAgKi9cbiAgc2VuZFJlc2V0UGFzc3dvcmQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnZW1haWwnKS5leGlzdHMoKS5pc0VtYWlsKCksXG4gICAgXSxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBlbWFpbCB9ID0gcmVxLmJvZHk7XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci53aGVyZSgnZW1haWwnLCBlbWFpbCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQyMikuc2VuZCgpO1xuICAgICAgfVxuICAgICAgLy8gRGVsZXRlIGFsbCBzdG9yZWQgdG9rZW5zIG9mIHJlc2V0IHBhc3N3b3JkIHRoYXQgYXNzb2NpYXRlIHRvIHRoZSBnaXZlIGVtYWlsLlxuICAgICAgYXdhaXQgUGFzc3dvcmRSZXNldC53aGVyZSh7IGVtYWlsIH0pLmRlc3Ryb3koeyByZXF1aXJlOiBmYWxzZSB9KTtcblxuICAgICAgY29uc3QgcGFzc3dvcmRSZXNldCA9IFBhc3N3b3JkUmVzZXQuZm9yZ2Uoe1xuICAgICAgICBlbWFpbCxcbiAgICAgICAgdG9rZW46ICcxMjMxMjMnLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBwYXNzd29yZFJlc2V0LnNhdmUoKTtcblxuICAgICAgY29uc3QgZmlsZVBhdGggPSBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vLi4vdmlld3MvbWFpbC9SZXNldFBhc3N3b3JkLmh0bWwnKTtcbiAgICAgIGNvbnN0IHRlbXBsYXRlID0gZnMucmVhZEZpbGVTeW5jKGZpbGVQYXRoLCAndXRmOCcpO1xuICAgICAgY29uc3QgcmVuZGVyZWQgPSBNdXN0YWNoZS5yZW5kZXIodGVtcGxhdGUsIHtcbiAgICAgICAgdXJsOiBgJHtyZXEucHJvdG9jb2x9Oi8vJHtyZXEuaG9zdG5hbWV9L3Jlc2V0LyR7cGFzc3dvcmRSZXNldC5hdHRyaWJ1dGVzLnRva2VufWAsXG4gICAgICAgIGZpcnN0X25hbWU6IHVzZXIuYXR0cmlidXRlcy5maXJzdF9uYW1lLFxuICAgICAgICBsYXN0X25hbWU6IHVzZXIuYXR0cmlidXRlcy5sYXN0X25hbWUsXG4gICAgICAgIGNvbnRhY3RfdXNfZW1haWw6IHByb2Nlc3MuZW52LkNPTlRBQ1RfVVNfRU1BSUwsXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgbWFpbE9wdGlvbnMgPSB7XG4gICAgICAgIHRvOiB1c2VyLmF0dHJpYnV0ZXMuZW1haWwsXG4gICAgICAgIGZyb206IGAke3Byb2Nlc3MuZW52Lk1BSUxfRlJPTV9OQU1FfSAke3Byb2Nlc3MuZW52Lk1BSUxfRlJPTV9BRERSRVNTfWAsXG4gICAgICAgIHN1YmplY3Q6ICdSYXR0ZWIgUGFzc3dvcmQgUmVzZXQnLFxuICAgICAgICBodG1sOiByZW5kZXJlZCxcbiAgICAgIH07XG5cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb25zaXN0ZW50LXJldHVyblxuICAgICAgbWFpbC5zZW5kTWFpbChtYWlsT3B0aW9ucywgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgZGF0YTogeyBlbWFpbDogcGFzc3dvcmRSZXNldC5hdHRyaWJ1dGVzLmVtYWlsIH0gfSk7XG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXNldCBwYXNzd29yZC5cbiAgICovXG4gIHJlc2V0UGFzc3dvcmQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygncGFzc3dvcmQnKS5leGlzdHMoKS5pc0xlbmd0aCh7IG1pbjogNSB9KS5jdXN0b20oKHZhbHVlLCB7IHJlcSB9KSA9PiB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gcmVxLmJvZHkuY29uZmlybV9wYXNzd29yZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBhc3N3b3JkcyBkb24ndCBtYXRjaFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ1ZBTElEQVRJT05fRVJST1InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgdG9rZW4gfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB7IHBhc3N3b3JkIH0gPSByZXEuYm9keTtcblxuICAgICAgY29uc3QgdG9rZW5Nb2RlbCA9IGF3YWl0IFBhc3N3b3JkUmVzZXQucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ3Rva2VuJywgdG9rZW4pXG4gICAgICAgIC53aGVyZSgnY3JlYXRlZF9hdCcsICc+PScsIERhdGUubm93KCkgLSAzNjAwMDAwKVxuICAgICAgICAuZmlyc3QoKTtcblxuICAgICAgaWYgKCF0b2tlbk1vZGVsKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdUT0tFTl9JTlZBTElEJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBVc2VyLndoZXJlKHtcbiAgICAgICAgZW1haWw6IHRva2VuTW9kZWwuZW1haWwsXG4gICAgICB9KTtcbiAgICAgIGlmICghdXNlcikge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnVVNFUl9OT1RfRk9VTkQnLCBjb2RlOiAxMjAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgaGFzaGVkUGFzc3dvcmQgPSBhd2FpdCBoYXNoUGFzc3dvcmQocGFzc3dvcmQpO1xuXG4gICAgICB1c2VyLnBhc3N3b3JkID0gaGFzaGVkUGFzc3dvcmQ7XG4gICAgICBhd2FpdCB1c2VyLnNhdmUoKTtcblxuICAgICAgYXdhaXQgUGFzc3dvcmRSZXNldC53aGVyZSgnZW1haWwnLCB1c2VyLmdldCgnZW1haWwnKSkuZGVzdHJveSh7IHJlcXVpcmU6IGZhbHNlIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe30pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQge1xuICBjaGVjayxcbiAgcXVlcnksXG4gIHBhcmFtLFxuICB2YWxpZGF0aW9uUmVzdWx0LFxufSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgeyBwaWNrLCBkaWZmZXJlbmNlLCBncm91cEJ5IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSBcIkAvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZVwiO1xuaW1wb3J0IEpXVEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgQnVkZ2V0IGZyb20gJ0AvbW9kZWxzL0J1ZGdldCc7XG5pbXBvcnQgQnVkZ2V0RW50cnkgZnJvbSAnQC9tb2RlbHMvQnVkZ2V0RW50cnknO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ0Avc2VydmljZXMvTW9tZW50JztcbmltcG9ydCBCdWRnZXRFbnRyaWVzU2V0IGZyb20gJ0AvY29sbGVjdGlvbi9CdWRnZXRFbnRyaWVzU2V0JztcbmltcG9ydCBBY2NvdW50VHlwZSBmcm9tICdAL21vZGVscy9BY2NvdW50VHlwZSc7XG5pbXBvcnQgTmVzdGVkU2V0IGZyb20gJ0AvY29sbGVjdGlvbi9OZXN0ZWRTZXQnO1xuaW1wb3J0IHsgZGF0ZVJhbmdlRm9ybWF0IH0gZnJvbSAnQC91dGlscyc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIudXNlKEpXVEF1dGgpO1xuXG4gICAgcm91dGVyLnBvc3QoJy8nLFxuICAgICAgdGhpcy5uZXdCdWRnZXQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm5ld0J1ZGdldC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvOmlkJyxcbiAgICAgIHRoaXMuZ2V0QnVkZ2V0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRCdWRnZXQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLzppZCcsXG4gICAgICB0aGlzLmRlbGV0ZUJ1ZGdldC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlQnVkZ2V0LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgdGhpcy5saXN0QnVkZ2V0cy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubGlzdEJ1ZGdldHMuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgYnVkZ2V0IGRldGFpbHMgb2YgdGhlIGdpdmVuIGlkLlxuICAgKi9cbiAgZ2V0QnVkZ2V0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgYnVkZ2V0ID0gYXdhaXQgQnVkZ2V0LnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWJ1ZGdldCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ2J1ZGdldC5ub3QuZm91bmQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYWNjb3VudFR5cGVzID0gYXdhaXQgQWNjb3VudFR5cGUucXVlcnkoKS53aGVyZSgnYmFsYW5jZV9zaGVldCcsIHRydWUpO1xuXG4gICAgICBjb25zdCBbYnVkZ2V0RW50cmllcywgYWNjb3VudHNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBCdWRnZXRFbnRyeS5xdWVyeSgpLndoZXJlKCdidWRnZXRfaWQnLCBidWRnZXQuaWQpLFxuICAgICAgICBBY2NvdW50LnF1ZXJ5KCkud2hlcmVJbignYWNjb3VudF90eXBlX2lkJywgYWNjb3VudFR5cGVzLm1hcCgoYSkgPT4gYS5pZCkpLFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IGFjY291bnRzTmVzdGVkU2V0ID0gbmV3IE5lc3RlZFNldChhY2NvdW50cyk7XG5cbiAgICAgIGNvbnN0IGNvbHVtbnMgPSBbXTtcbiAgICAgIGNvbnN0IGZyb21EYXRlID0gbW9tZW50KGJ1ZGdldC55ZWFyKS5zdGFydE9mKCd5ZWFyJylcbiAgICAgICAgLmFkZChidWRnZXQucmFuZ2VPZmZzZXQsIGJ1ZGdldC5yYW5nZUJ5KS50b0RhdGUoKTtcblxuICAgICAgY29uc3QgdG9EYXRlID0gbW9tZW50KGJ1ZGdldC55ZWFyKS5lbmRPZigneWVhcicpLnRvRGF0ZSgpO1xuXG4gICAgICBjb25zdCBkYXRlUmFuZ2UgPSBtb21lbnQucmFuZ2UoZnJvbURhdGUsIHRvRGF0ZSk7XG4gICAgICBjb25zdCBkYXRlUmFuZ2VDb2xsZWN0aW9uID0gQXJyYXkuZnJvbShkYXRlUmFuZ2UuYnkoYnVkZ2V0LnJhbmdlQnksIHtcbiAgICAgICAgc3RlcDogYnVkZ2V0LnJhbmdlSW5jcmVtZW50LCBleGNsdWRlRW5kOiBmYWxzZSwgZXhjbHVkZVN0YXJ0OiBmYWxzZSxcbiAgICAgIH0pKTtcblxuICAgICAgZGF0ZVJhbmdlQ29sbGVjdGlvbi5mb3JFYWNoKChkYXRlKSA9PiB7XG4gICAgICAgIGNvbHVtbnMucHVzaChkYXRlLmZvcm1hdChkYXRlUmFuZ2VGb3JtYXQoYnVkZ2V0LnJhbmdlQnkpKSk7XG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGJ1ZGdldEVudHJpZXNTZXQgPSBCdWRnZXRFbnRyaWVzU2V0LmZyb20oYnVkZ2V0RW50cmllcywge1xuICAgICAgICBvcmRlclNpemU6IGNvbHVtbnMubGVuZ3RoLFxuICAgICAgfSk7XG4gICAgICBidWRnZXRFbnRyaWVzU2V0LnNldFplcm9QbGFjZWhvbGRlcigpO1xuICAgICAgYnVkZ2V0RW50cmllc1NldC5jYWxjVG90YWxTdW1tYXJ5KCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGNvbHVtbnMsXG4gICAgICAgIGFjY291bnRzOiBidWRnZXRFbnRyaWVzU2V0LnRvQXJyYXkoKSxcbiAgICAgICAgdG90YWw6IGJ1ZGdldEVudHJpZXNTZXQudG9BcnJheVRvdGFsU3VtbWFyeSgpLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlbiBidWRnZXQuXG4gICAqL1xuICBkZWxldGVCdWRnZXQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBidWRnZXQgPSBhd2FpdCBCdWRnZXQucXVlcnkoKS5maW5kQnlJZChpZCk7XG5cbiAgICAgIGlmICghYnVkZ2V0KSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnYnVkZ2V0Lm5vdC5mb3VuZCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBCdWRnZXRFbnRyeS5xdWVyeSgpLndoZXJlKCdidWRnZXRfaWQnLCBidWRnZXQuaWQpLmRlbGV0ZSgpO1xuICAgICAgYXdhaXQgYnVkZ2V0LmRlbGV0ZSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBTYXZlcyB0aGUgbmV3IGJ1ZGdldC5cbiAgICovXG4gIG5ld0J1ZGdldDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCduYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnZmlzY2FsX3llYXInKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdwZXJpb2QnKS5leGlzdHMoKS5pc0luKFsneWVhcicsICdtb250aCcsICdxdWFydGVyJywgJ2hhbGYteWVhciddKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50c190eXBlJykuZXhpc3RzKCkuaXNJbihbJ2JhbGFuY2Vfc2hlZXQnLCAncHJvZml0X2xvc3MnXSksXG4gICAgICBjaGVjaygnYWNjb3VudHMnKS5pc0FycmF5KCksXG4gICAgICBjaGVjaygnYWNjb3VudHMuKi5hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50cy4qLmVudHJpZXMnKS5leGlzdHMoKS5pc0FycmF5KCksXG4gICAgICBjaGVjaygnYWNjb3VudHMuKi5lbnRyaWVzLiouYW1vdW50JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgY2hlY2soJ2FjY291bnRzLiouZW50cmllcy4qLm9yZGVyJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBzdWJtaXRBY2NvdW50c0lkcyA9IGZvcm0uYWNjb3VudHMubWFwKChhKSA9PiBhLmFjY291bnRfaWQpO1xuICAgICAgY29uc3Qgc3RvcmVkQWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkud2hlcmVJbignaWQnLCBzdWJtaXRBY2NvdW50c0lkcyk7XG4gICAgICBjb25zdCBzdG9yZWRBY2NvdW50c0lkcyA9IHN0b3JlZEFjY291bnRzLm1hcCgoYSkgPT4gYS5pZCk7XG5cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3Qgbm90Rm91bmRBY2NvdW50c0lkcyA9IGRpZmZlcmVuY2Uoc3VibWl0QWNjb3VudHNJZHMsIHN0b3JlZEFjY291bnRzSWRzKTtcblxuICAgICAgaWYgKG5vdEZvdW5kQWNjb3VudHNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ0FDQ09VTlQuTk9ULkZPVU5EJywgY29kZTogMjAwLCBhY2NvdW50czogbm90Rm91bmRBY2NvdW50c0lkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICAvLyB2YWxpZGF0aW9uIGVudHJpZXMgb3JkZXIuXG4gICAgICBjb25zdCBidWRnZXQgPSBhd2FpdCBCdWRnZXQucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAuLi5waWNrKGZvcm0sIFsnbmFtZScsICdmaXNjYWxfeWVhcicsICdwZXJpb2QnLCAnYWNjb3VudHNfdHlwZSddKSxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBwcm9taXNlT3BlcnMgPSBbXTtcblxuICAgICAgZm9ybS5hY2NvdW50cy5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG4gICAgICAgIGFjY291bnQuZW50cmllcy5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGJ1ZGdldEVudHJ5ID0gQnVkZ2V0RW50cnkucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudC5hY2NvdW50X2lkLFxuICAgICAgICAgICAgYW1vdW50OiBlbnRyeS5hbW91bnQsXG4gICAgICAgICAgICBvcmRlcjogZW50cnkub3JkZXIsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgcHJvbWlzZU9wZXJzLnB1c2goYnVkZ2V0RW50cnkpO1xuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwocHJvbWlzZU9wZXJzKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGJ1ZGdldC5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHBhZ2luYXRlZCBidWRnZXRzIGl0ZW1zLlxuICAgKi9cbiAgbGlzdEJ1ZGdldHM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgneWVhcicpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnaW5jb21lX3N0YXRlbWVudCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgncHJvZml0X2xvc3MnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgICAgcXVlcnkoJ3BhZ2UnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgncGFnZV9zaXplJykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdjdXN0b21fdmlld19pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgcGFnZV9zaXplOiAxMCxcbiAgICAgICAgcGFnZTogMSxcbiAgICAgICAgLi4ucmVxLnF1ZXJ5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGJ1ZGdldHMgPSBhd2FpdCBCdWRnZXQucXVlcnkoKS5ydW5CZWZvcmUoKHJlc3VsdCwgcSkgPT4ge1xuICAgICAgICBpZiAoZmlsdGVyLnByb2ZpdF9sb3NzKSB7XG4gICAgICAgICAgcS5tb2RpZnkoJ2ZpbHRlckJ5WWVhcicsIGZpbHRlci55ZWFyKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLmluY29tZV9zdGF0ZW1lbnQpIHtcbiAgICAgICAgICBxLm1vZGlmeSgnZmlsdGVyQnlJbmNvbWVTdGF0ZW1lbnQnLCBmaWx0ZXIuaW5jb21lX3N0YXRlbWVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5wcm9maXRfbG9zcykge1xuICAgICAgICAgIHEubW9kaWZ5KCdmaWx0ZXJCeVByb2ZpdExvc3MnLCBmaWx0ZXIucHJvZml0X2xvc3MpO1xuICAgICAgICB9XG4gICAgICAgIHEucGFnZShmaWx0ZXIucGFnZSwgZmlsdGVyLnBhZ2Vfc2l6ZSk7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGl0ZW1zOiBidWRnZXRzLml0ZW1zLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IHF1ZXJ5LCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IGp3dEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgQnVkZ2V0IGZyb20gJ0AvbW9kZWxzL0J1ZGdldCc7XG5pbXBvcnQgQWNjb3VudCBmcm9tICdAL21vZGVscy9BY2NvdW50JztcbmltcG9ydCBBY2NvdW50VHlwZSBmcm9tICdAL21vZGVscy9BY2NvdW50VHlwZSc7XG5pbXBvcnQgTmVzdGVkU2V0IGZyb20gJ0AvY29sbGVjdGlvbi9OZXN0ZWRTZXQnO1xuaW1wb3J0IEJ1ZGdldEVudHJ5IGZyb20gJ0AvbW9kZWxzL0J1ZGdldEVudHJ5JztcbmltcG9ydCB7IGRhdGVSYW5nZUZvcm1hdCB9IGZyb20gJ0AvdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnVzZShqd3RBdXRoKTtcblxuICAgIHJvdXRlci5nZXQoJy9idWRnZXRfdmVyc2VzX2FjdHVhbC86cmVwb3J0SWQnLFxuICAgICAgdGhpcy5idWRnZXRWZXJzZXNBY3R1YWwudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmJ1ZGdldFZlcnNlc0FjdHVhbC5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIGJ1ZGdldFZlcnNlc0FjdHVhbDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCkuaXNJbihbJ2Nhc2gnLCAnYWNjdXJhbCddKSxcbiAgICAgIHF1ZXJ5KCdwZXJpb2QnKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ2FjdGl2ZV9hY2NvdW50cycpLm9wdGlvbmFsKCkudG9Cb29sZWFuKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyByZXBvcnRJZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcblxuICAgICAgY29uc3QgYnVkZ2V0ID0gYXdhaXQgQnVkZ2V0LnF1ZXJ5KCkuZmluZEJ5SWQocmVwb3J0SWQpO1xuXG4gICAgICBpZiAoIWJ1ZGdldCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdCVURHRVRfTk9UX0ZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYnVkZ2V0RW50cmllcyA9IGF3YWl0IEJ1ZGdldEVudHJ5LnF1ZXJ5KCkud2hlcmUoJ2J1ZGdldF9pZCcsIGJ1ZGdldC5pZCk7XG5cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjY291bnRUeXBlcyA9IGF3YWl0IEFjY291bnRUeXBlLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdiYWxhbmNlX3NoZWV0JywgYnVkZ2V0LmFjY291bnRUeXBlcyA9PT0gJ2JhbGFuY2Vfc2hlZXQnKVxuICAgICAgICAud2hlcmUoJ2luY29tZV9zaGVldCcsIGJ1ZGdldC5hY2NvdW50VHlwZXMgPT09ICdwcm9maXRfbG9zc3MnKTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkucnVuQmVmb3JlKChyZXN1bHQsIHEpID0+IHtcbiAgICAgICAgY29uc3QgYWNjb3VudFR5cGVzSWRzID0gYWNjb3VudFR5cGVzLm1hcCgodCkgPT4gdC5pZCk7XG5cbiAgICAgICAgaWYgKGFjY291bnRUeXBlc0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcS53aGVyZUluKCdhY2NvdW50X3R5cGVfaWQnLCBhY2NvdW50VHlwZXNJZHMpO1xuICAgICAgICB9XG4gICAgICAgIHEud2hlcmUoJ2FjdGl2ZScsIGZvcm0uYWN0aXZlX2FjY291bnRzID09PSB0cnVlKTtcbiAgICAgICAgcS53aXRoR3JhcGhGZXRjaGVkKCd0cmFuc2FjdGlvbnMnKTtcbiAgICAgIH0pO1xuICAgICAgICBcbiAgICAgIC8vIGNvbnN0IGFjY291bnRzTmVzdGVkU2V0ID0gTmVzdGVkU2V0LmZyb20oYWNjb3VudHMpO1xuXG4gICAgICBjb25zdCBmcm9tRGF0ZSA9IG1vbWVudChidWRnZXQueWVhcikuc3RhcnRPZigneWVhcicpXG4gICAgICAgIC5hZGQoYnVkZ2V0LnJhbmdlT2Zmc2V0LCBidWRnZXQucmFuZ2VCeSkudG9EYXRlKCk7XG5cbiAgICAgIGNvbnN0IHRvRGF0ZSA9IG1vbWVudChidWRnZXQueWVhcikuZW5kT2YoJ3llYXInKS50b0RhdGUoKTtcblxuICAgICAgY29uc3QgZGF0ZVJhbmdlID0gbW9tZW50LnJhbmdlKGZyb21EYXRlLCB0b0RhdGUpO1xuICAgICAgY29uc3QgZGF0ZVJhbmdlQ29sbGVjdGlvbiA9IEFycmF5LmZyb20oZGF0ZVJhbmdlLmJ5KGJ1ZGdldC5yYW5nZUJ5LCB7XG4gICAgICAgIHN0ZXA6IGJ1ZGdldC5yYW5nZUluY3JlbWVudCwgZXhjbHVkZUVuZDogZmFsc2UsIGV4Y2x1ZGVTdGFydDogZmFsc2UsXG4gICAgICB9KSk7XG5cbiAgICAvLyAgIC8vIGNvbnN0IGFjY291bnRzID0ge1xuICAgIC8vICAgLy8gICBhc3NldHM6IFtcbiAgICAvLyAgIC8vICAgICB7XG4gICAgLy8gICAvLyAgICAgICBuYW1lOiAnJyxcbiAgICAvLyAgIC8vICAgICAgIGNvZGU6ICcnLFxuICAgIC8vICAgLy8gICAgICAgdG90YWxFbnRyaWVzOiBbXG4gICAgLy8gICAvLyAgICAgICAgIHtcblxuICAgIC8vICAgLy8gICAgICAgICB9XG4gICAgLy8gICAvLyAgICAgICBdLFxuICAgIC8vICAgLy8gICAgICAgY2hpbGRyZW46IFtcbiAgICAvLyAgIC8vICAgICAgICAge1xuICAgIC8vICAgLy8gICAgICAgICAgIG5hbWU6ICcnLFxuICAgIC8vICAgLy8gICAgICAgICAgIGNvZGU6ICcnLFxuICAgIC8vICAgLy8gICAgICAgICAgIGVudHJpZXM6IFtcbiAgICAvLyAgIC8vICAgICAgICAgICAgIHtcblxuICAgIC8vICAgLy8gICAgICAgICAgICAgfVxuICAgIC8vICAgLy8gICAgICAgICAgIF1cbiAgICAvLyAgIC8vICAgICAgICAgfVxuICAgIC8vICAgLy8gICAgICAgXVxuICAgIC8vICAgLy8gICAgIH1cbiAgICAvLyAgIC8vICAgXVxuICAgIC8vICAgLy8gfVxuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBjb2x1bW5zOiBkYXRlUmFuZ2VDb2xsZWN0aW9uLm1hcChkID0+IGQuZm9ybWF0KGRhdGVSYW5nZUZvcm1hdChidWRnZXQucmFuZ2VCeSkpKSxcbiAgICAgICAgLy8gYWNjb3VudHM6IHtcbiAgICAgICAgLy8gICBhc3NldDogW10sXG4gICAgICAgIC8vICAgbGlhYmlsaXRpZXM6IFtdLFxuICAgICAgICAvLyAgIGVxdWFpdHk6IFtdLFxuXG4gICAgICAgIC8vICAgaW5jb21lOiBbXSxcbiAgICAgICAgLy8gICBleHBlbnNlczogW10sXG4gICAgICAgIC8vIH1cbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59IiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcblxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLmdldCgnL2FsbCcsXG4gICAgICB0aGlzLmFsbC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuYWxsLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy9yZWdpc3RlcmVkJyxcbiAgICAgIHRoaXMucmVnaXN0ZXJlZC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMucmVnaXN0ZXJlZC5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIGFsbDoge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgY3VycmVuY2llczogW1xuICAgICAgICAgIHsgY3VycmVuY3lfY29kZTogJ1VTRCcsIGN1cnJlbmN5X3NpZ246ICckJyB9LFxuICAgICAgICAgIHsgY3VycmVuY3lfY29kZTogJ0xZRCcsIGN1cnJlbmN5X3NpZ246ICcnIH0sXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIHJlZ2lzdGVyZWQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGN1cnJlbmNpZXM6IFtcbiAgICAgICAgICB7IGN1cnJlbmN5X2NvZGU6ICdVU0QnLCBjdXJyZW5jeV9zaWduOiAnJCcgfSxcbiAgICAgICAgICB7IGN1cnJlbmN5X2NvZGU6ICdMWUQnLCBjdXJyZW5jeV9zaWduOiAnJyB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcbn07IiwiXG5leHBvcnQgZGVmYXVsdCB7XG5cblxuICByb3V0ZXIoKSB7XG5cbiAgfSxcbiAgXG4gIGFkZEV4Y2hhbmdlUHJpY2U6IHtcbiAgICB2YWxpZGF0aW9uOiB7XG4gICAgICBcbiAgICB9LFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcblxuICAgIH0sXG4gIH0sXG59IiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQge1xuICBjaGVjayxcbiAgcGFyYW0sXG4gIHF1ZXJ5LFxuICB2YWxpZGF0aW9uUmVzdWx0LFxufSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBkaWZmZXJlbmNlLCBjaGFpbiwgb21pdCB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgRXhwZW5zZSBmcm9tICdAL21vZGVscy9FeHBlbnNlJztcbmltcG9ydCBBY2NvdW50IGZyb20gJ0AvbW9kZWxzL0FjY291bnQnO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IEpvdXJuYWxFbnRyeSBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbEVudHJ5JztcbmltcG9ydCBKV1RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEFjY291bnRUcmFuc2FjdGlvbiBmcm9tICdAL21vZGVscy9BY2NvdW50VHJhbnNhY3Rpb24nO1xuaW1wb3J0IFZpZXcgZnJvbSAnQC9tb2RlbHMvVmlldyc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnLi4vLi4vbW9kZWxzL1Jlc291cmNlJztcbmltcG9ydCBSZXNvdXJjZUN1c3RvbUZpZWxkUmVwb3NpdG9yeSBmcm9tICdAL3NlcnZpY2VzL0N1c3RvbUZpZWxkcy9SZXNvdXJjZUN1c3RvbUZpZWxkUmVwb3NpdG9yeSc7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVZpZXdSb2xlcyxcbiAgbWFwVmlld1JvbGVzVG9Db25kaXRpb25hbHMsXG59IGZyb20gJ0AvbGliL1ZpZXdSb2xlc0J1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIudXNlKEpXVEF1dGgpO1xuXG4gICAgcm91dGVyLnBvc3QoJy8nLFxuICAgICAgdGhpcy5uZXdFeHBlbnNlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdFeHBlbnNlLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmlkL3B1Ymxpc2gnLFxuICAgICAgdGhpcy5wdWJsaXNoRXhwZW5zZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMucHVibGlzaEV4cGVuc2UuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmRlbGV0ZSgnLzppZCcsXG4gICAgICB0aGlzLmRlbGV0ZUV4cGVuc2UudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZUV4cGVuc2UuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9idWxrJyxcbiAgICAgIHRoaXMuYnVsa0FkZEV4cGVuc2VzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5idWxrQWRkRXhwZW5zZXMuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgdGhpcy51cGRhdGVFeHBlbnNlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy51cGRhdGVFeHBlbnNlLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgdGhpcy5saXN0RXhwZW5zZXMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmxpc3RFeHBlbnNlcy5oYW5kbGVyKSk7XG5cbiAgICAvLyByb3V0ZXIuZ2V0KCcvOmlkJyxcbiAgICAvLyAgIHRoaXMuZ2V0RXhwZW5zZS52YWxpZGF0aW9uLFxuICAgIC8vICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0RXhwZW5zZS5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBTYXZlcyBhIG5ldyBleHBlbnNlLlxuICAgKi9cbiAgbmV3RXhwZW5zZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdkYXRlJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdwYXltZW50X2FjY291bnRfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2V4cGVuc2VfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2Ftb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdjdXJyZW5jeV9jb2RlJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdleGNoYW5nZV9yYXRlJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgICBjaGVjaygncHVibGlzaCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBjaGVjaygnY3VzdG9tX2ZpZWxkcycpLm9wdGlvbmFsKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzLioua2V5JykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ2N1c3RvbV9maWVsZHMuKi52YWx1ZScpLmV4aXN0cygpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7XG4gICAgICAgIGRhdGU6IG5ldyBEYXRlKCksXG4gICAgICAgIHB1Ymxpc2hlZDogZmFsc2UsXG4gICAgICAgIGN1c3RvbV9maWVsZHM6IFtdLFxuICAgICAgICAuLi5yZXEuYm9keSxcbiAgICAgIH07XG4gICAgICAvLyBDb252ZXJ0IHRoZSBkYXRlIHRvIHRoZSBnZW5lcmFsIGZvcm1hdC5cbiAgICAgIGZvcm0uZGF0ZSA9IG1vbWVudChmb3JtLmRhdGUpLmZvcm1hdCgnWVlZWS1NTS1ERCcpO1xuXG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcbiAgICAgIGNvbnN0IHBheW1lbnRBY2NvdW50ID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpXG4gICAgICAgIC5maW5kQnlJZChmb3JtLnBheW1lbnRfYWNjb3VudF9pZCkuZmlyc3QoKTtcblxuICAgICAgaWYgKCFwYXltZW50QWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdQQVlNRU5ULkFDQ09VTlQuTk9ULkZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZW5zZUFjY291bnQgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5leHBlbnNlX2FjY291bnRfaWQpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghZXhwZW5zZUFjY291bnQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRVhQRU5TRS5BQ0NPVU5ULk5PVC5GT1VORCcsIGNvZGU6IDIwMCB9KTtcbiAgICAgIH1cbiAgICAgIC8vIGNvbnN0IGN1c3RvbUZpZWxkcyA9IG5ldyBSZXNvdXJjZUN1c3RvbUZpZWxkUmVwb3NpdG9yeShFeHBlbnNlKTtcbiAgICAgIC8vIGF3YWl0IGN1c3RvbUZpZWxkcy5sb2FkKCk7XG5cbiAgICAgIC8vIGlmIChjdXN0b21GaWVsZHMudmFsaWRhdGVFeGlzdEN1c3RvbUZpZWxkcygpKSB7XG4gICAgICAvLyAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0NVU1RPTS5GSUVMRFMuU0xVR1MuTk9ULkVYSVNUUycsIGNvZGU6IDQwMCB9KTtcbiAgICAgIC8vIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4cGVuc2VUcmFuc2FjdGlvbiA9IGF3YWl0IEV4cGVuc2UucXVlcnkoKS5pbnNlcnRBbmRGZXRjaCh7XG4gICAgICAgIC4uLm9taXQoZm9ybSwgWydjdXN0b21fZmllbGRzJ10pLFxuICAgICAgfSk7XG4gICAgICAvLyBjdXN0b21GaWVsZHMuZmlsbEN1c3RvbUZpZWxkcyhleHBlbnNlVHJhbnNhY3Rpb24uaWQsIGZvcm0uY3VzdG9tX2ZpZWxkcyk7XG5cbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGNvbnN0IGNyZWRpdEVudHJ5ID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAgIGNyZWRpdDogZm9ybS5hbW91bnQsXG4gICAgICAgIHJlZmVyZW5jZUlkOiBleHBlbnNlVHJhbnNhY3Rpb24uaWQsXG4gICAgICAgIHJlZmVyZW5jZVR5cGU6IEV4cGVuc2UucmVmZXJlbmNlVHlwZSxcbiAgICAgICAgZGF0ZTogZm9ybS5kYXRlLFxuICAgICAgICBhY2NvdW50OiBleHBlbnNlQWNjb3VudC5pZCxcbiAgICAgICAgYWNjb3VudE5vcm1hbDogJ2RlYml0JyxcbiAgICAgICAgZHJhZnQ6ICFmb3JtLnB1Ymxpc2hlZCxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgZGViaXRFbnRyeSA9IG5ldyBKb3VybmFsRW50cnkoe1xuICAgICAgICBkZWJpdDogZm9ybS5hbW91bnQsXG4gICAgICAgIHJlZmVyZW5jZUlkOiBleHBlbnNlVHJhbnNhY3Rpb24uaWQsXG4gICAgICAgIHJlZmVyZW5jZVR5cGU6IEV4cGVuc2UucmVmZXJlbmNlVHlwZSxcbiAgICAgICAgZGF0ZTogZm9ybS5kYXRlLFxuICAgICAgICBhY2NvdW50OiBwYXltZW50QWNjb3VudC5pZCxcbiAgICAgICAgYWNjb3VudE5vcm1hbDogJ2RlYml0JyxcbiAgICAgICAgZHJhZnQ6ICFmb3JtLnB1Ymxpc2hlZCxcbiAgICAgIH0pO1xuICAgICAgam91cm5hbEVudHJpZXMuY3JlZGl0KGNyZWRpdEVudHJ5KTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmRlYml0KGRlYml0RW50cnkpO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIC8vIGN1c3RvbUZpZWxkcy5zYXZlQ3VzdG9tRmllbGRzKGV4cGVuc2VUcmFuc2FjdGlvbi5pZCksXG4gICAgICAgIGpvdXJuYWxFbnRyaWVzLnNhdmVFbnRyaWVzKCksXG4gICAgICAgIGpvdXJuYWxFbnRyaWVzLnNhdmVCYWxhbmNlKCksXG4gICAgICBdKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBleHBlbnNlVHJhbnNhY3Rpb24uaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogQnVsayBhZGQgZXhwbmVzZXMgdG8gdGhlIGdpdmVuIGFjY291bnRzLlxuICAgKi9cbiAgYnVsa0FkZEV4cGVuc2VzOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ2V4cGVuc2VzJykuZXhpc3RzKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmRhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgY2hlY2soJ2V4cGVuc2VzLioucGF5bWVudF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmV4cGVuc2VfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZXhwZW5zZXMuKi5kZXNjcmlwdGlvbicpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnZXhwZW5zZXMuKi5hbW91bnQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgICBjaGVjaygnZXhwZW5zZXMuKi5jdXJyZW5jeV9jb2RlJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmV4Y2hhbmdlX3JhdGUnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG5cbiAgICAgIGNvbnN0IHBheW1lbnRBY2NvdW50c0lkcyA9IGNoYWluKGZvcm0uZXhwZW5zZXMpXG4gICAgICAgIC5tYXAoKGUpID0+IGUucGF5bWVudF9hY2NvdW50X2lkKS51bmlxKCkudmFsdWUoKTtcbiAgICAgIGNvbnN0IGV4cGVuc2VBY2NvdW50c0lkcyA9IGNoYWluKGZvcm0uZXhwZW5zZXMpXG4gICAgICAgIC5tYXAoKGUpID0+IGUuZXhwZW5zZV9hY2NvdW50X2lkKS51bmlxKCkudmFsdWUoKTtcblxuICAgICAgY29uc3QgW2V4cGVuc2VzQWNjb3VudHMsIHBheW1lbnRBY2NvdW50c10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIEFjY291bnQucXVlcnkoKS53aGVyZUluKCdpZCcsIGV4cGVuc2VBY2NvdW50c0lkcyksXG4gICAgICAgIEFjY291bnQucXVlcnkoKS53aGVyZUluKCdpZCcsIHBheW1lbnRBY2NvdW50c0lkcyksXG4gICAgICBdKTtcbiAgICAgIGNvbnN0IHN0b3JlZEV4cGVuc2VzQWNjb3VudHNJZHMgPSBleHBlbnNlc0FjY291bnRzLm1hcCgoYSkgPT4gYS5pZCk7XG4gICAgICBjb25zdCBzdG9yZWRQYXltZW50QWNjb3VudHNJZHMgPSBwYXltZW50QWNjb3VudHMubWFwKChhKSA9PiBhLmlkKTtcblxuICAgICAgY29uc3Qgbm90Rm91bmRQYXltZW50QWNjb3VudHNJZHMgPSBkaWZmZXJlbmNlKGV4cGVuc2VBY2NvdW50c0lkcywgc3RvcmVkRXhwZW5zZXNBY2NvdW50c0lkcyk7XG4gICAgICBjb25zdCBub3RGb3VuZEV4cGVuc2VBY2NvdW50c0lkcyA9IGRpZmZlcmVuY2UocGF5bWVudEFjY291bnRzSWRzLCBzdG9yZWRQYXltZW50QWNjb3VudHNJZHMpO1xuXG4gICAgICBpZiAobm90Rm91bmRQYXltZW50QWNjb3VudHNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ1BBWU1FTlkuQUNDT1VOVFMuTk9ULkZPVU5EJyxcbiAgICAgICAgICBjb2RlOiAxMDAsXG4gICAgICAgICAgYWNjb3VudHM6IG5vdEZvdW5kUGF5bWVudEFjY291bnRzSWRzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChub3RGb3VuZEV4cGVuc2VBY2NvdW50c0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnRVhQRU5TRS5BQ0NPVU5UUy5OT1QuRk9VTkQnLFxuICAgICAgICAgIGNvZGU6IDIwMCxcbiAgICAgICAgICBhY2NvdW50czogbm90Rm91bmRFeHBlbnNlQWNjb3VudHNJZHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgcmVhc29uczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZW5zZVNhdmVPcGVycyA9IFtdO1xuICAgICAgY29uc3Qgam91cm5hbFBvc3RlciA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG5cbiAgICAgIGZvcm0uZXhwZW5zZXMuZm9yRWFjaChhc3luYyAoZXhwZW5zZSkgPT4ge1xuICAgICAgICBjb25zdCBleHBlbnNlU2F2ZU9wZXIgPSBFeHBlbnNlLnF1ZXJ5KCkuaW5zZXJ0KHsgLi4uZXhwZW5zZSB9KTtcbiAgICAgICAgZXhwZW5zZVNhdmVPcGVycy5wdXNoKGV4cGVuc2VTYXZlT3Blcik7XG4gICAgICB9KTtcbiAgICAgIC8vIFdhaXQgdW5pdCBzYXZlIGFsbCBleHBlbnNlIHRyYW5zYWN0aW9ucy5cbiAgICAgIGNvbnN0IHNhdmVkRXhwZW5zZVRyYW5zYWN0aW9ucyA9IGF3YWl0IFByb21pc2UuYWxsKGV4cGVuc2VTYXZlT3BlcnMpO1xuXG4gICAgICBzYXZlZEV4cGVuc2VUcmFuc2FjdGlvbnMuZm9yRWFjaCgoZXhwZW5zZSkgPT4ge1xuICAgICAgICBjb25zdCBkYXRlID0gbW9tZW50KGV4cGVuc2UuZGF0ZSkuZm9ybWF0KCdZWVlZLURELU1NJyk7XG5cbiAgICAgICAgY29uc3QgZGViaXQgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgICBkZWJpdDogZXhwZW5zZS5hbW91bnQsXG4gICAgICAgICAgcmVmZXJlbmNlSWQ6IGV4cGVuc2UuaWQsXG4gICAgICAgICAgcmVmZXJlbmNlVHlwZTogRXhwZW5zZS5yZWZlcmVuY2VUeXBlLFxuICAgICAgICAgIGFjY291bnQ6IGV4cGVuc2UucGF5bWVudF9hY2NvdW50X2lkLFxuICAgICAgICAgIGFjY291bnROb3JtYWw6ICdkZWJpdCcsXG4gICAgICAgICAgZGF0ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IGNyZWRpdCA9IG5ldyBKb3VybmFsRW50cnkoe1xuICAgICAgICAgIGNyZWRpdDogZXhwZW5zZS5hbW91bnQsXG4gICAgICAgICAgcmVmZXJlbmNlSWQ6IGV4cGVuc2UuaWQsXG4gICAgICAgICAgcmVmZXJlbmNlVHlwZTogRXhwZW5zZS5yZWZlcmVuY2VJZCxcbiAgICAgICAgICBhY2NvdW50OiBleHBlbnNlLmV4cGVuc2VfYWNjb3VudF9pZCxcbiAgICAgICAgICBhY2NvdW50Tm9ybWFsOiAnZGViaXQnLFxuICAgICAgICAgIGRhdGUsXG4gICAgICAgIH0pO1xuICAgICAgICBqb3VybmFsUG9zdGVyLmNyZWRpdChjcmVkaXQpO1xuICAgICAgICBqb3VybmFsUG9zdGVyLmRlYml0KGRlYml0KTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBTYXZlIGV4cGVuc2Ugam91cm5hbCBlbnRyaWVzIGFuZCBiYWxhbmNlIGNoYW5nZS5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgam91cm5hbFBvc3Rlci5zYXZlRW50cmllcygpLFxuICAgICAgICBqb3VybmFsUG9zdGVyLnNhdmVCYWxhbmNlKCksXG4gICAgICBdKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFB1Ymxpc2ggdGhlIGdpdmVuIGV4cGVuc2UgaWQuXG4gICAqL1xuICBwdWJsaXNoRXhwZW5zZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBleHBlbnNlID0gYXdhaXQgRXhwZW5zZS5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFleHBlbnNlKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0VYUEVOU0UuTk9ULkZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZXhwZW5zZS5wdWJsaXNoZWQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRVhQRU5TRS5BTFJFQURZLlBVQkxJU0hFRCcsIGNvZGU6IDIwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdyZWZlcmVuY2VfaWQnLCBleHBlbnNlLmlkKVxuICAgICAgICAud2hlcmUoJ3JlZmVyZW5jZV90eXBlJywgJ0V4cGVuc2UnKVxuICAgICAgICAucGF0Y2goe1xuICAgICAgICAgIGRyYWZ0OiBmYWxzZSxcbiAgICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IEV4cGVuc2UucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ2lkJywgZXhwZW5zZS5pZClcbiAgICAgICAgLnVwZGF0ZSh7IHB1Ymxpc2hlZDogdHJ1ZSB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgcGFnaW5hdGVkIGV4cGVuc2VzIGxpc3QuXG4gICAqL1xuICBsaXN0RXhwZW5zZXM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnZXhwZW5zZV9hY2NvdW50X2lkJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ3BheW1lbnRfYWNjb3VudF9pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdub3RlJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdyYW5nZV9mcm9tJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgICBxdWVyeSgncmFuZ2VfdG8nKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIHF1ZXJ5KCdkYXRlX2Zyb20nKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ2RhdGVfdG8nKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ2NvbHVtbl9zb3J0X29yZGVyJykub3B0aW9uYWwoKS5pc0luKFsnY3JlYXRlZF9hdCcsICdkYXRlJywgJ2Ftb3VudCddKSxcbiAgICAgIHF1ZXJ5KCdzb3J0X29yZGVyJykub3B0aW9uYWwoKS5pc0luKFsnZGVzYycsICdhc2MnXSksXG4gICAgICBxdWVyeSgncGFnZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdwYWdlX3NpemUnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgnY3VzdG9tX3ZpZXdfaWQnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsdGVyID0ge1xuICAgICAgICBwYWdlX3NpemU6IDEwLFxuICAgICAgICBwYWdlOiAxLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBleHBlbnNlUmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpLndoZXJlKCduYW1lJywgJ2V4cGVuc2VzJykuZmlyc3QoKTtcblxuICAgICAgaWYgKCFleHBlbnNlUmVzb3VyY2UpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRVhQRU5TRV9SRVNPVVJDRV9OT1RfRk9VTkQnLCBjb2RlOiAzMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB2aWV3ID0gYXdhaXQgVmlldy5xdWVyeSgpLm9uQnVpbGQoKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlci5jdXN0b21fdmlld19pZCkge1xuICAgICAgICAgIGJ1aWxkZXIud2hlcmUoJ2lkJywgZmlsdGVyLmN1c3RvbV92aWV3X2lkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWlsZGVyLndoZXJlKCdmYXZvdXJpdGUnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBidWlsZGVyLndoZXJlKCdyZXNvdXJjZV9pZCcsIGV4cGVuc2VSZXNvdXJjZS5pZCk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgndmlld1JvbGVzLmZpZWxkJyk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgnY29sdW1ucycpO1xuXG4gICAgICAgIGJ1aWxkZXIuZmlyc3QoKTtcbiAgICAgIH0pO1xuICAgICAgbGV0IHZpZXdDb25kaXRpb25hbHMgPSBbXTtcblxuICAgICAgaWYgKHZpZXcgJiYgdmlldy52aWV3Um9sZXMubGVuZ3RoID4gMCkge1xuICAgICAgICB2aWV3Q29uZGl0aW9uYWxzID0gbWFwVmlld1JvbGVzVG9Db25kaXRpb25hbHModmlldy52aWV3Um9sZXMpO1xuXG4gICAgICAgIGlmICghdmFsaWRhdGVWaWV3Um9sZXModmlld0NvbmRpdGlvbmFscywgdmlldy5yb2xlc0xvZ2ljRXhwcmVzc2lvbikpIHtcbiAgICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdWSUVXLkxPR0lDLkVYUFJFU1NJT04uSU5WQUxJRCcsIGNvZGU6IDQwMCB9KVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoIXZpZXcgJiYgZmlsdGVyLmN1c3RvbV92aWV3X2lkKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1ZJRVdfTk9UX0ZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cGVuc2VzID0gYXdhaXQgRXhwZW5zZS5xdWVyeSgpLm9uQnVpbGQoKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCdwYXltZW50QWNjb3VudCcpO1xuICAgICAgICBidWlsZGVyLndpdGhHcmFwaEZldGNoZWQoJ2V4cGVuc2VBY2NvdW50Jyk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgndXNlcicpO1xuXG4gICAgICAgIGlmICh2aWV3Q29uZGl0aW9uYWxzLmxlbmd0aCkge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCd2aWV3Um9sZXNCdWlsZGVyJywgdmlld0NvbmRpdGlvbmFscywgdmlldy5yb2xlc0xvZ2ljRXhwcmVzc2lvbik7XG4gICAgICAgIH1cbiAgICAgICAgYnVpbGRlci5tb2RpZnkoJ2ZpbHRlckJ5QW1vdW50UmFuZ2UnLCBmaWx0ZXIucmFuZ2VfZnJvbSwgZmlsdGVyLnRvX3JhbmdlKTtcbiAgICAgICAgYnVpbGRlci5tb2RpZnkoJ2ZpbHRlckJ5RGF0ZVJhbmdlJywgZmlsdGVyLmRhdGVfZnJvbSwgZmlsdGVyLmRhdGVfdG8pO1xuICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyQnlFeHBlbnNlQWNjb3VudCcsIGZpbHRlci5leHBlbnNlX2FjY291bnRfaWQpO1xuICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyQnlQYXltZW50QWNjb3VudCcsIGZpbHRlci5wYXltZW50X2FjY291bnRfaWQpO1xuICAgICAgICBidWlsZGVyLm1vZGlmeSgnb3JkZXJCeScsIGZpbHRlci5jb2x1bW5fc29ydF9vcmRlciwgZmlsdGVyLnNvcnRfb3JkZXIpO1xuICAgICAgfSkucGFnZShmaWx0ZXIucGFnZSAtIDEsIGZpbHRlci5wYWdlX3NpemUpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICAuLi4odmlldykgPyB7XG4gICAgICAgICAgY3VzdG9tVmlld0lkOiB2aWV3LmlkLCBcbiAgICAgICAgICB2aWV3Q29sdW1uczogdmlldy5jb2x1bW5zLFxuICAgICAgICAgIHZpZXdDb25kaXRpb25hbHMsXG4gICAgICAgIH0gOiB7fSxcbiAgICAgICAgZXhwZW5zZXMsXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICBkZWxldGVFeHBlbnNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZXhwZW5zZVRyYW5zYWN0aW9uID0gYXdhaXQgRXhwZW5zZS5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFleHBlbnNlVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdFWFBFTlNFLlRSQU5TQUNUSU9OLk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBleHBlbnNlRW50cmllcyA9IGF3YWl0IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgncmVmZXJlbmNlX3R5cGUnLCAnRXhwZW5zZScpXG4gICAgICAgIC53aGVyZSgncmVmZXJlbmNlX2lkJywgZXhwZW5zZVRyYW5zYWN0aW9uLmlkKTtcblxuICAgICAgY29uc3QgZXhwZW5zZUVudHJpZXNDb2xsZWN0ID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGV4cGVuc2VFbnRyaWVzQ29sbGVjdC5sb2FkRW50cmllcyhleHBlbnNlRW50cmllcyk7XG4gICAgICBleHBlbnNlRW50cmllc0NvbGxlY3QucmV2ZXJzZUVudHJpZXMoKTtcblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBFeHBlbnNlLnF1ZXJ5KCkuZmluZEJ5SWQoZXhwZW5zZVRyYW5zYWN0aW9uLmlkKS5kZWxldGUoKSxcbiAgICAgICAgZXhwZW5zZUVudHJpZXNDb2xsZWN0LmRlbGV0ZUVudHJpZXMoKSxcbiAgICAgICAgZXhwZW5zZUVudHJpZXNDb2xsZWN0LnNhdmVCYWxhbmNlKCksXG4gICAgICBdKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFVwZGF0ZSBkZXRhaWxzIG9mIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKi9cbiAgdXBkYXRlRXhwZW5zZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGF0ZScpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBjaGVjaygncGF5bWVudF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlX2FjY291bnRfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2Rlc2NyaXB0aW9uJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdhbW91bnQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgICBjaGVjaygnY3VycmVuY3lfY29kZScpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnZXhjaGFuZ2VfcmF0ZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBleHBlbnNlVHJhbnNhY3Rpb24gPSBhd2FpdCBFeHBlbnNlLnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWV4cGVuc2VUcmFuc2FjdGlvbikge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0VYUEVOU0UuVFJBTlNBQ1RJT04uTk9ULkZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBkZXRhaWxzIG9mIHRoZSBnaXZlbiBleHBlbnNlIGlkLlxuICAgKi9cbiAgZ2V0RXhwZW5zZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGV4cGVuc2VUcmFuc2FjdGlvbiA9IGF3YWl0IEV4cGVuc2UucXVlcnkoKS5maW5kQnlJZChpZCk7XG5cbiAgICAgIGlmICghZXhwZW5zZVRyYW5zYWN0aW9uKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnRVhQRU5TRS5UUkFOU0FDVElPTi5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBleHBlbnNlQ0ZNZXRhZGF0YVJlcG8gPSBuZXcgUmVzb3VyY2VDdXN0b21GaWVsZFJlcG9zaXRvcnkoRXhwZW5zZSk7XG4gICAgICBhd2FpdCBleHBlbnNlQ0ZNZXRhZGF0YVJlcG8ubG9hZCgpO1xuICAgICAgYXdhaXQgZXhwZW5zZUNGTWV0YWRhdGFSZXBvLmZldGNoQ3VzdG9tRmllbGRzTWV0YWRhdGEoZXhwZW5zZVRyYW5zYWN0aW9uLmlkKTtcblxuICAgICAgY29uc3QgZXhwZW5zZUN1c0ZpZWxkc01ldGFkYXRhID0gZXhwZW5zZUNGTWV0YWRhdGFSZXBvLmdldE1ldGFkYXRhKGV4cGVuc2VUcmFuc2FjdGlvbi5pZCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIC4uLmV4cGVuc2VUcmFuc2FjdGlvbixcbiAgICAgICAgY3VzdG9tX2ZpZWxkczogW1xuICAgICAgICAgIC4uLmV4cGVuc2VDdXNGaWVsZHNNZXRhZGF0YS50b0FycmF5KCksXG4gICAgICAgIF0sXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgY2hlY2ssIHBhcmFtLCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IFJlc291cmNlRmllbGQgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZCc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICcuLi9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5cbi8qKlxuICogVHlwZXMgb2YgdGhlIGN1c3RvbSBmaWVsZHMuXG4gKi9cbmNvbnN0IFRZUEVTID0gWyd0ZXh0JywgJ2VtYWlsJywgJ251bWJlcicsICd1cmwnLCAncGVyY2VudGFnZScsICdjaGVja2JveCcsICdyYWRpbycsICd0ZXh0YXJlYSddO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IgbWV0aG9kLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIucG9zdCgnL3Jlc291cmNlLzpyZXNvdXJjZV9uYW1lJyxcbiAgICAgIHRoaXMuYWRkTmV3RmllbGQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmFkZE5ld0ZpZWxkLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmZpZWxkX2lkJyxcbiAgICAgIHRoaXMuZWRpdEZpZWxkLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5lZGl0RmllbGQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9zdGF0dXMvOmZpZWxkX2lkJyxcbiAgICAgIHRoaXMuY2hhbmdlU3RhdHVzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5jaGFuZ2VTdGF0dXMuaGFuZGxlcikpO1xuXG4gICAgLy8gcm91dGVyLmdldCgnLzpmaWVsZF9pZCcsXG4gICAgLy8gICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRGaWVsZC5oYW5kbGVyKSk7XG5cbiAgICAvLyByb3V0ZXIuZGVsZXRlKCcvOmZpZWxkX2lkJyxcbiAgICAvLyAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZUZpZWxkLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIEFkZHMgYSBuZXcgZmllbGQgY29udHJvbCB0byB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAqIEBwYXJhbSB7UmVxdWVzdH0gcmVxIC1cbiAgICogQHBhcmFtIHtSZXNwb25zZX0gcmVzIC1cbiAgICovXG4gIGFkZE5ld0ZpZWxkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ3Jlc291cmNlX25hbWUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnbGFiZWwnKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygnZGF0YV90eXBlJykuZXhpc3RzKCkuaXNJbihUWVBFUyksXG4gICAgICBjaGVjaygnaGVscF90ZXh0Jykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdkZWZhdWx0Jykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdvcHRpb25zJykub3B0aW9uYWwoKS5pc0FycmF5KCksXG4gICAgICBjaGVjaygnb3B0aW9ucy4qLmtleScpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnb3B0aW9ucy4qLnZhbHVlJykuZXhpc3RzKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IHJlc291cmNlX25hbWU6IHJlc291cmNlTmFtZSB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KCkud2hlcmUoJ25hbWUnLCByZXNvdXJjZU5hbWUpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdSRVNPVVJDRV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZm9ybSA9IHsgb3B0aW9uczogW10sIC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBjaG9pY2VzID0gZm9ybS5vcHRpb25zLm1hcCgob3B0aW9uKSA9PiAoeyBrZXk6IG9wdGlvbi5rZXksIHZhbHVlOiBvcHRpb24udmFsdWUgfSkpO1xuXG4gICAgICBjb25zdCBzdG9yZWRSZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlRmllbGQucXVlcnkoKS5pbnNlcnRBbmRGZXRjaCh7XG4gICAgICAgIGRhdGFfdHlwZTogZm9ybS5kYXRhX3R5cGUsXG4gICAgICAgIGxhYmVsX25hbWU6IGZvcm0ubGFiZWwsXG4gICAgICAgIGhlbHBfdGV4dDogZm9ybS5oZWxwX3RleHQsXG4gICAgICAgIGRlZmF1bHQ6IGZvcm0uZGVmYXVsdCxcbiAgICAgICAgcmVzb3VyY2VfaWQ6IHJlc291cmNlLmlkLFxuICAgICAgICBvcHRpb25zOiBjaG9pY2VzLFxuICAgICAgICBpbmRleDogLTEsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBzdG9yZWRSZXNvdXJjZS5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBFZGl0IGRldGFpbHMgb2YgdGhlIGdpdmVuIGZpZWxkLlxuICAgKi9cbiAgZWRpdEZpZWxkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2ZpZWxkX2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdsYWJlbCcpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdkYXRhX3R5cGUnKS5leGlzdHMoKS5pc0luKFRZUEVTKSxcbiAgICAgIGNoZWNrKCdoZWxwX3RleHQnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2RlZmF1bHQnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ29wdGlvbnMnKS5vcHRpb25hbCgpLmlzQXJyYXkoKSxcbiAgICAgIGNoZWNrKCdvcHRpb25zLioua2V5JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdvcHRpb25zLioudmFsdWUnKS5leGlzdHMoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgZmllbGRfaWQ6IGZpZWxkSWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZmllbGQgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLnF1ZXJ5KCkuZmluZEJ5SWQoZmllbGRJZCk7XG5cbiAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdGSUVMRF9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgLy8gU2V0cyB0aGUgZGVmYXVsdCB2YWx1ZSBvZiBvcHRpb25hbCBmaWVsZHMuXG4gICAgICBjb25zdCBmb3JtID0geyBvcHRpb25zOiBbXSwgLi4ucmVxLmJvZHkgfTtcbiAgICAgIGNvbnN0IGNob2ljZXMgPSBmb3JtLm9wdGlvbnMubWFwKChvcHRpb24pID0+ICh7IGtleTogb3B0aW9uLmtleSwgdmFsdWU6IG9wdGlvbi52YWx1ZSB9KSk7XG5cbiAgICAgIGF3YWl0IFJlc291cmNlRmllbGQucXVlcnkoKS5maW5kQnlJZChmaWVsZC5pZCkudXBkYXRlKHtcbiAgICAgICAgZGF0YV90eXBlOiBmb3JtLmRhdGFfdHlwZSxcbiAgICAgICAgbGFiZWxfbmFtZTogZm9ybS5sYWJlbCxcbiAgICAgICAgaGVscF90ZXh0OiBmb3JtLmhlbHBfdGV4dCxcbiAgICAgICAgZGVmYXVsdDogZm9ybS5kZWZhdWx0LFxuICAgICAgICBvcHRpb25zOiBjaG9pY2VzLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogZmllbGQuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGZpZWxkcyBsaXN0IG9mIHRoZSBnaXZlbiByZXNvdXJjZS5cbiAgICogQHBhcmFtIHtSZXF1ZXN0fSByZXEgLVxuICAgKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXMgLVxuICAgKi9cbiAgZmllbGRzTGlzdDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdyZXNvdXJjZV9uYW1lJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHJlc291cmNlX25hbWU6IHJlc291cmNlTmFtZSB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgUmVzb3VyY2UucXVlcnkoKS53aGVyZSgnbmFtZScsIHJlc291cmNlTmFtZSkuZmlyc3QoKTtcblxuICAgICAgaWYgKCFyZXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1JFU09VUkNFX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWVsZHMgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLndoZXJlKCdyZXNvdXJjZV9pZCcsIHJlc291cmNlLmlkKS5mZXRjaEFsbCgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBmaWVsZHM6IGZpZWxkcy50b0pTT04oKSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBDaGFuZ2Ugc3RhdHVzIG9mIHRoZSBnaXZlbiBmaWVsZC5cbiAgICovXG4gIGNoYW5nZVN0YXR1czoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdmaWVsZF9pZCcpLnRvSW50KCksXG4gICAgICBjaGVjaygnYWN0aXZlJykuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGZpZWxkX2lkOiBmaWVsZElkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZmllbGQgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLnF1ZXJ5KCkuZmluZEJ5SWQoZmllbGRJZCk7XG5cbiAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdOT1RfRk9VTkRfRklFTEQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGFjdGl2ZSB9ID0gcmVxLmJvZHk7XG4gICAgICBhd2FpdCBSZXNvdXJjZUZpZWxkLnF1ZXJ5KCkuZmluZEJ5SWQoZmllbGQuaWQpLnBhdGNoKHsgYWN0aXZlIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogZmllbGQuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gZmllbGQuXG4gICAqL1xuICBnZXRGaWVsZDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdmaWVsZF9pZCcpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGZpZWxkX2lkOiBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGZpZWxkID0gYXdhaXQgUmVzb3VyY2VGaWVsZC53aGVyZSgnaWQnLCBpZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgZmllbGQ6IGZpZWxkLnRvSlNPTigpLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlbiBmaWVsZC5cbiAgICovXG4gIGRlbGV0ZUZpZWxkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2ZpZWxkX2lkJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgZmllbGRfaWQ6IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZmllbGQgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLndoZXJlKCdpZCcsIGlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWZpZWxkKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgaWYgKGZpZWxkLmF0dHJpYnV0ZXMucHJlZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUFJFREVGSU5FRF9GSUVMRCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBmaWVsZC5kZXN0cm95KCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBmaWVsZC5nZXQoJ2lkJykgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IHF1ZXJ5LCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgcGljayB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgQWNjb3VudFRyYW5zYWN0aW9uIGZyb20gJ0AvbW9kZWxzL0FjY291bnRUcmFuc2FjdGlvbic7XG5pbXBvcnQgand0QXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBBY2NvdW50VHlwZSBmcm9tICdAL21vZGVscy9BY2NvdW50VHlwZSc7XG5pbXBvcnQgQWNjb3VudCBmcm9tICdAL21vZGVscy9BY2NvdW50JztcbmltcG9ydCBKb3VybmFsUG9zdGVyIGZyb20gJ0Avc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsUG9zdGVyJztcbmltcG9ydCB7IGRhdGVSYW5nZUNvbGxlY3Rpb24gfSBmcm9tICdAL3V0aWxzJztcblxuY29uc3QgZm9ybWF0TnVtYmVyQ2xvc3VyZSA9IChmaWx0ZXIpID0+IChiYWxhbmNlKSA9PiB7XG4gIGxldCBmb3JtYXR0ZWRCYWxhbmNlID0gcGFyc2VGbG9hdChiYWxhbmNlKTtcblxuICBpZiAoZmlsdGVyLm5vX2NlbnRzKSB7XG4gICAgZm9ybWF0dGVkQmFsYW5jZSA9IHBhcnNlSW50KGZvcm1hdHRlZEJhbGFuY2UsIDEwKTtcbiAgfVxuICBpZiAoZmlsdGVyLmRpdmlkZV8xMDAwKSB7XG4gICAgZm9ybWF0dGVkQmFsYW5jZSAvPSAxMDAwO1xuICB9XG4gIHJldHVybiBmb3JtYXR0ZWRCYWxhbmNlO1xufTtcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgcm91dGVyLnVzZShqd3RBdXRoKTtcblxuICAgIHJvdXRlci5nZXQoJy9sZWRnZXInLFxuICAgICAgdGhpcy5sZWRnZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmxlZGdlci5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvZ2VuZXJhbF9sZWRnZXInLFxuICAgICAgdGhpcy5nZW5lcmFsTGVkZ2VyLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZW5lcmFsTGVkZ2VyLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy9iYWxhbmNlX3NoZWV0JyxcbiAgICAgIHRoaXMuYmFsYW5jZVNoZWV0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5iYWxhbmNlU2hlZXQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnL3RyaWFsX2JhbGFuY2Vfc2hlZXQnLFxuICAgICAgdGhpcy50cmlhbEJhbGFuY2VTaGVldC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMudHJpYWxCYWxhbmNlU2hlZXQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnL3Byb2ZpdF9sb3NzX3NoZWV0JyxcbiAgICAgIHRoaXMucHJvZml0TG9zc1NoZWV0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5wcm9maXRMb3NzU2hlZXQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnL2Nhc2hfZmxvd19zdGF0ZW1lbnQnLFxuICAgICAgdGhpcy5jYXNoRmxvd1N0YXRlbWVudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuY2FzaEZsb3dTdGF0ZW1lbnQuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGxlZGdlciByZXBvcnQgb2YgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICBsZWRnZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCd0cmFuc2FjdGlvbl90eXBlcycpLm9wdGlvbmFsKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIHF1ZXJ5KCdhY2NvdW50X2lkcycpLm9wdGlvbmFsKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIHF1ZXJ5KCdhY2NvdW50X2lkcy4qJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ2Zyb21fcmFuZ2UnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgndG9fcmFuZ2UnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5ub19jZW50cycpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5kaXZpZGVfMTAwMCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsdGVyID0ge1xuICAgICAgICBmcm9tX3JhbmdlOiBudWxsLFxuICAgICAgICB0b19yYW5nZTogbnVsbCxcbiAgICAgICAgYWNjb3VudF9pZHM6IFtdLFxuICAgICAgICB0cmFuc2FjdGlvbl90eXBlczogW10sXG4gICAgICAgIG51bWJlcl9mb3JtYXQ6IHtcbiAgICAgICAgICBub19jZW50czogZmFsc2UsXG4gICAgICAgICAgZGl2aWRlXzEwMDA6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuICAgICAgY29uc3QgYWNjb3VudHNKb3VybmFsRW50cmllcyA9IGF3YWl0IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC5tb2RpZnkoJ2ZpbHRlckRhdGVSYW5nZScsIGZpbHRlci5mcm9tX2RhdGUsIGZpbHRlci50b19kYXRlKVxuICAgICAgICAubW9kaWZ5KCdmaWx0ZXJBY2NvdW50cycsIGZpbHRlci5hY2NvdW50X2lkcylcbiAgICAgICAgLm1vZGlmeSgnZmlsdGVyVHJhbnNhY3Rpb25UeXBlcycsIGZpbHRlci50cmFuc2FjdGlvbl90eXBlcylcbiAgICAgICAgLm1vZGlmeSgnZmlsdGVyQW1vdW50UmFuZ2UnLCBmaWx0ZXIuZnJvbV9yYW5nZSwgZmlsdGVyLnRvX3JhbmdlKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnYWNjb3VudCcpO1xuXG4gICAgICBjb25zdCBmb3JtYXROdW1iZXIgPSBmb3JtYXROdW1iZXJDbG9zdXJlKGZpbHRlci5udW1iZXJfZm9ybWF0KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgbWV0YTogeyAuLi5maWx0ZXIgfSxcbiAgICAgICAgaXRlbXM6IGFjY291bnRzSm91cm5hbEVudHJpZXMubWFwKChlbnRyeSkgPT4gKHtcbiAgICAgICAgICAuLi5lbnRyeSxcbiAgICAgICAgICBjcmVkaXQ6IGZvcm1hdE51bWJlcihlbnRyeS5jcmVkaXQpLFxuICAgICAgICAgIGRlYml0OiBmb3JtYXROdW1iZXIoZW50cnkuZGViaXQpLFxuICAgICAgICB9KSksXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgZ2VuZXJhbCBsZWRnZXIgZmluYW5jaWFsIHN0YXRlbWVudC5cbiAgICovXG4gIGdlbmVyYWxMZWRnZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5ub19jZW50cycpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5kaXZpZGVfMTAwMCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbm9uZV96ZXJvJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGZyb21fZGF0ZTogbW9tZW50KCkuc3RhcnRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICB0b19kYXRlOiBtb21lbnQoKS5lbmRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICBudW1iZXJfZm9ybWF0OiB7XG4gICAgICAgICAgbm9fY2VudHM6IGZhbHNlLFxuICAgICAgICAgIGRpdmlkZV8xMDAwOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgbm9uZV96ZXJvOiBmYWxzZSxcbiAgICAgICAgLi4ucmVxLnF1ZXJ5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpXG4gICAgICAgIC5vcmRlckJ5KCdpbmRleCcsICdERVNDJylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3RyYW5zYWN0aW9ucycpXG4gICAgICAgIC5tb2RpZnlHcmFwaCgndHJhbnNhY3Rpb25zJywgKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyRGF0ZVJhbmdlJywgZmlsdGVyLmZyb21fZGF0ZSwgZmlsdGVyLnRvX2RhdGUpO1xuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgb3BlbmluZ0JhbGFuY2VUcmFuc2FjdGlvbnMgPSBhd2FpdCBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKVxuICAgICAgICAubW9kaWZ5KCdmaWx0ZXJEYXRlUmFuZ2UnLCBudWxsLCBmaWx0ZXIuZnJvbV9kYXRlKVxuICAgICAgICAubW9kaWZ5KCdzdW1hdGlvbkNyZWRpdERlYml0JylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ2FjY291bnQudHlwZScpO1xuXG4gICAgICBjb25zdCBjbG9zaW5nQmFsYW5jZVRyYW5zYWN0aW9ucyA9IGF3YWl0IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC5tb2RpZnkoJ2ZpbHRlckRhdGVSYW5nZScsIG51bGwsIGZpbHRlci50b19kYXRlKVxuICAgICAgICAubW9kaWZ5KCdzdW1hdGlvbkNyZWRpdERlYml0JylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ2FjY291bnQudHlwZScpO1xuXG4gICAgICBjb25zdCBvcGVpbmdCYWxhbmNlQ29sbGVjdGlvbiA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG4gICAgICBjb25zdCBjbG9zaW5nQmFsYW5jZUNvbGxlY3Rpb24gPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuXG4gICAgICBvcGVpbmdCYWxhbmNlQ29sbGVjdGlvbi5sb2FkRW50cmllcyhvcGVuaW5nQmFsYW5jZVRyYW5zYWN0aW9ucyk7XG4gICAgICBjbG9zaW5nQmFsYW5jZUNvbGxlY3Rpb24ubG9hZEVudHJpZXMoY2xvc2luZ0JhbGFuY2VUcmFuc2FjdGlvbnMpO1xuXG4gICAgICAvLyBUcmFuc2FjdGlvbiBhbW91bnQgZm9ybWF0dGVyIGJhc2VkIG9uIHRoZSBnaXZlbiBxdWVyeS5cbiAgICAgIGNvbnN0IGZvcm1hdE51bWJlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IFtcbiAgICAgICAgLi4uYWNjb3VudHNcbiAgICAgICAgICAuZmlsdGVyKChhY2NvdW50KSA9PiAoXG4gICAgICAgICAgICBhY2NvdW50LnRyYW5zYWN0aW9ucy5sZW5ndGggPiAwIHx8ICFmaWx0ZXIubm9uZV96ZXJvXG4gICAgICAgICAgKSlcbiAgICAgICAgICAubWFwKChhY2NvdW50KSA9PiAoe1xuICAgICAgICAgICAgLi4ucGljayhhY2NvdW50LCBbJ2lkJywgJ25hbWUnLCAnY29kZScsICdpbmRleCddKSxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uczogW1xuICAgICAgICAgICAgICAuLi5hY2NvdW50LnRyYW5zYWN0aW9ucy5tYXAoKHRyYW5zYWN0aW9uKSA9PiAoe1xuICAgICAgICAgICAgICAgIC4uLnRyYW5zYWN0aW9uLFxuICAgICAgICAgICAgICAgIGNyZWRpdDogZm9ybWF0TnVtYmVyKHRyYW5zYWN0aW9uLmNyZWRpdCksXG4gICAgICAgICAgICAgICAgZGViaXQ6IGZvcm1hdE51bWJlcih0cmFuc2FjdGlvbi5kZWJpdCksXG4gICAgICAgICAgICAgIH0pKSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBvcGVuaW5nOiB7XG4gICAgICAgICAgICAgIGRhdGU6IGZpbHRlci5mcm9tX2RhdGUsXG4gICAgICAgICAgICAgIGJhbGFuY2U6IG9wZWluZ0JhbGFuY2VDb2xsZWN0aW9uLmdldENsb3NpbmdCYWxhbmNlKGFjY291bnQuaWQpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNsb3Npbmc6IHtcbiAgICAgICAgICAgICAgZGF0ZTogZmlsdGVyLnRvX2RhdGUsXG4gICAgICAgICAgICAgIGJhbGFuY2U6IGNsb3NpbmdCYWxhbmNlQ29sbGVjdGlvbi5nZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50LmlkKSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSkpLFxuICAgICAgXTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIG1ldGE6IHsgLi4uZmlsdGVyIH0sXG4gICAgICAgIGl0ZW1zLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGJhbGFuY2Ugc2hlZXQuXG4gICAqL1xuICBiYWxhbmNlU2hlZXQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnYWNjb3VudGluZ19tZXRob2QnKS5vcHRpb25hbCgpLmlzSW4oWydjYXNoJywgJ2FjY3VyYWwnXSksXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdkaXNwbGF5X2NvbHVtbnNfYnknKS5vcHRpb25hbCgpLmlzSW4oWyd5ZWFyJywgJ21vbnRoJywgJ3dlZWsnLCAnZGF5JywgJ3F1YXJ0ZXInXSksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5ub19jZW50cycpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5kaXZpZGVfMTAwMCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbm9uZV96ZXJvJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGRpc3BsYXlfY29sdW1uc19ieTogJ3llYXInLFxuICAgICAgICBmcm9tX2RhdGU6IG1vbWVudCgpLnN0YXJ0T2YoJ3llYXInKS5mb3JtYXQoJ1lZWVktTU0tREQnKSxcbiAgICAgICAgdG9fZGF0ZTogbW9tZW50KCkuZW5kT2YoJ3llYXInKS5mb3JtYXQoJ1lZWVktTU0tREQnKSxcbiAgICAgICAgbnVtYmVyX2Zvcm1hdDoge1xuICAgICAgICAgIG5vX2NlbnRzOiBmYWxzZSxcbiAgICAgICAgICBkaXZpZGVfMTAwMDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIG5vbmVfemVybzogZmFsc2UsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGJhbGFuY2VTaGVldFR5cGVzID0gYXdhaXQgQWNjb3VudFR5cGUucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ2JhbGFuY2Vfc2hlZXQnLCB0cnVlKTtcblxuICAgICAgLy8gRmV0Y2ggYWxsIGJhbGFuY2Ugc2hlZXQgYWNjb3VudHMuXG4gICAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKVxuICAgICAgICAud2hlcmVJbignYWNjb3VudF90eXBlX2lkJywgYmFsYW5jZVNoZWV0VHlwZXMubWFwKChhKSA9PiBhLmlkKSlcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3R5cGUnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHJhbnNhY3Rpb25zJylcbiAgICAgICAgLm1vZGlmeUdyYXBoKCd0cmFuc2FjdGlvbnMnLCAoYnVpbGRlcikgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJEYXRlUmFuZ2UnLCBudWxsLCBmaWx0ZXIudG9fZGF0ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBqb3VybmFsRW50cmllc0NvbGxlY3RlZCA9IEFjY291bnQuY29sbGVjdEpvdXJuYWxFbnRyaWVzKGFjY291bnRzKTtcbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmxvYWRFbnRyaWVzKGpvdXJuYWxFbnRyaWVzQ29sbGVjdGVkKTtcblxuICAgICAgLy8gQWNjb3VudCBiYWxhbmNlIGZvcm1tYXR0ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHF1ZXJ5LlxuICAgICAgY29uc3QgYmFsYW5jZUZvcm1hdHRlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuXG4gICAgICAvLyBHZXRzIHRoZSBkYXRlIHJhbmdlIHNldCBmcm9tIHN0YXJ0IHRvIGVuZCBkYXRlLlxuICAgICAgY29uc3QgZGF0ZVJhbmdlU2V0ID0gZGF0ZVJhbmdlQ29sbGVjdGlvbihcbiAgICAgICAgZmlsdGVyLmZyb21fZGF0ZSxcbiAgICAgICAgZmlsdGVyLnRvX2RhdGUsXG4gICAgICAgIGZpbHRlci5kaXNwbGF5X2NvbHVtbnNfYnksXG4gICAgICApO1xuICAgICAgLy8gUmV0cmlldmUgdGhlIGFzc2V0IGJhbGFuY2Ugc2hlZXQuXG4gICAgICBjb25zdCBhc3NldHMgPSBbXG4gICAgICAgIC4uLmFjY291bnRzXG4gICAgICAgICAgLmZpbHRlcigoYWNjb3VudCkgPT4gKFxuICAgICAgICAgICAgYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2RlYml0J1xuICAgICAgICAgICAgJiYgKGFjY291bnQudHJhbnNhY3Rpb25zLmxlbmd0aCA+IDAgfHwgIWZpbHRlci5ub25lX3plcm8pXG4gICAgICAgICAgKSlcbiAgICAgICAgICAubWFwKChhY2NvdW50KSA9PiAoe1xuICAgICAgICAgICAgLi4ucGljayhhY2NvdW50LCBbJ2lkJywgJ2luZGV4JywgJ25hbWUnLCAnY29kZSddKSxcbiAgICAgICAgICAgIHRyYW5zYWN0aW9uczogZGF0ZVJhbmdlU2V0Lm1hcCgoZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0eXBlID0gZmlsdGVyLmRpc3BsYXlfY29sdW1uc19ieTtcbiAgICAgICAgICAgICAgY29uc3QgYmFsYW5jZSA9IGpvdXJuYWxFbnRyaWVzLmdldENsb3NpbmdCYWxhbmNlKGFjY291bnQuaWQsIGRhdGUsIHR5cGUpO1xuICAgICAgICAgICAgICByZXR1cm4geyBkYXRlLCBiYWxhbmNlOiBiYWxhbmNlRm9ybWF0dGVyKGJhbGFuY2UpIH07XG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICB9KSksXG4gICAgICBdO1xuICAgICAgLy8gUmV0cmlldmUgbGlhYmlsaXRpZXMgYW5kIGVxdWl0eSBiYWxhbmNlIHNoZWV0LlxuICAgICAgY29uc3QgbGlhYmlsaXRpZXNFcXVpdHkgPSBbXG4gICAgICAgIC4uLmFjY291bnRzXG4gICAgICAgICAgLmZpbHRlcigoYWNjb3VudCkgPT4gKFxuICAgICAgICAgICAgYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2NyZWRpdCdcbiAgICAgICAgICAgICYmIChhY2NvdW50LnRyYW5zYWN0aW9ucy5sZW5ndGggPiAwIHx8ICFmaWx0ZXIubm9uZV96ZXJvKVxuICAgICAgICAgICkpXG4gICAgICAgICAgLm1hcCgoYWNjb3VudCkgPT4gKHtcbiAgICAgICAgICAgIC4uLnBpY2soYWNjb3VudCwgWydpZCcsICdpbmRleCcsICduYW1lJywgJ2NvZGUnXSksXG4gICAgICAgICAgICB0cmFuc2FjdGlvbnM6IGRhdGVSYW5nZVNldC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdHlwZSA9IGZpbHRlci5kaXNwbGF5X2NvbHVtbnNfYnk7XG4gICAgICAgICAgICAgIGNvbnN0IGJhbGFuY2UgPSBqb3VybmFsRW50cmllcy5nZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50LmlkLCBkYXRlLCB0eXBlKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgZGF0ZSwgYmFsYW5jZTogYmFsYW5jZUZvcm1hdHRlcihiYWxhbmNlKSB9O1xuICAgICAgICAgICAgfSksXG4gICAgICAgICAgfSkpLFxuICAgICAgXTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIHF1ZXJ5OiB7IC4uLmZpbHRlciB9LFxuICAgICAgICBjb2x1bW5zOiB7IC4uLmRhdGVSYW5nZVNldCB9LFxuICAgICAgICBiYWxhbmNlX3NoZWV0OiB7XG4gICAgICAgICAgYXNzZXRzLFxuICAgICAgICAgIGxpYWJpbGl0aWVzX2VxdWl0eTogbGlhYmlsaXRpZXNFcXVpdHksXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgdHJpYWwgYmFsYW5jZSBzaGVldC5cbiAgICovXG4gIHRyaWFsQmFsYW5jZVNoZWV0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcXVlcnkoJ2Jhc2lzJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdmcm9tX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ3RvX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ251bWJlcl9mb3JtYXQubm9fY2VudHMnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLFxuICAgICAgcXVlcnkoJ251bWJlcl9mb3JtYXQuMTAwMF9kaXZpZGUnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLFxuICAgICAgcXVlcnkoJ2Jhc2lzJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdub25lX3plcm8nKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgZnJvbV9kYXRlOiBtb21lbnQoKS5zdGFydE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIHRvX2RhdGU6IG1vbWVudCgpLmVuZE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIG51bWJlcl9mb3JtYXQ6IHtcbiAgICAgICAgICBub19jZW50czogZmFsc2UsXG4gICAgICAgICAgZGl2aWRlXzEwMDA6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBiYXNpczogJ2FjY3VyYWwnLFxuICAgICAgICBub25lX3plcm86IGZhbHNlLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHlwZScpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCd0cmFuc2FjdGlvbnMnKVxuICAgICAgICAubW9kaWZ5R3JhcGgoJ3RyYW5zYWN0aW9ucycsIChidWlsZGVyKSA9PiB7XG4gICAgICAgICAgYnVpbGRlci5tb2RpZnkoJ3N1bWF0aW9uQ3JlZGl0RGViaXQnKTtcbiAgICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyRGF0ZVJhbmdlJywgZmlsdGVyLmZyb21fZGF0ZSwgZmlsdGVyLnRvX2RhdGUpO1xuICAgICAgICB9KTtcblxuICAgICAgY29uc3Qgam91cm5hbEVudHJpZXNDb2xsZWN0ID0gQWNjb3VudC5jb2xsZWN0Sm91cm5hbEVudHJpZXMoYWNjb3VudHMpO1xuICAgICAgY29uc3Qgam91cm5hbEVudHJpZXMgPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuICAgICAgam91cm5hbEVudHJpZXMubG9hZEVudHJpZXMoam91cm5hbEVudHJpZXNDb2xsZWN0KTtcblxuICAgICAgLy8gQWNjb3VudCBiYWxhbmNlIGZvcm1tYXR0ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHF1ZXJ5LlxuICAgICAgY29uc3QgYmFsYW5jZUZvcm1hdHRlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGFjY291bnRzXG4gICAgICAgIC5maWx0ZXIoKGFjY291bnQpID0+IChcbiAgICAgICAgICBhY2NvdW50LnRyYW5zYWN0aW9ucy5sZW5ndGggPiAwIHx8ICFmaWx0ZXIubm9uZV96ZXJvXG4gICAgICAgICkpXG4gICAgICAgIC5tYXAoKGFjY291bnQpID0+IHtcbiAgICAgICAgICBjb25zdCB0cmlhbCA9IGpvdXJuYWxFbnRyaWVzLmdldFRyaWFsQmFsYW5jZShhY2NvdW50LmlkKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudC5pZCxcbiAgICAgICAgICAgIGNvZGU6IGFjY291bnQuY29kZSxcbiAgICAgICAgICAgIGFjY291bnROb3JtYWw6IGFjY291bnQudHlwZS5ub3JtYWwsXG4gICAgICAgICAgICBjcmVkaXQ6IGJhbGFuY2VGb3JtYXR0ZXIodHJpYWwuY3JlZGl0KSxcbiAgICAgICAgICAgIGRlYml0OiBiYWxhbmNlRm9ybWF0dGVyKHRyaWFsLmRlYml0KSxcbiAgICAgICAgICAgIGJhbGFuY2U6IGJhbGFuY2VGb3JtYXR0ZXIodHJpYWwuYmFsYW5jZSksXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBtZXRhOiB7IC4uLmZpbHRlciB9LFxuICAgICAgICBpdGVtczogWy4uLml0ZW1zXSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHByb2ZpdC9sb3NzIGZpbmFuY2lhbCBzdGF0ZW1lbnQuXG4gICAqL1xuICBwcm9maXRMb3NzU2hlZXQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnYmFzaXMnKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ2Zyb21fZGF0ZScpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBxdWVyeSgndG9fZGF0ZScpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5ub19jZW50cycpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5kaXZpZGVfMTAwMCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCksXG4gICAgICBxdWVyeSgnYmFzaXMnKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ25vbmVfemVybycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnZGlzcGxheV9jb2x1bW5zX2J5Jykub3B0aW9uYWwoKS5pc0luKFsneWVhcicsICdtb250aCcsICd3ZWVrJywgJ2RheScsICdxdWFydGVyJ10pLFxuICAgICAgcXVlcnkoJ2FjY291bnRzJykub3B0aW9uYWwoKS5pc0FycmF5KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZmlsdGVyID0ge1xuICAgICAgICBmcm9tX2RhdGU6IG1vbWVudCgpLnN0YXJ0T2YoJ3llYXInKS5mb3JtYXQoJ1lZWVktTU0tREQnKSxcbiAgICAgICAgdG9fZGF0ZTogbW9tZW50KCkuZW5kT2YoJ3llYXInKS5mb3JtYXQoJ1lZWVktTU0tREQnKSxcbiAgICAgICAgbnVtYmVyX2Zvcm1hdDoge1xuICAgICAgICAgIG5vX2NlbnRzOiBmYWxzZSxcbiAgICAgICAgICBkaXZpZGVfMTAwMDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGJhc2lzOiAnYWNjdXJhbCcsXG4gICAgICAgIG5vbmVfemVybzogZmFsc2UsXG4gICAgICAgIGRpc3BsYXlfY29sdW1uc19ieTogJ21vbnRoJyxcbiAgICAgICAgLi4ucmVxLnF1ZXJ5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGluY29tZVN0YXRlbWVudFR5cGVzID0gYXdhaXQgQWNjb3VudFR5cGUucXVlcnkoKS53aGVyZSgnaW5jb21lX3NoZWV0JywgdHJ1ZSk7XG5cbiAgICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpXG4gICAgICAgIC53aGVyZUluKCdhY2NvdW50X3R5cGVfaWQnLCBpbmNvbWVTdGF0ZW1lbnRUeXBlcy5tYXAoKHQpID0+IHQuaWQpKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHlwZScpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCd0cmFuc2FjdGlvbnMnKTtcblxuICAgICAgY29uc3QgZmlsdGVyZWRBY2NvdW50cyA9IGFjY291bnRzLmZpbHRlcigoYWNjb3VudCkgPT4ge1xuICAgICAgICByZXR1cm4gYWNjb3VudC50cmFuc2FjdGlvbnMubGVuZ3RoID4gMCB8fCAhZmlsdGVyLm5vbmVfemVybztcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgam91cm5hbEVudHJpZXNDb2xsZWN0ZWQgPSBBY2NvdW50LmNvbGxlY3RKb3VybmFsRW50cmllcyhhY2NvdW50cyk7XG4gICAgICBjb25zdCBqb3VybmFsRW50cmllcyA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG4gICAgICBqb3VybmFsRW50cmllcy5sb2FkRW50cmllcyhqb3VybmFsRW50cmllc0NvbGxlY3RlZCk7XG5cbiAgICAgIC8vIEFjY291bnQgYmFsYW5jZSBmb3JtbWF0dGVyIGJhc2VkIG9uIHRoZSBnaXZlbiBxdWVyeS5cbiAgICAgIGNvbnN0IG51bWJlckZvcm1hdHRlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuXG4gICAgICAvLyBHZXRzIHRoZSBkYXRlIHJhbmdlIHNldCBmcm9tIHN0YXJ0IHRvIGVuZCBkYXRlLlxuICAgICAgY29uc3QgZGF0ZVJhbmdlU2V0ID0gZGF0ZVJhbmdlQ29sbGVjdGlvbihcbiAgICAgICAgZmlsdGVyLmZyb21fZGF0ZSxcbiAgICAgICAgZmlsdGVyLnRvX2RhdGUsXG4gICAgICAgIGZpbHRlci5kaXNwbGF5X2NvbHVtbnNfYnksXG4gICAgICApO1xuICAgICAgY29uc3QgYWNjb3VudHNJbmNvbWUgPSBmaWx0ZXJlZEFjY291bnRzXG4gICAgICAgIC5maWx0ZXIoKGFjY291bnQpID0+IGFjY291bnQudHlwZS5ub3JtYWwgPT09ICdjcmVkaXQnKVxuICAgICAgICAubWFwKChhY2NvdW50KSA9PiAoe1xuICAgICAgICAgIC4uLnBpY2soYWNjb3VudCwgWydpZCcsICdpbmRleCcsICduYW1lJywgJ2NvZGUnXSksXG4gICAgICAgICAgZGF0ZXM6IGRhdGVSYW5nZVNldC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBmaWx0ZXIuZGlzcGxheV9jb2x1bW5zX2J5O1xuICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gam91cm5hbEVudHJpZXMuZ2V0Q2xvc2luZ0JhbGFuY2UoYWNjb3VudC5pZCwgZGF0ZSwgdHlwZSk7XG5cbiAgICAgICAgICAgIHJldHVybiB7IGRhdGUsIHJhd0Ftb3VudDogYW1vdW50LCBhbW91bnQ6IG51bWJlckZvcm1hdHRlcihhbW91bnQpIH07XG4gICAgICAgICAgfSksXG4gICAgICAgIH0pKTtcblxuICAgICAgY29uc3QgYWNjb3VudHNFeHBlbnNlcyA9IGZpbHRlcmVkQWNjb3VudHNcbiAgICAgICAgLmZpbHRlcigoYWNjb3VudCkgPT4gYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2RlYml0JylcbiAgICAgICAgLm1hcCgoYWNjb3VudCkgPT4gKHtcbiAgICAgICAgICAuLi5waWNrKGFjY291bnQsIFsnaWQnLCAnaW5kZXgnLCAnbmFtZScsICdjb2RlJ10pLFxuICAgICAgICAgIGRhdGVzOiBkYXRlUmFuZ2VTZXQubWFwKChkYXRlKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0eXBlID0gZmlsdGVyLmRpc3BsYXlfY29sdW1uc19ieTtcbiAgICAgICAgICAgIGNvbnN0IGFtb3VudCA9IGpvdXJuYWxFbnRyaWVzLmdldENsb3NpbmdCYWxhbmNlKGFjY291bnQuaWQsIGRhdGUsIHR5cGUpO1xuXG4gICAgICAgICAgICByZXR1cm4geyBkYXRlLCByYXdBbW91bnQ6IGFtb3VudCwgYW1vdW50OiBudW1iZXJGb3JtYXR0ZXIoYW1vdW50KSB9O1xuICAgICAgICAgIH0pLFxuICAgICAgICB9KSk7XG5cbiAgICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRvdGFsIGluY29tZSBvZiBpbmNvbWUgYWNjb3VudHMuXG4gICAgICBjb25zdCB0b3RhbEFjY291bnRzSW5jb21lID0gZGF0ZVJhbmdlU2V0LnJlZHVjZSgoYWNjLCBkYXRlLCBpbmRleCkgPT4ge1xuICAgICAgICBsZXQgYW1vdW50ID0gMDtcbiAgICAgICAgYWNjb3VudHNJbmNvbWUuZm9yRWFjaCgoYWNjb3VudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gYWNjb3VudC5kYXRlc1tpbmRleF07XG4gICAgICAgICAgYW1vdW50ICs9IGN1cnJlbnREYXRlLnJhd0Ftb3VudCB8fCAwO1xuICAgICAgICB9KTtcbiAgICAgICAgYWNjW2RhdGVdID0geyBkYXRlLCByYXdBbW91bnQ6IGFtb3VudCwgYW1vdW50OiBudW1iZXJGb3JtYXR0ZXIoYW1vdW50KSB9O1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwge30pO1xuXG4gICAgICAvLyBDYWxjdWxhdGVzIHRoZSB0b3RhbCBleHBlbnNlcyBvZiBleHBlbnNlcyBhY2NvdW50cy5cbiAgICAgIGNvbnN0IHRvdGFsQWNjb3VudHNFeHBlbnNlcyA9IGRhdGVSYW5nZVNldC5yZWR1Y2UoKGFjYywgZGF0ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgbGV0IGFtb3VudCA9IDA7XG4gICAgICAgIGFjY291bnRzRXhwZW5zZXMuZm9yRWFjaCgoYWNjb3VudCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGN1cnJlbnREYXRlID0gYWNjb3VudC5kYXRlc1tpbmRleF07XG4gICAgICAgICAgYW1vdW50ICs9IGN1cnJlbnREYXRlLnJhd0Ftb3VudCB8fCAwO1xuICAgICAgICB9KTtcbiAgICAgICAgYWNjW2RhdGVdID0geyBkYXRlLCByYXdBbW91bnQ6IGFtb3VudCwgYW1vdW50OiBudW1iZXJGb3JtYXR0ZXIoYW1vdW50KSB9O1xuICAgICAgICByZXR1cm4gYWNjO1xuICAgICAgfSwge30pO1xuXG4gICAgICAvLyBUb3RhbCBpbmNvbWUoZGF0ZSkgLSBUb3RhbCBleHBlbnNlcyhkYXRlKSA9IE5ldCBpbmNvbWUoZGF0ZSlcbiAgICAgIGNvbnN0IG5ldEluY29tZSA9IGRhdGVSYW5nZVNldC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgY29uc3QgdG90YWxJbmNvbWUgPSB0b3RhbEFjY291bnRzSW5jb21lW2RhdGVdO1xuICAgICAgICBjb25zdCB0b3RhbEV4cGVuc2VzID0gdG90YWxBY2NvdW50c0V4cGVuc2VzW2RhdGVdO1xuXG4gICAgICAgIGxldCBhbW91bnQgPSB0b3RhbEluY29tZS5yYXdBbW91bnQgfHwgMDtcbiAgICAgICAgYW1vdW50IC09IHRvdGFsRXhwZW5zZXMucmF3QW1vdW50IHx8IDA7XG4gICAgICAgIHJldHVybiB7IGRhdGUsIHJhd0Ftb3VudDogYW1vdW50LCBhbW91bnQ6IG51bWJlckZvcm1hdHRlcihhbW91bnQpIH07XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgbWV0YTogeyAuLi5maWx0ZXIgfSxcbiAgICAgICAgaW5jb21lOiB7XG4gICAgICAgICAgZW50cnlfbm9ybWFsOiAnY3JlZGl0JyxcbiAgICAgICAgICBhY2NvdW50czogYWNjb3VudHNJbmNvbWUsXG4gICAgICAgIH0sXG4gICAgICAgIGV4cGVuc2VzOiB7XG4gICAgICAgICAgZW50cnlfbm9ybWFsOiAnZGViaXQnLFxuICAgICAgICAgIGFjY291bnRzOiBhY2NvdW50c0V4cGVuc2VzLFxuICAgICAgICB9LFxuICAgICAgICB0b3RhbF9pbmNvbWU6IE9iamVjdC52YWx1ZXModG90YWxBY2NvdW50c0luY29tZSksXG4gICAgICAgIHRvdGFsX2V4cGVuc2VzOiBPYmplY3QudmFsdWVzKHRvdGFsQWNjb3VudHNFeHBlbnNlcyksXG4gICAgICAgIHRvdGFsX25ldF9pbmNvbWU6IG5ldEluY29tZSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgY2FzaEZsb3dTdGF0ZW1lbnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnZGF0ZV9mcm9tJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdkYXRlX3RvJykub3B0aW9uYWwoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIFxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgbWV0YToge30sXG4gICAgICAgIG9wZXJhdGluZzogW10sXG4gICAgICAgIGZpbmFuY2luZzogW10sXG4gICAgICAgIGludmVzdGluZzogW10sXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxufVxuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgcGFyYW0sIHZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBJdGVtQ2F0ZWdvcnkgZnJvbSAnQC9tb2RlbHMvSXRlbUNhdGVnb3J5JztcbmltcG9ydCBBdXRob3JpemF0aW9uIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2F1dGhvcml6YXRpb24nO1xuaW1wb3J0IEpXVEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3RvciBtZXRob2QuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICBjb25zdCBwZXJtaXQgPSBBdXRob3JpemF0aW9uKCdpdGVtc19jYXRlZ29yaWVzJyk7XG5cbiAgICByb3V0ZXIudXNlKEpXVEF1dGgpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgcGVybWl0KCdjcmVhdGUnLCAnZWRpdCcpLFxuICAgICAgdGhpcy5lZGl0Q2F0ZWdvcnkudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmVkaXRDYXRlZ29yeS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICBwZXJtaXQoJ2NyZWF0ZScpLFxuICAgICAgdGhpcy5uZXdDYXRlZ29yeS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubmV3Q2F0ZWdvcnkuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmRlbGV0ZSgnLzppZCcsXG4gICAgICBwZXJtaXQoJ2NyZWF0ZScsICdlZGl0JywgJ2RlbGV0ZScpLFxuICAgICAgdGhpcy5kZWxldGVJdGVtLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVJdGVtLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy86aWQnLFxuICAgICAgcGVybWl0KCd2aWV3JyksXG4gICAgICB0aGlzLmdldENhdGVnb3J5LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRDYXRlZ29yeS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHBlcm1pdCgndmlldycpLFxuICAgICAgdGhpcy5nZXRMaXN0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRMaXN0LnZhbGlkYXRpb24pKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgaXRlbSBjYXRlZ29yeS5cbiAgICovXG4gIG5ld0NhdGVnb3J5OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoeyBjaGVja0ZhbHN5OiB0cnVlIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdwYXJlbnRfY2F0ZWdvcnlfaWQnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgbmFtZSwgcGFyZW50X2NhdGVnb3J5X2lkOiBwYXJlbnRDYXRlZ29yeUlkLCBkZXNjcmlwdGlvbiB9ID0gcmVxLmJvZHk7XG5cbiAgICAgIGlmIChwYXJlbnRDYXRlZ29yeUlkKSB7XG4gICAgICAgIGNvbnN0IGZvdW5kUGFyZW50Q2F0ZWdvcnkgPSBhd2FpdCBJdGVtQ2F0ZWdvcnkud2hlcmUoJ2lkJywgcGFyZW50Q2F0ZWdvcnlJZCkuZmV0Y2goKTtcblxuICAgICAgICBpZiAoIWZvdW5kUGFyZW50Q2F0ZWdvcnkpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoJ1RoZSBwYXJlbnQgY2F0ZWdvcnkgSUQgaXMgbm90IGZvdW5kLicsIHtcbiAgICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1BBUkVOVF9DQVRFR09SWV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGNvbnN0IGNhdGVnb3J5ID0gYXdhaXQgSXRlbUNhdGVnb3J5LmZvcmdlKHtcbiAgICAgICAgbGFiZWw6IG5hbWUsXG4gICAgICAgIHBhcmVudF9jYXRlZ29yeV9pZDogcGFyZW50Q2F0ZWdvcnlJZCxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICB9KTtcblxuICAgICAgYXdhaXQgY2F0ZWdvcnkuc2F2ZSgpO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGNhdGVnb3J5LmdldCgnaWQnKSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBFZGl0IGRldGFpbHMgb2YgdGhlIGdpdmVuIGNhdGVnb3J5IGl0ZW0uXG4gICAqL1xuICBlZGl0Q2F0ZWdvcnk6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS50b0ludCgpLFxuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoeyBjaGVja0ZhbHN5OiB0cnVlIH0pLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdwYXJlbnRfY2F0ZWdvcnlfaWQnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBuYW1lLCBwYXJlbnRfY2F0ZWdvcnlfaWQ6IHBhcmVudENhdGVnb3J5SWQsIGRlc2NyaXB0aW9uIH0gPSByZXEuYm9keTtcbiAgICAgIGNvbnN0IGl0ZW1DYXRlZ29yeSA9IGF3YWl0IEl0ZW1DYXRlZ29yeS53aGVyZSgnaWQnLCBpZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCFpdGVtQ2F0ZWdvcnkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICBpZiAocGFyZW50Q2F0ZWdvcnlJZCAmJiBwYXJlbnRDYXRlZ29yeUlkICE9PSBpdGVtQ2F0ZWdvcnkuYXR0cmlidXRlcy5wYXJlbnRfY2F0ZWdvcnlfaWQpIHtcbiAgICAgICAgY29uc3QgZm91bmRQYXJlbnRDYXRlZ29yeSA9IGF3YWl0IEl0ZW1DYXRlZ29yeS53aGVyZSgnaWQnLCBwYXJlbnRDYXRlZ29yeUlkKS5mZXRjaCgpO1xuXG4gICAgICAgIGlmICghZm91bmRQYXJlbnRDYXRlZ29yeSkge1xuICAgICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgnVGhlIHBhcmVudCBjYXRlZ29yeSBJRCBpcyBub3QgZm91bmQuJywge1xuICAgICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUEFSRU5UX0NBVEVHT1JZX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgYXdhaXQgaXRlbUNhdGVnb3J5LnNhdmUoe1xuICAgICAgICBsYWJlbDogbmFtZSxcbiAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgIHBhcmVudF9jYXRlZ29yeV9pZDogcGFyZW50Q2F0ZWdvcnlJZCxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogaXRlbUNhdGVnb3J5LmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZSBpdGVtIGNhdGVnb3J5LlxuICAgKi9cbiAgZGVsZXRlSXRlbToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgaXRlbUNhdGVnb3J5ID0gYXdhaXQgSXRlbUNhdGVnb3J5LndoZXJlKCdpZCcsIGlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWl0ZW1DYXRlZ29yeSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGl0ZW1DYXRlZ29yeS5kZXN0cm95KCk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgbGlzdCBvZiBpdGVtcy5cbiAgICovXG4gIGdldExpc3Q6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IEl0ZW1DYXRlZ29yeS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWl0ZW1zKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaXRlbXM6IGl0ZW1zLnRvSlNPTigpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGRldGFpbHMgb2YgdGhlIGdpdmVuIGNhdGVnb3J5LlxuICAgKi9cbiAgZ2V0Q2F0ZWdvcnk6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnY2F0ZWdvcnlfaWQnKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBjYXRlZ29yeV9pZDogY2F0ZWdvcnlJZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGl0ZW0gPSBhd2FpdCBJdGVtQ2F0ZWdvcnkud2hlcmUoJ2lkJywgY2F0ZWdvcnlJZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCFpdGVtKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnQ0FURUdPUllfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgY2F0ZWdvcnk6IGl0ZW0udG9KU09OKCkgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGNoZWNrLCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgand0QXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBJdGVtIGZyb20gJ0AvbW9kZWxzL0l0ZW0nO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgSXRlbUNhdGVnb3J5IGZyb20gJ0AvbW9kZWxzL0l0ZW1DYXRlZ29yeSc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IFJlc291cmNlRmllbGQgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZCc7XG5pbXBvcnQgQXV0aG9yaXphdGlvbiBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hdXRob3JpemF0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIGNvbnN0IHBlcm1pdCA9IEF1dGhvcml6YXRpb24oJ2l0ZW1zJyk7XG5cbiAgICByb3V0ZXIudXNlKGp3dEF1dGgpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgdGhpcy5lZGl0SXRlbS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdEl0ZW0uaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy8nLFxuICAgICAgLy8gcGVybWl0KCdjcmVhdGUnKSxcbiAgICAgIHRoaXMubmV3SXRlbS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubmV3SXRlbS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOmlkJyxcbiAgICAgIHRoaXMuZGVsZXRlSXRlbS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlSXRlbS5oYW5kbGVyKSk7XG5cbiAgICAvLyByb3V0ZXIuZ2V0KCcvOmlkJyxcbiAgICAvLyAgIHRoaXMuZ2V0Q2F0ZWdvcnkudmFsaWRhdGlvbixcbiAgICAvLyAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldENhdGVnb3J5LmhhbmRsZXIpKTtcblxuICAgIC8vIHJvdXRlci5nZXQoJy8nLFxuICAgIC8vICAgdGhpcy5jYXRlZ29yaWVzTGlzdC52YWxpZGF0aW9uLFxuICAgIC8vICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuY2F0ZWdvcmllc0xpc3QudmFsaWRhdGlvbikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBpdGVtLlxuICAgKi9cbiAgbmV3SXRlbToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCduYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygndHlwZScpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKS5pc0luKFsnc2VydmljZScsICdwcm9kdWN0J10pLFxuICAgICAgY2hlY2soJ2Nvc3RfcHJpY2UnKS5leGlzdHMoKS5pc051bWVyaWMoKSxcbiAgICAgIGNoZWNrKCdzZWxsX3ByaWNlJykuZXhpc3RzKCkuaXNOdW1lcmljKCksXG4gICAgICBjaGVjaygnY29zdF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNJbnQoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ3NlbGxfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzSW50KCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdjYXRlZ29yeV9pZCcpLm9wdGlvbmFsKCkuaXNJbnQoKS50b0ludCgpLFxuXG4gICAgICBjaGVjaygnY3VzdG9tX2ZpZWxkcycpLm9wdGlvbmFsKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzLioua2V5JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzLioudmFsdWUnKS5leGlzdHMoKSxcblxuICAgICAgY2hlY2soJ25vdGUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7XG4gICAgICAgIGN1c3RvbV9maWVsZHM6IFtdLFxuICAgICAgICAuLi5yZXEuYm9keSxcbiAgICAgIH07XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcblxuICAgICAgY29uc3QgY29zdEFjY291bnRQcm9taXNlID0gQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGZvcm0uY29zdF9hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IHNlbGxBY2NvdW50UHJvbWlzZSA9IEFjY291bnQucXVlcnkoKS5maW5kQnlJZChmb3JtLnNlbGxfYWNjb3VudF9pZCk7XG4gICAgICBjb25zdCBpdGVtQ2F0ZWdvcnlQcm9taXNlID0gKGZvcm0uY2F0ZWdvcnlfaWQpXG4gICAgICAgID8gSXRlbUNhdGVnb3J5LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5jYXRlZ29yeV9pZCkgOiBudWxsO1xuXG4gICAgICAvLyBWYWxpZGF0ZSB0aGUgY3VzdG9tIGZpZWxkcyBrZXkgYW5kIHZhbHVlIHR5cGUuXG4gICAgICBpZiAoZm9ybS5jdXN0b21fZmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgY3VzdG9tRmllbGRzS2V5cyA9IGZvcm0uY3VzdG9tX2ZpZWxkcy5tYXAoKGZpZWxkKSA9PiBmaWVsZC5rZXkpO1xuXG4gICAgICAgIC8vIEdldCByZXNvdXJjZSBpZCB0aGFuIGdldCBhbGwgcmVzb3VyY2UgZmllbGRzLlxuICAgICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLndoZXJlKCduYW1lJywgJ2l0ZW1zJykuZmV0Y2goKTtcbiAgICAgICAgY29uc3QgZmllbGRzID0gYXdhaXQgUmVzb3VyY2VGaWVsZC5xdWVyeSgocXVlcnkpID0+IHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgncmVzb3VyY2VfaWQnLCByZXNvdXJjZS5pZCk7XG4gICAgICAgICAgcXVlcnkud2hlcmVJbigna2V5JywgY3VzdG9tRmllbGRzS2V5cyk7XG4gICAgICAgIH0pLmZldGNoQWxsKCk7XG5cbiAgICAgICAgY29uc3Qgc3RvcmVkRmllbGRzS2V5ID0gZmllbGRzLm1hcCgoZikgPT4gZi5hdHRyaWJ1dGVzLmtleSk7XG5cbiAgICAgICAgLy8gR2V0IGFsbCBub3QgZGVmaW5lZCByZXNvdXJjZSBmaWVsZHMuXG4gICAgICAgIGNvbnN0IG5vdEZvdW5kRmllbGRzID0gZGlmZmVyZW5jZShjdXN0b21GaWVsZHNLZXlzLCBzdG9yZWRGaWVsZHNLZXkpO1xuXG4gICAgICAgIGlmIChub3RGb3VuZEZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRklFTERfS0VZX05PVF9GT1VORCcsIGNvZGU6IDE1MCwgZmllbGRzOiBub3RGb3VuZEZpZWxkcyB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgW2Nvc3RBY2NvdW50LCBzZWxsQWNjb3VudCwgaXRlbUNhdGVnb3J5XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgY29zdEFjY291bnRQcm9taXNlLCBzZWxsQWNjb3VudFByb21pc2UsIGl0ZW1DYXRlZ29yeVByb21pc2UsXG4gICAgICBdKTtcbiAgICAgIGlmICghY29zdEFjY291bnQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQ09TVF9BQ0NPVU5UX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghc2VsbEFjY291bnQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnU0VMTF9BQ0NPVU5UX05PVF9GT1VORCcsIGNvZGU6IDEyMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghaXRlbUNhdGVnb3J5ICYmIGZvcm0uY2F0ZWdvcnlfaWQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnSVRFTV9DQVRFR09SWV9OT1RfRk9VTkQnLCBjb2RlOiAxNDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwgeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGl0ZW0gPSBhd2FpdCBJdGVtLnF1ZXJ5KCkuaW5zZXJ0QW5kRmV0Y2goe1xuICAgICAgICBuYW1lOiBmb3JtLm5hbWUsXG4gICAgICAgIHR5cGU6IGZvcm0udHlwZSxcbiAgICAgICAgY29zdF9wcmljZTogZm9ybS5jb3N0X3ByaWNlLFxuICAgICAgICBzZWxsX3ByaWNlOiBmb3JtLnNlbGxfcHJpY2UsXG4gICAgICAgIHNlbGxfYWNjb3VudF9pZDogZm9ybS5zZWxsX2FjY291bnRfaWQsXG4gICAgICAgIGNvc3RfYWNjb3VudF9pZDogZm9ybS5jb3N0X2FjY291bnRfaWQsXG4gICAgICAgIGN1cnJlbmN5X2NvZGU6IGZvcm0uY3VycmVuY3lfY29kZSxcbiAgICAgICAgbm90ZTogZm9ybS5ub3RlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogaXRlbS5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBFZGl0IHRoZSBnaXZlbiBpdGVtLlxuICAgKi9cbiAgZWRpdEl0ZW06IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ3R5cGUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCkuaXNJbihbJ3Byb2R1Y3QnLCAnc2VydmljZSddKSxcbiAgICAgIGNoZWNrKCdjb3N0X3ByaWNlJykuZXhpc3RzKCkuaXNOdW1lcmljKCksXG4gICAgICBjaGVjaygnc2VsbF9wcmljZScpLmV4aXN0cygpLmlzTnVtZXJpYygpLFxuICAgICAgY2hlY2soJ2Nvc3RfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzSW50KCksXG4gICAgICBjaGVjaygnc2VsbF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNJbnQoKSxcbiAgICAgIGNoZWNrKCdjYXRlZ29yeV9pZCcpLm9wdGlvbmFsKCkuaXNJbnQoKSxcbiAgICAgIGNoZWNrKCdub3RlJykub3B0aW9uYWwoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBmb3JtID0ge1xuICAgICAgICBjdXN0b21fZmllbGRzOiBbXSxcbiAgICAgICAgLi4ucmVxLmJvZHksXG4gICAgICB9O1xuICAgICAgY29uc3QgaXRlbSA9IGF3YWl0IEl0ZW0ucXVlcnkoKS5maW5kQnlJZChpZCk7XG4gICAgICBcbiAgICAgIGlmICghaXRlbSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwgeyBlcnJvcnM6IFtcbiAgICAgICAgICB7IHR5cGU6ICdJVEVNLk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9LFxuICAgICAgICBdfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcblxuICAgICAgY29uc3QgY29zdEFjY291bnRQcm9taXNlID0gQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGZvcm0uY29zdF9hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IHNlbGxBY2NvdW50UHJvbWlzZSA9IEFjY291bnQucXVlcnkoKS5maW5kQnlJZChmb3JtLnNlbGxfYWNjb3VudF9pZCk7XG4gICAgICBjb25zdCBpdGVtQ2F0ZWdvcnlQcm9taXNlID0gKGZvcm0uY2F0ZWdvcnlfaWQpXG4gICAgICAgID8gSXRlbUNhdGVnb3J5LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5jYXRlZ29yeV9pZCkgOiBudWxsO1xuXG4gICAgICBjb25zdCBbY29zdEFjY291bnQsIHNlbGxBY2NvdW50LCBpdGVtQ2F0ZWdvcnldID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBjb3N0QWNjb3VudFByb21pc2UsIHNlbGxBY2NvdW50UHJvbWlzZSwgaXRlbUNhdGVnb3J5UHJvbWlzZSxcbiAgICAgIF0pO1xuICAgICAgaWYgKCFjb3N0QWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdDT1NUX0FDQ09VTlRfTk9UX0ZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFzZWxsQWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdTRUxMX0FDQ09VTlRfTk9UX0ZPVU5EJywgY29kZTogMTIwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFpdGVtQ2F0ZWdvcnkgJiYgZm9ybS5jYXRlZ29yeV9pZCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdJVEVNX0NBVEVHT1JZX05PVF9GT1VORCcsIGNvZGU6IDE0MCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1cGRhdGVkSXRlbSA9IGF3YWl0IEl0ZW0ucXVlcnkoKS5maW5kQnlJZChpZCkucGF0Y2goe1xuICAgICAgICBuYW1lOiBmb3JtLm5hbWUsXG4gICAgICAgIHR5cGU6IGZvcm0udHlwZSxcbiAgICAgICAgY29zdF9wcmljZTogZm9ybS5jb3N0X3ByaWNlLFxuICAgICAgICBzZWxsX3ByaWNlOiBmb3JtLnNlbGxfcHJpY2UsXG4gICAgICAgIGN1cnJlbmN5X2NvZGU6IGZvcm0uY3VycmVuY3lfY29kZSxcbiAgICAgICAgc2VsbF9hY2NvdW50X2lkOiBmb3JtLnNlbGxfYWNjb3VudF9pZCxcbiAgICAgICAgY29zdF9hY2NvdW50X2lkOiBmb3JtLmNvc3RfYWNjb3VudF9pZCxcbiAgICAgICAgY2F0ZWdvcnlfaWQ6IGZvcm0uY2F0ZWdvcnlfaWQsXG4gICAgICAgIG5vdGU6IGZvcm0ubm90ZSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHVwZGF0ZWRJdGVtLmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZW4gaXRlbSBmcm9tIHRoZSBzdG9yYWdlLlxuICAgKi9cbiAgZGVsZXRlSXRlbToge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBpdGVtID0gYXdhaXQgSXRlbS5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFpdGVtKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnSVRFTV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBEZWxldGUgdGhlIGZ1Y2tpbmcgdGhlIGdpdmVuIGl0ZW0gaWQuXG4gICAgICBhd2FpdCBJdGVtLnF1ZXJ5KCkuZmluZEJ5SWQoaXRlbS5pZCkuZGVsZXRlKCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpdmUgdGhlIGxpc3QgaXRlbXMgd2l0aCBwYWdpbmF0aW9uIG1ldGEuXG4gICAqL1xuICBsaXN0SXRlbXM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIG5hbWU6ICcnLFxuICAgICAgICBkZXNjcmlwdGlvbjogJycsXG4gICAgICAgIFNLVTogJycsXG4gICAgICAgIGFjY291bnRfaWQ6IG51bGwsXG4gICAgICAgIHBhZ2Vfc2l6ZTogMTAsXG4gICAgICAgIHBhZ2U6IDEsXG4gICAgICAgIHN0YXJ0X2RhdGU6IG51bGwsXG4gICAgICAgIGVuZF9kYXRlOiBudWxsLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBpdGVtcyA9IGF3YWl0IEl0ZW0ucXVlcnkoKHF1ZXJ5KSA9PiB7XG4gICAgICAgIGlmIChmaWx0ZXIuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnZGVzY3JpcHRpb24nLCAnbGlrZScsIGAlJHtmaWx0ZXIuZGVzY3JpcHRpb259JWApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXIuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnU0tVJywgZmlsdGVyLlNLWSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5uYW1lKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ25hbWUnLCBmaWx0ZXIubmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5zdGFydF9kYXRlKSB7XG4gICAgICAgICAgY29uc3Qgc3RhcnREYXRlRm9ybWF0dGVkID0gbW9tZW50KGZpbHRlci5zdGFydF9kYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQgSEg6bW06U1MnKTtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnY3JlYXRlZF9hdCcsICc+PScsIHN0YXJ0RGF0ZUZvcm1hdHRlZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5lbmRfZGF0ZSkge1xuICAgICAgICAgIGNvbnN0IGVuZERhdGVGb3JtYXR0ZWQgPSBtb21lbnQoZmlsdGVyLmVuZF9kYXRlKS5mb3JtYXQoJ1lZWVktTU0tREQgSEg6bW06U1MnKTtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnY3JlYXRlZF9hdCcsICc8PScsIGVuZERhdGVGb3JtYXR0ZWQpO1xuICAgICAgICB9XG4gICAgICB9KS5mZXRjaFBhZ2Uoe1xuICAgICAgICBwYWdlX3NpemU6IGZpbHRlci5wYWdlX3NpemUsXG4gICAgICAgIHBhZ2U6IGZpbHRlci5wYWdlLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGl0ZW1zOiBpdGVtcy50b0pTT04oKSxcbiAgICAgICAgcGFnaW5hdGlvbjogaXRlbXMucGFnaW5hdGlvbixcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBib2R5LCBxdWVyeSwgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBPcHRpb24gZnJvbSAnQC9tb2RlbHMvT3B0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLnNhdmVPcHRpb25zLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5zYXZlT3B0aW9ucy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHRoaXMuZ2V0T3B0aW9ucy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0U2V0dGluZ3MpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBnaXZlbiBvcHRpb25zIHRvIHRoZSBzdG9yYWdlLlxuICAgKi9cbiAgc2F2ZU9wdGlvbnM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBib2R5KCdvcHRpb25zJykuaXNBcnJheSgpLFxuICAgICAgYm9keSgnb3B0aW9ucy4qLmtleScpLmV4aXN0cygpLFxuICAgICAgYm9keSgnb3B0aW9ucy4qLnZhbHVlJykuZXhpc3RzKCksXG4gICAgICBib2R5KCdvcHRpb25zLiouZ3JvdXAnKS5leGlzdHMoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICdWQUxJREFUSU9OX0VSUk9SJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3Qgb3B0aW9uc0NvbGxlY3Rpb25zID0gYXdhaXQgT3B0aW9uLnF1ZXJ5KCk7XG5cbiAgICAgIGZvcm0ub3B0aW9ucy5mb3JFYWNoKChvcHRpb24pID0+IHtcbiAgICAgICAgb3B0aW9uc0NvbGxlY3Rpb25zLnNldE1ldGEob3B0aW9uLmtleSwgb3B0aW9uLnZhbHVlLCBvcHRpb24uZ3JvdXApO1xuICAgICAgfSk7XG4gICAgICBhd2FpdCBvcHRpb25zQ29sbGVjdGlvbnMuc2F2ZU1ldGEoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGFwcGxpY2F0aW9uIG9wdGlvbnMgZnJvbSB0aGUgc3RvcmFnZS5cbiAgICovXG4gIGdldE9wdGlvbnM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgna2V5Jykub3B0aW9uYWwoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICdWQUxJREFUSU9OX0VSUk9SJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBvcHRpb25zID0gYXdhaXQgT3B0aW9uLnF1ZXJ5KCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZHMoeyBvcHRpb25zIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQge1xuICBwYXJhbSxcbiAgcXVlcnksXG4gIHZhbGlkYXRpb25SZXN1bHQsXG59IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IFJlc291cmNlIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIudXNlKGp3dEF1dGgpO1xuXG4gICAgcm91dGVyLmdldCgnLzpyZXNvdXJjZV9zbHVnL2NvbHVtbnMnLFxuICAgICAgdGhpcy5yZXNvdXJjZUNvbHVtbnMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlc291cmNlQ29sdW1ucy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvOnJlc291cmNlX3NsdWcvZmllbGRzJyxcbiAgICAgIHRoaXMucmVzb3VyY2VGaWVsZHMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlc291cmNlRmllbGRzLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHJlc291cmNlIGNvbHVtbnMgb2YgdGhlIGdpdmVuIHJlc291cmNlLlxuICAgKi9cbiAgcmVzb3VyY2VDb2x1bW5zOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ3Jlc291cmNlX3NsdWcnKS50cmltKCkuZXNjYXBlKCkuZXhpc3RzKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IHJlc291cmNlX3NsdWc6IHJlc291cmNlU2x1ZyB9ID0gcmVxLnBhcmFtcztcblxuICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnbmFtZScsIHJlc291cmNlU2x1ZylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ2ZpZWxkcycpXG4gICAgICAgIC5maXJzdCgpO1xuXG4gICAgICBpZiAoIXJlc291cmNlKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUkVTT1VSQ0UuU0xVRy5OT1QuRk9VTkQnLCBjb2RlOiAyMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzb3VyY2VGaWVsZHMgPSByZXNvdXJjZS5maWVsZHNcbiAgICAgICAgLmZpbHRlcigoZmllbGQpID0+IGZpZWxkLmNvbHVtbmFibGUpXG4gICAgICAgIC5tYXAoKGZpZWxkKSA9PiAoe1xuICAgICAgICAgIGlkOiBmaWVsZC5pZCxcbiAgICAgICAgICBsYWJlbDogZmllbGQubGFiZWxOYW1lLFxuICAgICAgICAgIGtleTogZmllbGQua2V5LFxuICAgICAgICB9KSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIHJlc291cmNlX2NvbHVtbnM6IHJlc291cmNlRmllbGRzLFxuICAgICAgICByZXNvdXJjZV9zbHVnOiByZXNvdXJjZVNsdWcsXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSByZXNvdXJjZSBmaWVsZHMgb2YgdGhlIGdpdmVuIHJlc291cmNlLlxuICAgKi9cbiAgcmVzb3VyY2VGaWVsZHM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgncmVzb3VyY2Vfc2x1ZycpLnRyaW0oKS5lc2NhcGUoKS5leGlzdHMoKSxcbiAgICAgIHF1ZXJ5KCdwcmVkZWZpbmVkJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdidWlsdGluJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgcmVzb3VyY2Vfc2x1ZzogcmVzb3VyY2VTbHVnIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCduYW1lJywgcmVzb3VyY2VTbHVnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnZmllbGRzJylcbiAgICAgICAgLmZpcnN0KCk7XG5cbiAgICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdSRVNPVVJDRS5TTFVHLk5PVC5GT1VORCcsIGNvZGU6IDIwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICByZXNvdXJjZV9maWVsZHM6IHJlc291cmNlLmZpZWxkcyxcbiAgICAgICAgcmVzb3VyY2Vfc2x1ZzogcmVzb3VyY2VTbHVnLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCB7IGRpZmZlcmVuY2UgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IFJvbGUgZnJvbSAnQC9tb2RlbHMvUm9sZSc7XG5pbXBvcnQgUGVybWlzc2lvbiBmcm9tICdAL21vZGVscy9QZXJtaXNzaW9uJztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICdAL21vZGVscy9SZXNvdXJjZSc7XG5pbXBvcnQga25leCBmcm9tICdAL2RhdGFiYXNlL2tuZXgnO1xuXG5jb25zdCBBY2Nlc3NDb250cm9sbFNjaGVtYSA9IFtcbiAge1xuICAgIHJlc291cmNlOiAnaXRlbXMnLFxuICAgIGxhYmVsOiAncHJvZHVjdHNfc2VydmljZXMnLFxuICAgIHBlcm1pc3Npb25zOiBbJ2NyZWF0ZScsICdlZGl0JywgJ2RlbGV0ZScsICd2aWV3J10sXG4gICAgZnVsbEFjY2VzczogdHJ1ZSxcbiAgICBvd25Db250cm9sOiB0cnVlLFxuICB9LFxuXTtcblxuY29uc3QgZ2V0UmVzb3VyY2VTY2hlbWEgPSAocmVzb3VyY2UpID0+IEFjY2Vzc0NvbnRyb2xsU2NoZW1hXG4gIC5maW5kKChzY2hlbWEpID0+IHNjaGVtYS5yZXNvdXJjZSA9PT0gcmVzb3VyY2UpO1xuXG5jb25zdCBnZXRSZXNvdXJjZVBlcm1pc3Npb25zID0gKHJlc291cmNlKSA9PiB7XG4gIGNvbnN0IGZvdW5kUmVzb3VyY2UgPSBnZXRSZXNvdXJjZVNjaGVtYShyZXNvdXJjZSk7XG4gIHJldHVybiBmb3VuZFJlc291cmNlID8gZm91bmRSZXNvdXJjZS5wZXJtaXNzaW9ucyA6IFtdO1xufTtcblxuY29uc3QgZmluZE5vdEZvdW5kUmVzb3VyY2VzID0gKHJlc291cmNlc1NsdWdzKSA9PiB7XG4gIGNvbnN0IHNjaGVtYVJlc291cmNlc1NsdWdzID0gQWNjZXNzQ29udHJvbGxTY2hlbWEubWFwKChzKSA9PiBzLnJlc291cmNlKTtcbiAgcmV0dXJuIGRpZmZlcmVuY2UocmVzb3VyY2VzU2x1Z3MsIHNjaGVtYVJlc291cmNlc1NsdWdzKTtcbn07XG5cbmNvbnN0IGZpbmROb3RGb3VuZFBlcm1pc3Npb25zID0gKHBlcm1pc3Npb25zLCByZXNvdXJjZVNsdWcpID0+IHtcbiAgY29uc3Qgc2NoZW1hUGVybWlzc2lvbnMgPSBnZXRSZXNvdXJjZVBlcm1pc3Npb25zKHJlc291cmNlU2x1Zyk7XG4gIHJldHVybiBkaWZmZXJlbmNlKHBlcm1pc3Npb25zLCBzY2hlbWFQZXJtaXNzaW9ucyk7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IgbWV0aG9kLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLm5ld1JvbGUudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm5ld1JvbGUuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgdGhpcy5lZGl0Um9sZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdFJvbGUuaGFuZGxlci5iaW5kKHRoaXMpKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOmlkJyxcbiAgICAgIHRoaXMuZGVsZXRlUm9sZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlUm9sZS5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHJvbGUuXG4gICAqL1xuICBuZXdSb2xlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdwZXJtaXNzaW9ucycpLmlzQXJyYXkoeyBtaW46IDAgfSksXG4gICAgICBjaGVjaygncGVybWlzc2lvbnMuKi5yZXNvdXJjZV9zbHVnJykuZXhpc3RzKCkud2hpdGVsaXN0KCdeW2EtejAtOV0rKD86LVthLXowLTldKykqJCcpLFxuICAgICAgY2hlY2soJ3Blcm1pc3Npb25zLioucGVybWlzc2lvbnMnKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgbmFtZSwgZGVzY3JpcHRpb24sIHBlcm1pc3Npb25zIH0gPSByZXEuYm9keTtcblxuICAgICAgY29uc3QgcmVzb3VyY2VzU2x1Z3MgPSBwZXJtaXNzaW9ucy5tYXAoKHBlcm0pID0+IHBlcm0ucmVzb3VyY2Vfc2x1Zyk7XG4gICAgICBjb25zdCBwZXJtaXNzaW9uc1NsdWdzID0gW107XG4gICAgICBjb25zdCByZXNvdXJjZXNOb3RGb3VuZCA9IGZpbmROb3RGb3VuZFJlc291cmNlcyhyZXNvdXJjZXNTbHVncyk7XG5cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3Qgbm90Rm91bmRQZXJtaXNzaW9ucyA9IFtdO1xuXG4gICAgICBpZiAocmVzb3VyY2VzTm90Rm91bmQubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ1JFU09VUkNFX1NMVUdfTk9UX0ZPVU5EJywgY29kZTogMTAwLCByZXNvdXJjZXM6IHJlc291cmNlc05vdEZvdW5kLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHBlcm1pc3Npb25zLmZvckVhY2goKHBlcm0pID0+IHtcbiAgICAgICAgY29uc3QgYWJpbGl0aWVzID0gcGVybS5wZXJtaXNzaW9ucy5tYXAoKGFiaWxpdHkpID0+IGFiaWxpdHkpO1xuXG4gICAgICAgIC8vIEdldHMgdGhlIG5vdCBmb3VuZCBwZXJtaXNzaW9ucyBpbiB0aGUgc2NoZW1hLlxuICAgICAgICBjb25zdCBub3RGb3VuZEFiaWxpdGllcyA9IGZpbmROb3RGb3VuZFBlcm1pc3Npb25zKGFiaWxpdGllcywgcGVybS5yZXNvdXJjZV9zbHVnKTtcbiAgICAgICAgXG4gICAgICAgIGlmIChub3RGb3VuZEFiaWxpdGllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbm90Rm91bmRQZXJtaXNzaW9ucy5wdXNoKHtcbiAgICAgICAgICAgIHJlc291cmNlX3NsdWc6IHBlcm0ucmVzb3VyY2Vfc2x1ZyxcbiAgICAgICAgICAgIHBlcm1pc3Npb25zOiBub3RGb3VuZEFiaWxpdGllcyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBwZXJtcyA9IHBlcm0ucGVybWlzc2lvbnMgfHwgW107XG4gICAgICAgICAgcGVybXMuZm9yRWFjaCgocGVybWlzc2lvbikgPT4ge1xuICAgICAgICAgICAgaWYgKHBlcm1zLmluZGV4T2YocGVybWlzc2lvbikgIT09IC0xKSB7XG4gICAgICAgICAgICAgIHBlcm1pc3Npb25zU2x1Z3MucHVzaChwZXJtaXNzaW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAobm90Rm91bmRQZXJtaXNzaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnUEVSTUlTU0lPTlNfU0xVR19OT1RfRk9VTkQnLFxuICAgICAgICAgIGNvZGU6IDIwMCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogbm90Rm91bmRQZXJtaXNzaW9ucyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwgeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIC8vIFBlcm1pc3Npb25zLlxuICAgICAgY29uc3QgW3Jlc291cmNlc0NvbGxlY3Rpb24sIHBlcm1zQ29sbGVjdGlvbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIFJlc291cmNlLnF1ZXJ5KChxdWVyeSkgPT4geyBxdWVyeS53aGVyZUluKCduYW1lJywgcmVzb3VyY2VzU2x1Z3MpOyB9KS5mZXRjaEFsbCgpLFxuICAgICAgICBQZXJtaXNzaW9uLnF1ZXJ5KChxdWVyeSkgPT4geyBxdWVyeS53aGVyZUluKCduYW1lJywgcGVybWlzc2lvbnNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICBdKTtcblxuICAgICAgY29uc3Qgbm90U3RvcmVkUmVzb3VyY2VzID0gZGlmZmVyZW5jZShcbiAgICAgICAgcmVzb3VyY2VzU2x1Z3MsIHJlc291cmNlc0NvbGxlY3Rpb24ubWFwKChzKSA9PiBzLm5hbWUpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5vdFN0b3JlZFBlcm1pc3Npb25zID0gZGlmZmVyZW5jZShcbiAgICAgICAgcGVybWlzc2lvbnNTbHVncywgcGVybXNDb2xsZWN0aW9uLm1hcCgocGVybSkgPT4gcGVybS5zbHVnKSxcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGluc2VydFRocmVhZCA9IFtdO1xuXG4gICAgICBpZiAobm90U3RvcmVkUmVzb3VyY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaW5zZXJ0VGhyZWFkLnB1c2goa25leCgncmVzb3VyY2VzJykuaW5zZXJ0KFtcbiAgICAgICAgICAuLi5ub3RTdG9yZWRSZXNvdXJjZXMubWFwKChyZXNvdXJjZSkgPT4gKHsgbmFtZTogcmVzb3VyY2UgfSkpLFxuICAgICAgICBdKSk7XG4gICAgICB9XG4gICAgICBpZiAobm90U3RvcmVkUGVybWlzc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICBpbnNlcnRUaHJlYWQucHVzaChrbmV4KCdwZXJtaXNzaW9ucycpLmluc2VydChbXG4gICAgICAgICAgLi4ubm90U3RvcmVkUGVybWlzc2lvbnMubWFwKChwZXJtaXNzaW9uKSA9PiAoeyBuYW1lOiBwZXJtaXNzaW9uIH0pKSxcbiAgICAgICAgXSkpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChpbnNlcnRUaHJlYWQpO1xuXG4gICAgICBjb25zdCBbc3RvcmVkUGVybWlzc2lvbnMsIHN0b3JlZFJlc291cmNlc10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIFBlcm1pc3Npb24ucXVlcnkoKHEpID0+IHsgcS53aGVyZUluKCduYW1lJywgcGVybWlzc2lvbnNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICAgIFJlc291cmNlLnF1ZXJ5KChxKSA9PiB7IHEud2hlcmVJbignbmFtZScsIHJlc291cmNlc1NsdWdzKTsgfSkuZmV0Y2hBbGwoKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBzdG9yZWRSZXNvdXJjZXNTZXQgPSBuZXcgTWFwKHN0b3JlZFJlc291cmNlcy5tYXAoKHJlc291cmNlKSA9PiBbXG4gICAgICAgIHJlc291cmNlLmF0dHJpYnV0ZXMubmFtZSwgcmVzb3VyY2UuYXR0cmlidXRlcy5pZCxcbiAgICAgIF0pKTtcbiAgICAgIGNvbnN0IHN0b3JlZFBlcm1pc3Npb25zU2V0ID0gbmV3IE1hcChzdG9yZWRQZXJtaXNzaW9ucy5tYXAoKHBlcm0pID0+IFtcbiAgICAgICAgcGVybS5hdHRyaWJ1dGVzLm5hbWUsIHBlcm0uYXR0cmlidXRlcy5pZCxcbiAgICAgIF0pKTtcbiAgICAgIGNvbnN0IHJvbGUgPSBSb2xlLmZvcmdlKHsgbmFtZSwgZGVzY3JpcHRpb24gfSk7XG5cbiAgICAgIGF3YWl0IHJvbGUuc2F2ZSgpO1xuXG4gICAgICBjb25zdCByb2xlSGFzUGVybXMgPSBwZXJtaXNzaW9ucy5tYXAoKHJlc291cmNlKSA9PiByZXNvdXJjZS5wZXJtaXNzaW9ucy5tYXAoKHBlcm0pID0+ICh7XG4gICAgICAgIHJvbGVfaWQ6IHJvbGUuaWQsXG4gICAgICAgIHJlc291cmNlX2lkOiBzdG9yZWRSZXNvdXJjZXNTZXQuZ2V0KHJlc291cmNlLnJlc291cmNlX3NsdWcpLFxuICAgICAgICBwZXJtaXNzaW9uX2lkOiBzdG9yZWRQZXJtaXNzaW9uc1NldC5nZXQocGVybSksXG4gICAgICB9KSkpO1xuXG4gICAgICBpZiAocm9sZUhhc1Blcm1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgYXdhaXQga25leCgncm9sZV9oYXNfcGVybWlzc2lvbnMnKS5pbnNlcnQocm9sZUhhc1Blcm1zWzBdKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiByb2xlLmdldCgnaWQnKSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBFZGl0IHRoZSBnaXZlIHJvbGUuXG4gICAqL1xuICBlZGl0Um9sZToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCduYW1lJykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ2Rlc2NyaXB0aW9uJykub3B0aW9uYWwoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygncGVybWlzc2lvbnMnKS5pc0FycmF5KHsgbWluOiAwIH0pLFxuICAgICAgY2hlY2soJ3Blcm1pc3Npb25zLioucmVzb3VyY2Vfc2x1ZycpLmV4aXN0cygpLndoaXRlbGlzdCgnXlthLXowLTldKyg/Oi1bYS16MC05XSspKiQnKSxcbiAgICAgIGNoZWNrKCdwZXJtaXNzaW9ucy4qLnBlcm1pc3Npb25zJykuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCByb2xlID0gYXdhaXQgUm9sZS53aGVyZSgnaWQnLCBpZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCFyb2xlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUk9MRV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IHBlcm1pc3Npb25zIH0gPSByZXEuYm9keTtcbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3QgcGVybWlzc2lvbnNTbHVncyA9IFtdO1xuICAgICAgY29uc3Qgbm90Rm91bmRQZXJtaXNzaW9ucyA9IFtdO1xuXG4gICAgICBjb25zdCByZXNvdXJjZXNTbHVncyA9IHBlcm1pc3Npb25zLm1hcCgocGVybSkgPT4gcGVybS5yZXNvdXJjZV9zbHVnKTtcbiAgICAgIGNvbnN0IHJlc291cmNlc05vdEZvdW5kID0gZmluZE5vdEZvdW5kUmVzb3VyY2VzKHJlc291cmNlc1NsdWdzKTtcblxuICAgICAgaWYgKHJlc291cmNlc05vdEZvdW5kLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdSRVNPVVJDRV9TTFVHX05PVF9GT1VORCcsXG4gICAgICAgICAgY29kZTogMTAwLFxuICAgICAgICAgIHJlc291cmNlczogcmVzb3VyY2VzTm90Rm91bmQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBwZXJtaXNzaW9ucy5mb3JFYWNoKChwZXJtKSA9PiB7XG4gICAgICAgIGNvbnN0IGFiaWxpdGllcyA9IHBlcm0ucGVybWlzc2lvbnMubWFwKChhYmlsaXR5KSA9PiBhYmlsaXR5KTtcbiAgICAgICAgLy8gR2V0cyB0aGUgbm90IGZvdW5kIHBlcm1pc3Npb25zIGluIHRoZSBzY2hlbWEuXG4gICAgICAgIGNvbnN0IG5vdEZvdW5kQWJpbGl0aWVzID0gZmluZE5vdEZvdW5kUGVybWlzc2lvbnMoYWJpbGl0aWVzLCBwZXJtLnJlc291cmNlX3NsdWcpO1xuXG4gICAgICAgIGlmIChub3RGb3VuZEFiaWxpdGllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgbm90Rm91bmRQZXJtaXNzaW9ucy5wdXNoKHtcbiAgICAgICAgICAgIHJlc291cmNlX3NsdWc6IHBlcm0ucmVzb3VyY2Vfc2x1ZywgcGVybWlzc2lvbnM6IG5vdEZvdW5kQWJpbGl0aWVzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHBlcm1zID0gcGVybS5wZXJtaXNzaW9ucyB8fCBbXTtcbiAgICAgICAgICBwZXJtcy5mb3JFYWNoKChwZXJtaXNzaW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAocGVybXMuaW5kZXhPZihwZXJtaXNzaW9uKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnNTbHVncy5wdXNoKHBlcm1pc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgaWYgKG5vdEZvdW5kUGVybWlzc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ1BFUk1JU1NJT05TX1NMVUdfTk9UX0ZPVU5EJyxcbiAgICAgICAgICBjb2RlOiAyMDAsXG4gICAgICAgICAgcGVybWlzc2lvbnM6IG5vdEZvdW5kUGVybWlzc2lvbnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFBlcm1pc3Npb25zLlxuICAgICAgY29uc3QgW3Jlc291cmNlc0NvbGxlY3Rpb24sIHBlcm1zQ29sbGVjdGlvbl0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIFJlc291cmNlLnF1ZXJ5KChxdWVyeSkgPT4geyBxdWVyeS53aGVyZUluKCduYW1lJywgcmVzb3VyY2VzU2x1Z3MpOyB9KS5mZXRjaEFsbCgpLFxuICAgICAgICBQZXJtaXNzaW9uLnF1ZXJ5KChxdWVyeSkgPT4geyBxdWVyeS53aGVyZUluKCduYW1lJywgcGVybWlzc2lvbnNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICBdKTtcblxuICAgICAgY29uc3Qgbm90U3RvcmVkUmVzb3VyY2VzID0gZGlmZmVyZW5jZShcbiAgICAgICAgcmVzb3VyY2VzU2x1Z3MsIHJlc291cmNlc0NvbGxlY3Rpb24ubWFwKChzKSA9PiBzLm5hbWUpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IG5vdFN0b3JlZFBlcm1pc3Npb25zID0gZGlmZmVyZW5jZShcbiAgICAgICAgcGVybWlzc2lvbnNTbHVncywgcGVybXNDb2xsZWN0aW9uLm1hcCgocGVybSkgPT4gcGVybS5zbHVnKSxcbiAgICAgICk7XG4gICAgICBjb25zdCBpbnNlcnRUaHJlYWQgPSBbXTtcblxuICAgICAgaWYgKG5vdFN0b3JlZFJlc291cmNlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGluc2VydFRocmVhZC5wdXNoKGtuZXgoJ3Jlc291cmNlcycpLmluc2VydChbXG4gICAgICAgICAgLi4ubm90U3RvcmVkUmVzb3VyY2VzLm1hcCgocmVzb3VyY2UpID0+ICh7IG5hbWU6IHJlc291cmNlIH0pKSxcbiAgICAgICAgXSkpO1xuICAgICAgfVxuICAgICAgaWYgKG5vdFN0b3JlZFBlcm1pc3Npb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaW5zZXJ0VGhyZWFkLnB1c2goa25leCgncGVybWlzc2lvbnMnKS5pbnNlcnQoW1xuICAgICAgICAgIC4uLm5vdFN0b3JlZFBlcm1pc3Npb25zLm1hcCgocGVybWlzc2lvbikgPT4gKHsgbmFtZTogcGVybWlzc2lvbiB9KSksXG4gICAgICAgIF0pKTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoaW5zZXJ0VGhyZWFkKTtcblxuICAgICAgY29uc3QgW3N0b3JlZFBlcm1pc3Npb25zLCBzdG9yZWRSZXNvdXJjZXNdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBQZXJtaXNzaW9uLnF1ZXJ5KChxKSA9PiB7IHEud2hlcmVJbignbmFtZScsIHBlcm1pc3Npb25zU2x1Z3MpOyB9KS5mZXRjaEFsbCgpLFxuICAgICAgICBSZXNvdXJjZS5xdWVyeSgocSkgPT4geyBxLndoZXJlSW4oJ25hbWUnLCByZXNvdXJjZXNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICBdKTtcblxuICAgICAgY29uc3Qgc3RvcmVkUmVzb3VyY2VzU2V0ID0gbmV3IE1hcChzdG9yZWRSZXNvdXJjZXMubWFwKChyZXNvdXJjZSkgPT4gW1xuICAgICAgICByZXNvdXJjZS5hdHRyaWJ1dGVzLm5hbWUsIHJlc291cmNlLmF0dHJpYnV0ZXMuaWQsXG4gICAgICBdKSk7XG4gICAgICBjb25zdCBzdG9yZWRQZXJtaXNzaW9uc1NldCA9IG5ldyBNYXAoc3RvcmVkUGVybWlzc2lvbnMubWFwKChwZXJtKSA9PiBbXG4gICAgICAgIHBlcm0uYXR0cmlidXRlcy5uYW1lLCBwZXJtLmF0dHJpYnV0ZXMuaWQsXG4gICAgICBdKSk7XG5cbiAgICAgIGF3YWl0IHJvbGUuc2F2ZSgpO1xuXG5cbiAgICAgIGNvbnN0IHNhdmVkUm9sZUhhc1Blcm1zID0gYXdhaXQga25leCgncm9sZV9oYXNfcGVybWlzc2lvbnMnKS53aGVyZSh7XG4gICAgICAgIHJvbGVfaWQ6IHJvbGUuaWQsXG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coc2F2ZWRSb2xlSGFzUGVybXMpO1xuXG4gICAgICAvLyBjb25zdCByb2xlSGFzUGVybXMgPSBwZXJtaXNzaW9ucy5tYXAoKHJlc291cmNlKSA9PiByZXNvdXJjZS5wZXJtaXNzaW9ucy5tYXAoKHBlcm0pID0+ICh7XG4gICAgICAvLyAgIHJvbGVfaWQ6IHJvbGUuaWQsXG4gICAgICAvLyAgIHJlc291cmNlX2lkOiBzdG9yZWRSZXNvdXJjZXNTZXQuZ2V0KHJlc291cmNlLnJlc291cmNlX3NsdWcpLFxuICAgICAgLy8gICBwZXJtaXNzaW9uX2lkOiBzdG9yZWRQZXJtaXNzaW9uc1NldC5nZXQocGVybSksXG4gICAgICAvLyB9KSkpO1xuXG4gICAgICAvLyBpZiAocm9sZUhhc1Blcm1zLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vICAgYXdhaXQga25leCgncm9sZV9oYXNfcGVybWlzc2lvbnMnKS5pbnNlcnQocm9sZUhhc1Blcm1zWzBdKTtcbiAgICAgIC8vIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiByb2xlLmdldCgnaWQnKSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIGRlbGV0ZVJvbGU6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3Qgcm9sZSA9IGF3YWl0IFJvbGUud2hlcmUoJ2lkJywgaWQpLmZldGNoKCk7XG5cbiAgICAgIGlmICghcm9sZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChyb2xlLmF0dHJpYnV0ZXMucHJlZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUk9MRV9QUkVERUZJTkVEJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgYXdhaXQga25leCgncm9sZV9oYXNfcGVybWlzc2lvbnMnKVxuICAgICAgICAud2hlcmUoJ3JvbGVfaWQnLCByb2xlLmlkKS5kZWxldGUoeyByZXF1aXJlOiBmYWxzZSB9KTtcblxuICAgICAgYXdhaXQgcm9sZS5kZXN0cm95KCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgZ2V0Um9sZToge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQge1xuICBjaGVjayxcbiAgcXVlcnksXG4gIHBhcmFtLFxuICB2YWxpZGF0aW9uUmVzdWx0LFxufSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgVXNlciBmcm9tICdAL21vZGVscy9Vc2VyJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEF1dGhvcml6YXRpb24gZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXV0aG9yaXphdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgLy8gY29uc3QgcGVybWl0ID0gQXV0aG9yaXphdGlvbigndXNlcnMnKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICAvLyBwZXJtaXQoJ2NyZWF0ZScpLFxuICAgICAgdGhpcy5uZXdVc2VyLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdVc2VyLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmlkJyxcbiAgICAgIC8vIHBlcm1pdCgnY3JlYXRlJywgJ2VkaXQnKSxcbiAgICAgIHRoaXMuZWRpdFVzZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmVkaXRVc2VyLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgLy8gcGVybWl0KCd2aWV3JyksXG4gICAgICB0aGlzLmxpc3RVc2Vycy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubGlzdFVzZXJzLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy86aWQnLFxuICAgICAgLy8gcGVybWl0KCd2aWV3JyksXG4gICAgICB0aGlzLmdldFVzZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldFVzZXIuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmRlbGV0ZSgnLzppZCcsXG4gICAgICAvLyBwZXJtaXQoJ2NyZWF0ZScsICdlZGl0JywgJ2RlbGV0ZScpLFxuICAgICAgdGhpcy5kZWxldGVVc2VyLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVVc2VyLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgdXNlci5cbiAgICovXG4gIG5ld1VzZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnZmlyc3RfbmFtZScpLnRyaW0oKS5lc2NhcGUoKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdsYXN0X25hbWUnKS50cmltKCkuZXNjYXBlKCkuZXhpc3RzKCksXG4gICAgICBjaGVjaygnZW1haWwnKS5leGlzdHMoKS5pc0VtYWlsKCksXG4gICAgICBjaGVjaygncGhvbmVfbnVtYmVyJykub3B0aW9uYWwoKS5pc01vYmlsZVBob25lKCksXG4gICAgICBjaGVjaygncGFzc3dvcmQnKS5pc0xlbmd0aCh7IG1pbjogNCB9KS5leGlzdHMoKS5jdXN0b20oKHZhbHVlLCB7IHJlcSB9KSA9PiB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gcmVxLmJvZHkuY29uZmlybV9wYXNzd29yZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBhc3N3b3JkcyBkb24ndCBtYXRjaFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgY2hlY2soJ3N0YXR1cycpLmV4aXN0cygpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgZW1haWwsIHBob25lX251bWJlcjogcGhvbmVOdW1iZXIgfSA9IHJlcS5ib2R5O1xuXG4gICAgICBjb25zdCBmb3VuZFVzZXJzID0gYXdhaXQgVXNlci5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnZW1haWwnLCBlbWFpbClcbiAgICAgICAgLm9yV2hlcmUoJ3Bob25lX251bWJlcicsIHBob25lTnVtYmVyKTtcblxuICAgICAgY29uc3QgZm91bmRVc2VyRW1haWwgPSBmb3VuZFVzZXJzLmZpbmQoKHUpID0+IHUuZW1haWwgPT09IGVtYWlsKTtcbiAgICAgIGNvbnN0IGZvdW5kVXNlclBob25lID0gZm91bmRVc2Vycy5maW5kKCh1KSA9PiB1LnBob25lTnVtYmVyID09PSBwaG9uZU51bWJlcik7XG5cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuXG4gICAgICBpZiAoZm91bmRVc2VyRW1haWwpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRU1BSUxfQUxSRUFEWV9FWElTVCcsIGNvZGU6IDEwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZFVzZXJQaG9uZSkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdQSE9ORV9OVU1CRVJfQUxSRUFEWV9FWElTVCcsIGNvZGU6IDEyMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci5xdWVyeSgpLmluc2VydCh7XG4gICAgICAgIGZpcnN0X25hbWU6IHJlcS5ib2R5LmZpcnN0X25hbWUsXG4gICAgICAgIGxhc3RfbmFtZTogcmVxLmJvZHkubGFzdF9uYW1lLFxuICAgICAgICBlbWFpbDogcmVxLmJvZHkuZW1haWwsXG4gICAgICAgIHBob25lX251bWJlcjogcmVxLmJvZHkucGhvbmVfbnVtYmVyLFxuICAgICAgICBhY3RpdmU6IHJlcS5ib2R5LnN0YXR1cyxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB1c2VyIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEVkaXQgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gdXNlci5cbiAgICovXG4gIGVkaXRVc2VyOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdmaXJzdF9uYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnbGFzdF9uYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnZW1haWwnKS5leGlzdHMoKS5pc0VtYWlsKCksXG4gICAgICBjaGVjaygncGhvbmVfbnVtYmVyJykub3B0aW9uYWwoKS5pc01vYmlsZVBob25lKCksXG4gICAgICBjaGVjaygncGFzc3dvcmQnKS5pc0xlbmd0aCh7IG1pbjogNCB9KS5leGlzdHMoKS5jdXN0b20oKHZhbHVlLCB7IHJlcSB9KSA9PiB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gcmVxLmJvZHkuY29uZmlybV9wYXNzd29yZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlBhc3N3b3JkcyBkb24ndCBtYXRjaFwiKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgY2hlY2soJ3N0YXR1cycpLmV4aXN0cygpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci5xdWVyeSgpLndoZXJlKCdpZCcsIGlkKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGVtYWlsLCBwaG9uZV9udW1iZXI6IHBob25lTnVtYmVyIH0gPSByZXEuYm9keTtcblxuICAgICAgY29uc3QgZm91bmRVc2VycyA9IGF3YWl0IFVzZXIucXVlcnkoKVxuICAgICAgICAud2hlcmVOb3QoJ2lkJywgaWQpXG4gICAgICAgIC5hbmRXaGVyZSgocSkgPT4ge1xuICAgICAgICAgIHEud2hlcmUoJ2VtYWlsJywgZW1haWwpO1xuICAgICAgICAgIHEub3JXaGVyZSgncGhvbmVfbnVtYmVyJywgcGhvbmVOdW1iZXIpO1xuICAgICAgICB9KTtcblxuICAgICAgY29uc3QgZm91bmRVc2VyRW1haWwgPSBmb3VuZFVzZXJzLmZpbmQoKHUpID0+IHUuZW1haWwgPT09IGVtYWlsKTtcbiAgICAgIGNvbnN0IGZvdW5kVXNlclBob25lID0gZm91bmRVc2Vycy5maW5kKCh1KSA9PiB1LnBob25lTnVtYmVyID09PSBwaG9uZU51bWJlcik7XG5cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuXG4gICAgICBpZiAoZm91bmRVc2VyRW1haWwpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRU1BSUxfQUxSRUFEWV9FWElTVCcsIGNvZGU6IDEwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChmb3VuZFVzZXJQaG9uZSkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdQSE9ORV9OVU1CRVJfQUxSRUFEWV9FWElTVCcsIGNvZGU6IDEyMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBVc2VyLnF1ZXJ5KCkud2hlcmUoJ2lkJywgaWQpLnVwZGF0ZSh7XG4gICAgICAgIGZpcnN0X25hbWU6IHJlcS5ib2R5LmZpcnN0X25hbWUsXG4gICAgICAgIGxhc3RfbmFtZTogcmVxLmJvZHkubGFzdF9uYW1lLFxuICAgICAgICBlbWFpbDogcmVxLmJvZHkuZW1haWwsXG4gICAgICAgIHBob25lX251bWJlcjogcmVxLmJvZHkucGhvbmVfbnVtYmVyLFxuICAgICAgICBhY3RpdmU6IHJlcS5ib2R5LnN0YXR1cyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogU29mdCBkZWxldGluZyB0aGUgZ2l2ZW4gdXNlci5cbiAgICovXG4gIGRlbGV0ZVVzZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXIucXVlcnkoKS53aGVyZSgnaWQnLCBpZCkuZmlyc3QoKTtcblxuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnVVNFUl9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgVXNlci5xdWVyeSgpLndoZXJlKCdpZCcsIGlkKS5kZWxldGUoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdXNlciBkZXRhaWxzIG9mIHRoZSBnaXZlbiB1c2VyIGlkLlxuICAgKi9cbiAgZ2V0VXNlcjoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXIucXVlcnkoKS53aGVyZSgnaWQnLCBpZCkuZmlyc3QoKTtcblxuICAgICAgaWYgKCF1c2VyKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgdXNlciB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgbGlzdCBvZiB1c2Vycy5cbiAgICovXG4gIGxpc3RVc2Vyczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdwYWdlX3NpemUnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgncGFnZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgZmlyc3RfbmFtZTogJycsXG4gICAgICAgIGxhc3RfbmFtZTogJycsXG4gICAgICAgIGVtYWlsOiAnJyxcbiAgICAgICAgcGhvbmVfbnVtYmVyOiAnJyxcblxuICAgICAgICBwYWdlX3NpemU6IDEwLFxuICAgICAgICBwYWdlOiAxLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBjb25zdCB1c2VycyA9IGF3YWl0IFVzZXIucXVlcnkoKVxuICAgICAgICAucGFnZShmaWx0ZXIucGFnZSAtIDEsIGZpbHRlci5wYWdlX3NpemUpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB1c2VycyB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCB7IGRpZmZlcmVuY2UsIHBpY2sgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQge1xuICBjaGVjayxcbiAgcXVlcnksXG4gIHBhcmFtLFxuICBvbmVPZixcbiAgdmFsaWRhdGlvblJlc3VsdCxcbn0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IGp3dEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IFZpZXcgZnJvbSAnQC9tb2RlbHMvVmlldyc7XG5pbXBvcnQgVmlld1JvbGUgZnJvbSAnQC9tb2RlbHMvVmlld1JvbGUnO1xuaW1wb3J0IFZpZXdDb2x1bW4gZnJvbSAnQC9tb2RlbHMvVmlld0NvbHVtbic7XG5pbXBvcnQge1xuICB2YWxpZGF0ZVZpZXdMb2dpY0V4cHJlc3Npb24sXG59IGZyb20gJ0AvbGliL1ZpZXdSb2xlc0J1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIHJlc291cmNlOiAnaXRlbXMnLFxuXG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHRoaXMubGlzdFZpZXdzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5saXN0Vmlld3MuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy8nLFxuICAgICAgdGhpcy5jcmVhdGVWaWV3LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5jcmVhdGVWaWV3LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOnZpZXdfaWQnLFxuICAgICAgdGhpcy5lZGl0Vmlldy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdFZpZXcuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmRlbGV0ZSgnLzp2aWV3X2lkJyxcbiAgICAgIHRoaXMuZGVsZXRlVmlldy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlVmlldy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvOnZpZXdfaWQnLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0Vmlldy5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBMaXN0IGFsbCB2aWV3cyB0aGF0IGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAqL1xuICBsaXN0Vmlld3M6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBvbmVPZihbXG4gICAgICAgIHF1ZXJ5KCdyZXNvdXJjZV9uYW1lJykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgXSwgW1xuICAgICAgICBxdWVyeSgncmVzb3VyY2VfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgXSksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7IC4uLnJlcS5xdWVyeSB9O1xuXG4gICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KCkub25CdWlsZCgoYnVpbGRlcikgPT4ge1xuICAgICAgICBpZiAoZmlsdGVyLnJlc291cmNlX2lkKSB7XG4gICAgICAgICAgYnVpbGRlci53aGVyZSgnaWQnLCBmaWx0ZXIucmVzb3VyY2VfaWQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXIucmVzb3VyY2VfbmFtZSkge1xuICAgICAgICAgIGJ1aWxkZXIud2hlcmUoJ25hbWUnLCBmaWx0ZXIucmVzb3VyY2VfbmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgYnVpbGRlci5maXJzdCgpO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IHZpZXdzID0gYXdhaXQgVmlldy5xdWVyeSgpLndoZXJlKCdyZXNvdXJjZV9pZCcsIHJlc291cmNlLmlkKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgdmlld3MgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdmlldyBkZXRhaWxzIG9mIHRoZSBnaXZlbiB2aWV3IGlkLlxuICAgKi9cbiAgZ2V0Vmlldzoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCd2aWV3X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgdmlld19pZDogdmlld0lkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdmlldyA9IGF3YWl0IFZpZXcucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ2lkJywgdmlld0lkKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgncmVzb3VyY2UnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnY29sdW1ucycpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCdyb2xlcy5maWVsZCcpXG4gICAgICAgIC5maXJzdCgpO1xuXG4gICAgICBpZiAoIXZpZXcpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdWSUVXX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB2aWV3OiB2aWV3LnRvSlNPTigpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZW4gdmlldyBvZiB0aGUgcmVzb3VyY2UuXG4gICAqL1xuICBkZWxldGVWaWV3OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ3ZpZXdfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyB2aWV3X2lkOiB2aWV3SWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB2aWV3ID0gYXdhaXQgVmlldy5xdWVyeSgpLmZpbmRCeUlkKHZpZXdJZCk7XG5cbiAgICAgIGlmICghdmlldykge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1ZJRVdfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICh2aWV3LnByZWRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1BSRURFRklORURfVklFVycsIGNvZGU6IDIwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIHZpZXcuJHJlbGF0ZWRRdWVyeSgncm9sZXMnKS5kZWxldGUoKSxcbiAgICAgICAgdmlldy4kcmVsYXRlZFF1ZXJ5KCdjb2x1bW5zJykuZGVsZXRlKCksXG4gICAgICBdKTtcbiAgICAgIGF3YWl0IFZpZXcucXVlcnkoKS53aGVyZSgnaWQnLCB2aWV3LmlkKS5kZWxldGUoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHZpZXcuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB2aWV3LlxuICAgKi9cbiAgY3JlYXRlVmlldzoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdyZXNvdXJjZV9uYW1lJykuZXhpc3RzKCkuZXNjYXBlKCkudHJpbSgpLFxuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygnbG9naWNfZXhwcmVzc2lvbicpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdyb2xlcycpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgICBjaGVjaygncm9sZXMuKi5maWVsZF9rZXknKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygncm9sZXMuKi5jb21wYXJhdG9yJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygncm9sZXMuKi52YWx1ZScpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ3JvbGVzLiouaW5kZXgnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2NvbHVtbnMnKS5leGlzdHMoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2NvbHVtbnMuKi5rZXknKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygnY29sdW1ucy4qLmluZGV4JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpLndoZXJlKCduYW1lJywgZm9ybS5yZXNvdXJjZV9uYW1lKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXJlc291cmNlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUkVTT1VSQ0VfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3QgZmllbGRzU2x1Z3MgPSBmb3JtLnJvbGVzLm1hcCgocm9sZSkgPT4gcm9sZS5maWVsZF9rZXkpO1xuXG4gICAgICBjb25zdCByZXNvdXJjZUZpZWxkcyA9IGF3YWl0IHJlc291cmNlLiRyZWxhdGVkUXVlcnkoJ2ZpZWxkcycpO1xuICAgICAgY29uc3QgcmVzb3VyY2VGaWVsZHNLZXlzID0gcmVzb3VyY2VGaWVsZHMubWFwKChmKSA9PiBmLmtleSk7XG4gICAgICBjb25zdCByZXNvdXJjZUZpZWxkc0tleXNNYXAgPSBuZXcgTWFwKHJlc291cmNlRmllbGRzLm1hcCgoZmllbGQpID0+IFtmaWVsZC5rZXksIGZpZWxkXSkpO1xuICAgICAgY29uc3QgY29sdW1uc0tleXMgPSBmb3JtLmNvbHVtbnMubWFwKChjKSA9PiBjLmtleSk7XG5cbiAgICAgIC8vIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHN0b3JlZCByZXNvdXJjZSBmaWVsZHMgYW5kIHN1Ym1pdCBmaWVsZHMga2V5cy5cbiAgICAgIGNvbnN0IG5vdEZvdW5kRmllbGRzID0gZGlmZmVyZW5jZShmaWVsZHNTbHVncywgcmVzb3VyY2VGaWVsZHNLZXlzKTtcblxuICAgICAgaWYgKG5vdEZvdW5kRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnUkVTT1VSQ0VfRklFTERTX05PVF9FWElTVCcsIGNvZGU6IDEwMCwgZmllbGRzOiBub3RGb3VuZEZpZWxkcyB9KTtcbiAgICAgIH1cbiAgICAgIC8vIFRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHN0b3JlZCByZXNvdXJjZSBmaWVsZHMgYW5kIHRoZSBzdWJtaXQgY29sdW1ucyBrZXlzLlxuICAgICAgY29uc3Qgbm90Rm91bmRDb2x1bW5zID0gZGlmZmVyZW5jZShjb2x1bW5zS2V5cywgcmVzb3VyY2VGaWVsZHNLZXlzKTtcblxuICAgICAgaWYgKG5vdEZvdW5kQ29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0NPTFVNTlNfTk9UX0VYSVNUJywgY29kZTogMjAwLCBjb2x1bW5zOiBub3RGb3VuZENvbHVtbnMgfSk7XG4gICAgICB9XG4gICAgICAvLyBWYWxpZGF0ZXMgdGhlIHZpZXcgY29uZGl0aW9uYWwgbG9naWMgZXhwcmVzc2lvbi5cbiAgICAgIGlmICghdmFsaWRhdGVWaWV3TG9naWNFeHByZXNzaW9uKGZvcm0ubG9naWNfZXhwcmVzc2lvbiwgZm9ybS5yb2xlcy5tYXAoKHIpID0+IHIuaW5kZXgpKSkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdWSUVXLlJPTEVTLkxPR0lDLkVYUFJFU1NJT04uSU5WQUxJRCcsIGNvZGU6IDQwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICAvLyBTYXZlIHZpZXcgZGV0YWlscy5cbiAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBWaWV3LnF1ZXJ5KCkuaW5zZXJ0KHtcbiAgICAgICAgbmFtZTogZm9ybS5uYW1lLFxuICAgICAgICBwcmVkZWZpbmVkOiBmYWxzZSxcbiAgICAgICAgcmVzb3VyY2VfaWQ6IHJlc291cmNlLmlkLFxuICAgICAgICByb2xlc19sb2dpY19leHByZXNzaW9uOiBmb3JtLmxvZ2ljX2V4cHJlc3Npb24sXG4gICAgICB9KTtcbiAgICAgIC8vIFNhdmUgdmlldyByb2xlcyBhc3luYyBvcGVyYXRpb25zLlxuICAgICAgY29uc3Qgc2F2ZVZpZXdSb2xlc09wZXJzID0gW107XG5cbiAgICAgIGZvcm0ucm9sZXMuZm9yRWFjaCgocm9sZSkgPT4ge1xuICAgICAgICBjb25zdCBmaWVsZE1vZGVsID0gcmVzb3VyY2VGaWVsZHNLZXlzTWFwLmdldChyb2xlLmZpZWxkX2tleSk7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBzYXZlVmlld1JvbGVPcGVyID0gVmlld1JvbGUucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAgIC4uLnBpY2socm9sZSwgWydjb21wYXJhdG9yJywgJ3ZhbHVlJywgJ2luZGV4J10pLFxuICAgICAgICAgIGZpZWxkX2lkOiBmaWVsZE1vZGVsLmlkLFxuICAgICAgICAgIHZpZXdfaWQ6IHZpZXcuaWQsXG4gICAgICAgIH0pO1xuICAgICAgICBzYXZlVmlld1JvbGVzT3BlcnMucHVzaChzYXZlVmlld1JvbGVPcGVyKTtcbiAgICAgIH0pO1xuXG4gICAgICBmb3JtLmNvbHVtbnMuZm9yRWFjaCgoY29sdW1uKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkTW9kZWwgPSByZXNvdXJjZUZpZWxkc0tleXNNYXAuZ2V0KGNvbHVtbi5rZXkpO1xuXG4gICAgICAgIGNvbnN0IHNhdmVWaWV3Q29sdW1uT3BlciA9IFZpZXdDb2x1bW4ucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAgIGZpZWxkX2lkOiBmaWVsZE1vZGVsLmlkLFxuICAgICAgICAgIHZpZXdfaWQ6IHZpZXcuaWQsXG4gICAgICAgICAgaW5kZXg6IGNvbHVtbi5pbmRleCxcbiAgICAgICAgfSk7XG4gICAgICAgIHNhdmVWaWV3Um9sZXNPcGVycy5wdXNoKHNhdmVWaWV3Q29sdW1uT3Blcik7XG4gICAgICB9KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHNhdmVWaWV3Um9sZXNPcGVycyk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiB2aWV3LmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgZWRpdFZpZXc6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgndmlld19pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnbGFiZWwnKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygnY29sdW1ucycpLmlzQXJyYXkoeyBtaW46IDMgfSksXG4gICAgICBjaGVjaygncm9sZXMnKS5pc0FycmF5KCksXG4gICAgICBjaGVjaygncm9sZXMuKi5maWVsZCcpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLmNvbXBhcmF0b3InKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLnZhbHVlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygncm9sZXMuKi5pbmRleCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IHZpZXdfaWQ6IHZpZXdJZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB2aWV3ID0gYXdhaXQgVmlldy53aGVyZSgnaWQnLCB2aWV3SWQpLmZldGNoKCk7XG5cbiAgICAgIGlmICghdmlldykge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1JPTEVfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiLy8gaW1wb3J0IE9BdXRoMiBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvT0F1dGgyJztcbmltcG9ydCBBdXRoZW50aWNhdGlvbiBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQXV0aGVudGljYXRpb24nO1xuaW1wb3J0IFVzZXJzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9Vc2Vycyc7XG5pbXBvcnQgUm9sZXMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1JvbGVzJztcbmltcG9ydCBJdGVtcyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvSXRlbXMnO1xuaW1wb3J0IEl0ZW1DYXRlZ29yaWVzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9JdGVtQ2F0ZWdvcmllcyc7XG5pbXBvcnQgQWNjb3VudHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRzJztcbmltcG9ydCBBY2NvdW50VHlwZXMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRUeXBlcyc7XG5pbXBvcnQgQWNjb3VudE9wZW5pbmdCYWxhbmNlIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9BY2NvdW50T3BlbmluZ0JhbGFuY2UnO1xuaW1wb3J0IFZpZXdzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9WaWV3cyc7XG5pbXBvcnQgQ3VzdG9tRmllbGRzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9GaWVsZHMnO1xuaW1wb3J0IEFjY291bnRpbmcgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRpbmcnO1xuaW1wb3J0IEZpbmFuY2lhbFN0YXRlbWVudHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0ZpbmFuY2lhbFN0YXRlbWVudHMnO1xuaW1wb3J0IEV4cGVuc2VzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9FeHBlbnNlcyc7XG5pbXBvcnQgT3B0aW9ucyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvT3B0aW9ucyc7XG5pbXBvcnQgQnVkZ2V0IGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9CdWRnZXQnO1xuaW1wb3J0IEJ1ZGdldFJlcG9ydHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0J1ZGdldFJlcG9ydHMnO1xuaW1wb3J0IEN1cnJlbmNpZXMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0N1cnJlbmNpZXMnO1xuaW1wb3J0IEN1c3RvbWVycyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQ3VzdG9tZXJzJztcbmltcG9ydCBTdXBwbGllcnMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1N1cHBsaWVycyc7XG5pbXBvcnQgQmlsbHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0JpbGxzJztcbmltcG9ydCBDdXJyZW5jeUFkanVzdG1lbnQgZnJvbSAnLi9jb250cm9sbGVycy9DdXJyZW5jeUFkanVzdG1lbnQnO1xuaW1wb3J0IFJlc291cmNlcyBmcm9tICcuL2NvbnRyb2xsZXJzL1Jlc291cmNlcyc7XG4vLyBpbXBvcnQgU2FsZXNSZXBvcnRzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9TYWxlc1JlcG9ydHMnO1xuLy8gaW1wb3J0IFB1cmNoYXNlc1JlcG9ydHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1B1cmNoYXNlc1JlcG9ydHMnO1xuXG5leHBvcnQgZGVmYXVsdCAoYXBwKSA9PiB7XG4gIC8vIGFwcC51c2UoJy9hcGkvb2F1dGgyJywgT0F1dGgyLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9hdXRoJywgQXV0aGVudGljYXRpb24ucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2N1cnJlbmNpZXMnLCBDdXJyZW5jaWVzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS91c2VycycsIFVzZXJzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9yb2xlcycsIFJvbGVzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9hY2NvdW50cycsIEFjY291bnRzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9hY2NvdW50X3R5cGVzJywgQWNjb3VudFR5cGVzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9hY2NvdW50aW5nJywgQWNjb3VudGluZy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvYWNjb3VudHNfb3BlbmluZ19iYWxhbmNlcycsIEFjY291bnRPcGVuaW5nQmFsYW5jZS5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvdmlld3MnLCBWaWV3cy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvZmllbGRzJywgQ3VzdG9tRmllbGRzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9pdGVtcycsIEl0ZW1zLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9pdGVtX2NhdGVnb3JpZXMnLCBJdGVtQ2F0ZWdvcmllcy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvZXhwZW5zZXMnLCBFeHBlbnNlcy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvZmluYW5jaWFsX3N0YXRlbWVudHMnLCBGaW5hbmNpYWxTdGF0ZW1lbnRzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9vcHRpb25zJywgT3B0aW9ucy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvYnVkZ2V0X3JlcG9ydHMnLCBCdWRnZXRSZXBvcnRzLnJvdXRlcigpKTtcbiAgLy8gYXBwLnVzZSgnL2FwaS9jdXN0b21lcnMnLCBDdXN0b21lcnMucm91dGVyKCkpO1xuICAvLyBhcHAudXNlKCcvYXBpL3N1cHBsaWVycycsIFN1cHBsaWVycy5yb3V0ZXIoKSk7XG4gIC8vIGFwcC51c2UoJy9hcGkvYmlsbHMnLCBCaWxscy5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvYnVkZ2V0JywgQnVkZ2V0LnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9yZXNvdXJjZXMnLCBSZXNvdXJjZXMucm91dGVyKCkpO1xuICAvLyBhcHAudXNlKCcvYXBpL2N1cnJlbmN5X2FkanVzdG1lbnQnLCBDdXJyZW5jeUFkanVzdG1lbnQucm91dGVyKCkpO1xuICAvLyBhcHAudXNlKCcvYXBpL3JlcG9ydHMvc2FsZXMnLCBTYWxlc1JlcG9ydHMucm91dGVyKCkpO1xuICAvLyBhcHAudXNlKCcvYXBpL3JlcG9ydHMvcHVyY2hhc2VzJywgUHVyY2hhc2VzUmVwb3J0cy5yb3V0ZXIoKSk7XG59O1xuIiwiY29uc3QgYXN5bmNNaWRkbGV3YXJlID0gKGZuKSA9PiAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgUHJvbWlzZS5yZXNvbHZlKGZuKHJlcSwgcmVzLCBuZXh0KSlcbiAgICAuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICBuZXh0KGVycm9yKTtcbiAgICB9KTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGFzeW5jTWlkZGxld2FyZTtcbiIsIi8qIGVzbGludC1kaXNhYmxlIGNvbnNpc3RlbnQtcmV0dXJuICovXG5jb25zdCBhdXRob3JpemF0aW9uID0gKHJlc291cmNlTmFtZSkgPT4gKC4uLnBlcm1pc3Npb25zKSA9PiAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgY29uc3QgeyB1c2VyIH0gPSByZXE7XG4gIGNvbnN0IG9uRXJyb3IgPSAoKSA9PiB7XG4gICAgcmVzLmJvb20udW5hdXRob3JpemVkKCk7XG4gIH07XG4gIHVzZXIuaGFzUGVybWlzc2lvbnMocmVzb3VyY2VOYW1lLCBwZXJtaXNzaW9ucylcbiAgICAudGhlbigoYXV0aG9yaXplZCkgPT4ge1xuICAgICAgaWYgKCFhdXRob3JpemVkKSB7XG4gICAgICAgIHJldHVybiBvbkVycm9yKCk7XG4gICAgICB9XG4gICAgICBuZXh0KCk7XG4gICAgfSkuY2F0Y2gob25FcnJvcik7XG59O1xuXG5leHBvcnQgZGVmYXVsdCBhdXRob3JpemF0aW9uO1xuIiwiLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCBVc2VyIGZyb20gJ0AvbW9kZWxzL1VzZXInO1xuLy8gaW1wb3J0IEF1dGggZnJvbSAnQC9tb2RlbHMvQXV0aCc7XG5cbmNvbnN0IGF1dGhNaWRkbGV3YXJlID0gKHJlcSwgcmVzLCBuZXh0KSA9PiB7XG4gIGNvbnN0IHsgSldUX1NFQ1JFVF9LRVkgfSA9IHByb2Nlc3MuZW52O1xuICBjb25zdCB0b2tlbiA9IHJlcS5oZWFkZXJzWyd4LWFjY2Vzcy10b2tlbiddIHx8IHJlcS5xdWVyeS50b2tlbjtcblxuICBjb25zdCBvbkVycm9yID0gKCkgPT4ge1xuICAgIC8vIEF1dGgubG9nZ2VkT3V0KCk7XG4gICAgcmVzLnN0YXR1cyg0MDEpLnNlbmQoe1xuICAgICAgc3VjY2VzczogZmFsc2UsXG4gICAgICBtZXNzYWdlOiAndW5hdXRob3JpemVkJyxcbiAgICB9KTtcbiAgfTtcblxuICBpZiAoIXRva2VuKSB7XG4gICAgcmV0dXJuIG9uRXJyb3IoKTtcbiAgfVxuXG4gIGNvbnN0IHZlcmlmeSA9IG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICBqd3QudmVyaWZ5KHRva2VuLCBKV1RfU0VDUkVUX0tFWSwgYXN5bmMgKGVycm9yLCBkZWNvZGVkKSA9PiB7XG4gICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuICAgICAgICByZXEudXNlciA9IGF3YWl0IFVzZXIucXVlcnkoKS5maW5kQnlJZChkZWNvZGVkLl9pZCk7XG4gICAgICAgIC8vIEF1dGguc2V0QXV0aGVudGljYXRlZFVzZXIocmVxLnVzZXIpO1xuXG4gICAgICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgICAgICByZXR1cm4gb25FcnJvcigpO1xuICAgICAgICB9XG4gICAgICAgIHJlc29sdmUoZGVjb2RlZCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuXG4gIHZlcmlmeS50aGVuKCgpID0+IHsgbmV4dCgpOyB9KS5jYXRjaChvbkVycm9yKTtcbn07XG5leHBvcnQgZGVmYXVsdCBhdXRoTWlkZGxld2FyZTtcbiIsIlxuY29uc3QgT3BlcmF0aW9uVHlwZSA9IHtcbiAgTE9HSUM6ICdMT0dJQycsXG4gIFNUUklORzogJ1NUUklORycsXG4gIENPTVBBUklTT046ICdDT01QQVJJU09OJyxcbiAgTUFUSDogJ01BVEgnLFxufTtcblxuZXhwb3J0IGNsYXNzIExleGVyIHtcbiAgLy8gb3BlcmF0aW9uIHRhYmxlXG4gIHN0YXRpYyBnZXQgb3B0YWJsZSgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgJz0nOiBPcGVyYXRpb25UeXBlLkxPR0lDLFxuICAgICAgJyYnOiBPcGVyYXRpb25UeXBlLkxPR0lDLFxuICAgICAgJ3wnOiBPcGVyYXRpb25UeXBlLkxPR0lDLFxuICAgICAgJz8nOiBPcGVyYXRpb25UeXBlLkxPR0lDLFxuICAgICAgJzonOiBPcGVyYXRpb25UeXBlLkxPR0lDLFxuXG4gICAgICAnXFwnJzogT3BlcmF0aW9uVHlwZS5TVFJJTkcsXG4gICAgICAnXCInOiBPcGVyYXRpb25UeXBlLlNUUklORyxcblxuICAgICAgJyEnOiBPcGVyYXRpb25UeXBlLkNPTVBBUklTT04sXG4gICAgICAnPic6IE9wZXJhdGlvblR5cGUuQ09NUEFSSVNPTixcbiAgICAgICc8JzogT3BlcmF0aW9uVHlwZS5DT01QQVJJU09OLFxuXG4gICAgICAnKCc6IE9wZXJhdGlvblR5cGUuTUFUSCxcbiAgICAgICcpJzogT3BlcmF0aW9uVHlwZS5NQVRILFxuICAgICAgJysnOiBPcGVyYXRpb25UeXBlLk1BVEgsXG4gICAgICAnLSc6IE9wZXJhdGlvblR5cGUuTUFUSCxcbiAgICAgICcqJzogT3BlcmF0aW9uVHlwZS5NQVRILFxuICAgICAgJy8nOiBPcGVyYXRpb25UeXBlLk1BVEgsXG4gICAgICAnJSc6IE9wZXJhdGlvblR5cGUuTUFUSCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7Kn0gZXhwcmVzc2lvbiAtXG4gICAqL1xuICBjb25zdHJ1Y3RvcihleHByZXNzaW9uKSB7XG4gICAgdGhpcy5jdXJyZW50SW5kZXggPSAwO1xuICAgIHRoaXMuaW5wdXQgPSBleHByZXNzaW9uO1xuICAgIHRoaXMudG9rZW5MaXN0ID0gW107XG4gIH1cblxuICBnZXRUb2tlbnMoKSB7XG4gICAgbGV0IHRvaztcbiAgICBkbyB7XG4gICAgICAvLyByZWFkIGN1cnJlbnQgdG9rZW4sIHNvIHN0ZXAgc2hvdWxkIGJlIC0xXG4gICAgICB0b2sgPSB0aGlzLnBpY2tOZXh0KC0xKTtcbiAgICAgIGNvbnN0IHBvcyA9IHRoaXMuY3VycmVudEluZGV4O1xuICAgICAgc3dpdGNoIChMZXhlci5vcHRhYmxlW3Rva10pIHtcbiAgICAgICAgY2FzZSBPcGVyYXRpb25UeXBlLkxPR0lDOlxuICAgICAgICAgIC8vID09ICYmIHx8ID09PVxuICAgICAgICAgIHRoaXMucmVhZExvZ2ljT3B0KHRvayk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPcGVyYXRpb25UeXBlLlNUUklORzpcbiAgICAgICAgICB0aGlzLnJlYWRTdHJpbmcodG9rKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9wZXJhdGlvblR5cGUuQ09NUEFSSVNPTjpcbiAgICAgICAgICB0aGlzLnJlYWRDb21wYXJlKHRvayk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPcGVyYXRpb25UeXBlLk1BVEg6XG4gICAgICAgICAgdGhpcy5yZWNlaXZlVG9rZW4oKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRoaXMucmVhZFZhbHVlKHRvayk7XG4gICAgICB9XG5cbiAgICAgIC8vIGlmIHRoZSBwb3Mgbm90IGNoYW5nZWQsIHRoaXMgbG9vcCB3aWxsIGdvIGludG8gYSBpbmZpbml0ZSBsb29wLCBldmVyeSBzdGVwIG9mIHdoaWxlIGxvb3AsXG4gICAgICAvLyB3ZSBtdXN0IG1vdmUgdGhlIHBvcyBmb3J3YXJkXG4gICAgICAvLyBzbyBoZXJlIHdlIHNob3VsZCB0aHJvdyBlcnJvciwgZm9yIGV4YW1wbGUgYDEgJiAyYFxuICAgICAgaWYgKHBvcyA9PT0gdGhpcy5jdXJyZW50SW5kZXggJiYgdG9rICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY29uc3QgZXJyID0gbmV3IEVycm9yKGB1bmtvbncgdG9rZW4gJHt0b2t9IGZyb20gaW5wdXQgc3RyaW5nICR7dGhpcy5pbnB1dH1gKTtcbiAgICAgICAgZXJyLm5hbWUgPSAnVW5rbm93VG9rZW4nO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG4gICAgfSB3aGlsZSAodG9rICE9PSB1bmRlZmluZWQpXG5cbiAgICByZXR1cm4gdGhpcy50b2tlbkxpc3Q7XG4gIH1cblxuICAvKipcbiAgICogcmVhZCBuZXh0IHRva2VuLCB0aGUgaW5kZXggcGFyYW0gY2FuIHNldCBuZXh0IHN0ZXAsIGRlZmF1bHQgZ28gZm93YXJkIDEgc3RlcFxuICAgKlxuICAgKiBAcGFyYW0gaW5kZXggbmV4dCBwb3N0aW9uXG4gICAqL1xuICBwaWNrTmV4dChpbmRleCA9IDApIHtcbiAgICByZXR1cm4gdGhpcy5pbnB1dFtpbmRleCArIHRoaXMuY3VycmVudEluZGV4ICsgMV07XG4gIH1cblxuICAvKipcbiAgICogU3RvcmUgdG9rZW4gaW50byByZXN1bHQgdG9rZW5MaXN0LCBhbmQgbW92ZSB0aGUgcG9zIGluZGV4XG4gICAqXG4gICAqIEBwYXJhbSBpbmRleFxuICAgKi9cbiAgcmVjZWl2ZVRva2VuKGluZGV4ID0gMSkge1xuICAgIGNvbnN0IHRvayA9IHRoaXMuaW5wdXQuc2xpY2UodGhpcy5jdXJyZW50SW5kZXgsIHRoaXMuY3VycmVudEluZGV4ICsgaW5kZXgpLnRyaW0oKTtcbiAgICAvLyBza2lwIGVtcHR5IHN0cmluZ1xuICAgIGlmICh0b2spIHtcbiAgICAgIHRoaXMudG9rZW5MaXN0LnB1c2godG9rKTtcbiAgICB9XG5cbiAgICB0aGlzLmN1cnJlbnRJbmRleCArPSBpbmRleDtcbiAgfVxuXG4gIC8vICcgb3IgXCJcbiAgcmVhZFN0cmluZyh0b2spIHtcbiAgICBsZXQgbmV4dDtcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGRvIHtcbiAgICAgIG5leHQgPSB0aGlzLnBpY2tOZXh0KGluZGV4KTtcbiAgICAgIGluZGV4ICs9IDE7XG4gICAgfSB3aGlsZSAobmV4dCAhPT0gdG9rICYmIG5leHQgIT09IHVuZGVmaW5lZCk7XG4gICAgdGhpcy5yZWNlaXZlVG9rZW4oaW5kZXggKyAxKTtcbiAgfVxuXG4gIC8vID4gb3IgPCBvciA+PSBvciA8PSBvciAhPT1cbiAgLy8gdG9rIGluICg+LCA8LCAhKVxuICByZWFkQ29tcGFyZSh0b2spIHtcbiAgICBpZiAodGhpcy5waWNrTmV4dCgpICE9PSAnPScpIHtcbiAgICAgIHRoaXMucmVjZWl2ZVRva2VuKDEpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyAhPT1cbiAgICBpZiAodG9rID09PSAnIScgJiYgdGhpcy5waWNrTmV4dCgxKSA9PT0gJz0nKSB7XG4gICAgICB0aGlzLnJlY2VpdmVUb2tlbigzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZWNlaXZlVG9rZW4oMik7XG4gIH1cblxuICAvLyA9PT0gb3IgPT1cbiAgLy8gJiYgfHxcbiAgcmVhZExvZ2ljT3B0KHRvaykge1xuICAgIGlmICh0aGlzLnBpY2tOZXh0KCkgPT09IHRvaykge1xuICAgICAgLy8gPT09XG4gICAgICBpZiAodG9rID09PSAnPScgJiYgdGhpcy5waWNrTmV4dCgxKSA9PT0gdG9rKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlY2VpdmVUb2tlbigzKTtcbiAgICAgIH1cbiAgICAgIC8vID09ICYmIHx8XG4gICAgICByZXR1cm4gdGhpcy5yZWNlaXZlVG9rZW4oMik7XG4gICAgfVxuICAgIC8vIGhhbmRsZSBhcyAmJlxuICAgIC8vIGEgPyBiIDogYyBpcyBlcXVhbCB0byBhICYmIGIgfHwgY1xuICAgIGlmICh0b2sgPT09ICc/JyB8fCB0b2sgPT09ICc6Jykge1xuICAgICAgcmV0dXJuIHRoaXMucmVjZWl2ZVRva2VuKDEpO1xuICAgIH1cbiAgfVxuXG4gIHJlYWRWYWx1ZSh0b2spIHtcbiAgICBpZiAoIXRvaykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBpbmRleCA9IDA7XG4gICAgd2hpbGUgKCFMZXhlci5vcHRhYmxlW3Rva10gJiYgdG9rICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRvayA9IHRoaXMucGlja05leHQoaW5kZXgpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICB9XG4gICAgdGhpcy5yZWNlaXZlVG9rZW4oaW5kZXgpO1xuICB9XG59XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRva2VuKGV4cHJlc3Npb24pIHtcbiAgY29uc3QgbGV4ZXIgPSBuZXcgTGV4ZXIoZXhwcmVzc2lvbik7XG4gIHJldHVybiBsZXhlci5nZXRUb2tlbnMoKTtcbn1cbiIsImV4cG9ydCBjb25zdCBPUEVSQVRJT04gPSB7XG4gICchJzogNSxcbiAgJyonOiA0LFxuICAnLyc6IDQsXG4gICclJzogNCxcbiAgJysnOiAzLFxuICAnLSc6IDMsXG4gICc+JzogMixcbiAgJzwnOiAyLFxuICAnPj0nOiAyLFxuICAnPD0nOiAyLFxuICAnPT09JzogMixcbiAgJyE9PSc6IDIsXG4gICc9PSc6IDIsXG4gICchPSc6IDIsXG4gICcmJic6IDEsXG4gICd8fCc6IDEsXG4gICc/JzogMSxcbiAgJzonOiAxLFxufTtcblxuLy8gZXhwb3J0IGludGVyZmFjZSBOb2RlIHtcbi8vICAgbGVmdDogTm9kZSB8IHN0cmluZyB8IG51bGw7XG4vLyAgIHJpZ2h0OiBOb2RlIHwgc3RyaW5nIHwgbnVsbDtcbi8vICAgb3BlcmF0aW9uOiBzdHJpbmc7XG4vLyAgIGdyb3VwZWQ/OiBib29sZWFuO1xuLy8gfTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFyc2VyIHtcblxuICBjb25zdHJ1Y3Rvcih0b2tlbikge1xuICAgIHRoaXMuaW5kZXggPSAtMTtcbiAgICB0aGlzLmJsb2NrTGV2ZWwgPSAwO1xuICAgIHRoaXMudG9rZW4gPSB0b2tlbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBcbiAgICogQHJldHVybiB7Tm9kZSB8IHN0cmluZ30gPS0gXG4gICAqL1xuICBwYXJzZSgpIHtcbiAgICBsZXQgdG9rO1xuICAgIGxldCByb290ID0ge1xuICAgICAgbGVmdDogbnVsbCxcbiAgICAgIHJpZ2h0OiBudWxsLFxuICAgICAgb3BlcmF0aW9uOiBudWxsLFxuICAgIH07XG5cbiAgICBkbyB7XG4gICAgICB0b2sgPSB0aGlzLnBhcnNlU3RhdGVtZW50KCk7XG5cbiAgICAgIGlmICh0b2sgPT09IG51bGwgfHwgdG9rID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChyb290LmxlZnQgPT09IG51bGwpIHtcbiAgICAgICAgcm9vdC5sZWZ0ID0gdG9rO1xuICAgICAgICByb290Lm9wZXJhdGlvbiA9IHRoaXMubmV4dFRva2VuKCk7XG5cbiAgICAgICAgaWYgKCFyb290Lm9wZXJhdGlvbikge1xuICAgICAgICAgIHJldHVybiB0b2s7XG4gICAgICAgIH1cblxuICAgICAgICByb290LnJpZ2h0ID0gdGhpcy5wYXJzZVN0YXRlbWVudCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHR5cGVvZiB0b2sgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdvcGVyYXRpb24gbXVzdCBiZSBzdHJpbmcsIGJ1dCBnZXQgJyArIEpTT04uc3RyaW5naWZ5KHRvaykpO1xuICAgICAgICB9XG4gICAgICAgIHJvb3QgPSB0aGlzLmFkZE5vZGUodG9rLCB0aGlzLnBhcnNlU3RhdGVtZW50KCksIHJvb3QpO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKHRvayk7XG5cbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIG5leHRUb2tlbigpIHtcbiAgICB0aGlzLmluZGV4ICs9IDE7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5bdGhpcy5pbmRleF07XG4gIH1cblxuICBwcmV2VG9rZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5bdGhpcy5pbmRleCAtIDFdO1xuICB9XG5cbiAgLyoqXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIFxuICAgKiBAcGFyYW0ge05vZGV8U3RyaW5nfG51bGx9IHJpZ2h0IFxuICAgKiBAcGFyYW0ge05vZGV9IHJvb3QgXG4gICAqL1xuICBhZGROb2RlKG9wZXJhdGlvbiwgcmlnaHQsIHJvb3QpIHtcbiAgICBsZXQgcHJlID0gcm9vdDtcbiAgICBcbiAgICBpZiAodGhpcy5jb21wYXJlKHByZS5vcGVyYXRpb24sIG9wZXJhdGlvbikgPCAwICYmICFwcmUuZ3JvdXBlZCkge1xuICAgICAgXG4gICAgICB3aGlsZSAocHJlLnJpZ2h0ICE9PSBudWxsICYmXG4gICAgICAgIHR5cGVvZiBwcmUucmlnaHQgIT09ICdzdHJpbmcnICYmXG4gICAgICAgIHRoaXMuY29tcGFyZShwcmUucmlnaHQub3BlcmF0aW9uLCBvcGVyYXRpb24pIDwgMCAmJiAhcHJlLnJpZ2h0Lmdyb3VwZWQpIHtcbiAgICAgICAgcHJlID0gcHJlLnJpZ2h0O1xuICAgICAgfVxuXG4gICAgICBwcmUucmlnaHQgPSB7XG4gICAgICAgIG9wZXJhdGlvbixcbiAgICAgICAgbGVmdDogcHJlLnJpZ2h0LFxuICAgICAgICByaWdodCxcbiAgICAgIH07XG4gICAgICByZXR1cm4gcm9vdDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGxlZnQ6IHByZSxcbiAgICAgIHJpZ2h0LFxuICAgICAgb3BlcmF0aW9uLFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGEgXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBiIFxuICAgKi9cbiAgY29tcGFyZShhLCBiKSB7XG4gICAgaWYgKCFPUEVSQVRJT04uaGFzT3duUHJvcGVydHkoYSkgfHwgIU9QRVJBVElPTi5oYXNPd25Qcm9wZXJ0eShiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3cgb3BlcmF0aW9uICR7YX0gb3IgJHtifWApO1xuICAgIH1cbiAgICByZXR1cm4gT1BFUkFUSU9OW2FdIC0gT1BFUkFUSU9OW2JdO1xuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm4gc3RyaW5nIHwgTm9kZSB8IG51bGxcbiAgICovXG4gIHBhcnNlU3RhdGVtZW50KCkge1xuICAgIGNvbnN0IHRva2VuID0gdGhpcy5uZXh0VG9rZW4oKTtcbiAgICBpZiAodG9rZW4gPT09ICcoJykge1xuICAgICAgdGhpcy5ibG9ja0xldmVsICs9IDE7XG4gICAgICBjb25zdCBub2RlID0gdGhpcy5wYXJzZSgpO1xuICAgICAgdGhpcy5ibG9ja0xldmVsIC09IDE7XG5cbiAgICAgIGlmICh0eXBlb2Ygbm9kZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgbm9kZS5ncm91cGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBub2RlO1xuICAgIH1cblxuICAgIGlmICh0b2tlbiA9PT0gJyknKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAodG9rZW4gPT09ICchJykge1xuICAgICAgcmV0dXJuIHsgbGVmdDogbnVsbCwgb3BlcmF0aW9uOiB0b2tlbiwgcmlnaHQ6IHRoaXMucGFyc2VTdGF0ZW1lbnQoKSB9XG4gICAgfVxuXG4gICAgLy8gMyA+IC0xMiBvciAtMTIgKyAxMFxuICAgIGlmICh0b2tlbiA9PT0gJy0nICYmIChPUEVSQVRJT05bdGhpcy5wcmV2VG9rZW4oKV0gPiAwIHx8IHRoaXMucHJldlRva2VuKCkgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgIHJldHVybiB7IGxlZnQ6ICcwJywgb3BlcmF0aW9uOiB0b2tlbiwgcmlnaHQ6IHRoaXMucGFyc2VTdGF0ZW1lbnQoKSwgZ3JvdXBlZDogdHJ1ZSB9O1xuICAgIH1cblxuICAgIHJldHVybiB0b2tlbjtcbiAgfVxufVxuIiwiaW1wb3J0IHsgT1BFUkFUSU9OIH0gZnJvbSAnLi9QYXJzZXInO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBRdWVyeVBhcnNlciB7XG5cbiAgY29uc3RydWN0b3IodHJlZSwgcXVlcmllcykge1xuICAgIHRoaXMudHJlZSA9IHRyZWU7XG4gICAgdGhpcy5xdWVyaWVzID0gcXVlcmllcztcbiAgICB0aGlzLnF1ZXJ5ID0gbnVsbDtcbiAgfVxuXG4gIHNldFF1ZXJ5KHF1ZXJ5KSB7XG4gICAgdGhpcy5xdWVyeSA9IHF1ZXJ5LmNsb25lKCk7XG4gIH1cblxuICBwYXJzZSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJzZU5vZGUodGhpcy50cmVlKTtcbiAgfVxuXG4gIHBhcnNlTm9kZShub2RlKSB7XG4gICAgaWYgKHR5cGVvZiBub2RlID09PSAnc3RyaW5nJykge1xuICAgICAgY29uc3Qgbm9kZVF1ZXJ5ID0gdGhpcy5nZXRRdWVyeShub2RlKTtcbiAgICAgIHJldHVybiAocXVlcnkpID0+IHsgbm9kZVF1ZXJ5KHF1ZXJ5KTsgfTtcbiAgICB9XG4gICAgaWYgKE9QRVJBVElPTltub2RlLm9wZXJhdGlvbl0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGB1bmtub3cgZXhwcmVzc2lvbiAke25vZGUub3BlcmF0aW9ufWApO1xuICAgIH1cbiAgICBjb25zdCBsZWZ0UXVlcnkgPSB0aGlzLmdldFF1ZXJ5KG5vZGUubGVmdCk7XG4gICAgY29uc3QgcmlnaHRRdWVyeSA9IHRoaXMuZ2V0UXVlcnkobm9kZS5yaWdodCk7XG5cbiAgICBzd2l0Y2ggKG5vZGUub3BlcmF0aW9uKSB7XG4gICAgICBjYXNlICcmJic6XG4gICAgICBjYXNlICdBTkQnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIChub2RlUXVlcnkpID0+IG5vZGVRdWVyeS53aGVyZSgocXVlcnkpID0+IHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgocSkgPT4geyBsZWZ0UXVlcnkocSk7IH0pO1xuICAgICAgICAgIHF1ZXJ5LmFuZFdoZXJlKChxKSA9PiB7IHJpZ2h0UXVlcnkocSk7IH0pO1xuICAgICAgICB9KTtcbiAgICAgIGNhc2UgJ3x8JzpcbiAgICAgIGNhc2UgJ09SJzpcbiAgICAgICAgcmV0dXJuIChub2RlUXVlcnkpID0+IG5vZGVRdWVyeS53aGVyZSgocXVlcnkpID0+IHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgocSkgPT4geyBsZWZ0UXVlcnkocSk7IH0pO1xuICAgICAgICAgIHF1ZXJ5Lm9yV2hlcmUoKHEpID0+IHsgcmlnaHRRdWVyeShxKTsgfSk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGdldFF1ZXJ5KG5vZGUpIHtcbiAgICBpZiAodHlwZW9mIG5vZGUgIT09ICdzdHJpbmcnICYmIG5vZGUgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiB0aGlzLnBhcnNlTm9kZShub2RlKTtcbiAgICB9XG4gICAgY29uc3QgdmFsdWUgPSBwYXJzZUZsb2F0KG5vZGUpO1xuXG4gICAgaWYgKCFpc05hTih2YWx1ZSkpIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5xdWVyaWVzW25vZGVdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vdyBxdWVyeSB1bmRlciBpbmRleCAke25vZGV9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5xdWVyaWVzW25vZGVdO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufSIsIlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWV0YWJsZUNvbGxlY3Rpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLm1ldGFkYXRhID0gW107XG4gICAgdGhpcy5LRVlfQ09MVU1OID0gJ2tleSc7XG4gICAgdGhpcy5WQUxVRV9DT0xVTU4gPSAndmFsdWUnO1xuICAgIHRoaXMuVFlQRV9DT0xVTU4gPSAndHlwZSc7XG4gICAgdGhpcy5tb2RlbCA9IG51bGw7XG4gICAgdGhpcy5leHRyYUNvbHVtbnMgPSBbXTtcblxuICAgIHRoaXMuZXh0cmFRdWVyeSA9IChxdWVyeSwgbWV0YSkgPT4ge1xuICAgICAgcXVlcnkud2hlcmUoJ2tleScsIG1ldGFbdGhpcy5LRVlfQ09MVU1OXSk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgbW9kZWwgb2YgdGhpcyBtZXRhZGF0YSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge09iamVjdH0gbW9kZWwgLVxuICAgKi9cbiAgc2V0TW9kZWwobW9kZWwpIHtcbiAgICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogRmluZCB0aGUgZ2l2ZW4gbWV0YWRhdGEga2V5LlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IC1cbiAgICogQHJldHVybiB7b2JqZWN0fSAtIE1ldGFkYXRhIG9iamVjdC5cbiAgICovXG4gIGZpbmRNZXRhKGtleSkge1xuICAgIHJldHVybiB0aGlzLmFsbE1ldGFkYXRhKCkuZmluZCgobWV0YSkgPT4gbWV0YS5rZXkgPT09IGtleSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYWxsIG1ldGFkYXRhLlxuICAgKi9cbiAgYWxsTWV0YWRhdGEoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0YWRhdGEuZmlsdGVyKChtZXRhKSA9PiAhbWV0YS5tYXJrQXNEZWxldGVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBtZXRhZGF0YSBvZiB0aGUgZ2l2ZW4ga2V5LlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IC1cbiAgICogQHBhcmFtIHtNaXhpZWR9IGRlZmF1bHRWYWx1ZSAtXG4gICAqL1xuICBnZXRNZXRhKGtleSwgZGVmYXVsdFZhbHVlKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmZpbmRNZXRhKGtleSk7XG4gICAgcmV0dXJuIG1ldGFkYXRhID8gbWV0YWRhdGEudmFsdWUgOiBkZWZhdWx0VmFsdWUgfHwgZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogTWFya2VzIHRoZSBtZXRhZGF0YSB0byBzaG91bGQgYmUgZGVsZXRlZC5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleSAtXG4gICAqL1xuICByZW1vdmVNZXRhKGtleSkge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5maW5kTWV0YShrZXkpO1xuXG4gICAgaWYgKG1ldGFkYXRhKSB7XG4gICAgICBtZXRhZGF0YS5tYXJrQXNEZWxldGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlIGFsbCBtZXRhIGRhdGEgb2YgdGhlIGdpdmVuIGdyb3VwLlxuICAgKiBAcGFyYW0geyp9IGdyb3VwXG4gICAqL1xuICByZW1vdmVBbGxNZXRhKGdyb3VwID0gJ2RlZmF1bHQnKSB7XG4gICAgdGhpcy5tZXRhZGF0YSA9IHRoaXMubWV0YWRhdGEubWFwKChtZXRhKSA9PiAoe1xuICAgICAgLi4ubWV0YSxcbiAgICAgIG1hcmtBc0RlbGV0ZWQ6IHRydWUsXG4gICAgfSkpO1xuICB9XG5cbiAgc2V0RXh0cmFRdWVyeShjYWxsYmFjaykge1xuICAgIHRoaXMuZXh0cmFRdWVyeSA9IGNhbGxiYWNrO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbWV0YSBkYXRhIHRvIHRoZSBzdGFjay5cbiAgICogQHBhcmFtIHtTdHJpbmd9IGtleSAtXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZSAtXG4gICAqL1xuICBzZXRNZXRhKGtleSwgdmFsdWUsIHBheWxvYWQpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShrZXkpKSB7XG4gICAgICBjb25zdCBtZXRhZGF0YSA9IGtleTtcblxuICAgICAgbWV0YWRhdGEuZm9yRWFjaCgobWV0YSkgPT4ge1xuICAgICAgICB0aGlzLnNldE1ldGEobWV0YS5rZXksIG1ldGEudmFsdWUpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5maW5kTWV0YShrZXkpO1xuXG4gICAgaWYgKG1ldGFkYXRhKSB7XG4gICAgICBtZXRhZGF0YS52YWx1ZSA9IHZhbHVlO1xuICAgICAgbWV0YWRhdGEubWFya0FzVXBkYXRlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWV0YWRhdGEucHVzaCh7XG4gICAgICAgIHZhbHVlLCBrZXksIC4uLnBheWxvYWQsIG1hcmtBc0luc2VydGVkOiB0cnVlLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVkIHRoZSBtb2RpZmllZC9kZWxldGVkIGFuZCBpbnNlcnRlZCBtZXRhZGF0YS5cbiAgICovXG4gIGFzeW5jIHNhdmVNZXRhKCkge1xuICAgIGNvbnN0IGluc2VydGVkID0gdGhpcy5tZXRhZGF0YS5maWx0ZXIoKG0pID0+IChtLm1hcmtBc0luc2VydGVkID09PSB0cnVlKSk7XG4gICAgY29uc3QgdXBkYXRlZCA9IHRoaXMubWV0YWRhdGEuZmlsdGVyKChtKSA9PiAobS5tYXJrQXNVcGRhdGVkID09PSB0cnVlKSk7XG4gICAgY29uc3QgZGVsZXRlZCA9IHRoaXMubWV0YWRhdGEuZmlsdGVyKChtKSA9PiAobS5tYXJrQXNEZWxldGVkID09PSB0cnVlKSk7XG4gICAgY29uc3Qgb3BlcnMgPSBbXTtcblxuICAgIGlmIChkZWxldGVkLmxlbmd0aCA+IDApIHtcbiAgICAgIGRlbGV0ZWQuZm9yRWFjaCgobWV0YSkgPT4ge1xuICAgICAgICBjb25zdCBkZWxldGVPcGVyID0gdGhpcy5tb2RlbC5xdWVyeSgpLmJlZm9yZVJ1bigocXVlcnksIHJlc3VsdCkgPT4ge1xuICAgICAgICAgIHRoaXMuZXh0cmFRdWVyeShxdWVyeSwgbWV0YSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSkuZGVsZXRlKCk7XG4gICAgICAgIG9wZXJzLnB1c2goZGVsZXRlT3Blcik7XG4gICAgICB9KTtcbiAgICB9XG4gICAgaW5zZXJ0ZWQuZm9yRWFjaCgobWV0YSkgPT4ge1xuICAgICAgY29uc3QgaW5zZXJ0T3BlciA9IHRoaXMubW9kZWwucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICBbdGhpcy5LRVlfQ09MVU1OXTogbWV0YS5rZXksXG4gICAgICAgIFt0aGlzLlZBTFVFX0NPTFVNTl06IG1ldGEudmFsdWUsXG4gICAgICAgIC4uLnRoaXMuZXh0cmFDb2x1bW5zLnJlZHVjZSgob2JqLCBjb2x1bW4pID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIG1ldGFbY29sdW1uXSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICAgIG9ialtjb2x1bW5dID0gbWV0YVtjb2x1bW5dO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSksXG4gICAgICB9KTtcbiAgICAgIG9wZXJzLnB1c2goaW5zZXJ0T3Blcik7XG4gICAgfSk7XG4gICAgdXBkYXRlZC5mb3JFYWNoKChtZXRhKSA9PiB7XG4gICAgICBjb25zdCB1cGRhdGVPcGVyID0gdGhpcy5tb2RlbC5xdWVyeSgpLm9uQnVpbGQoKHF1ZXJ5KSA9PiB7XG4gICAgICAgIHRoaXMuZXh0cmFRdWVyeShxdWVyeSwgbWV0YSk7XG4gICAgICB9KS5wYXRjaCh7XG4gICAgICAgIFt0aGlzLlZBTFVFX0NPTFVNTl06IG1ldGEudmFsdWUsXG4gICAgICB9KTtcbiAgICAgIG9wZXJzLnB1c2godXBkYXRlT3Blcik7XG4gICAgfSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwob3BlcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBtZXRhZGF0YSBmcm9tIHRoZSBzdG9yYWdlLlxuICAgKiBAcGFyYW0ge1N0cmluZ3xBcnJheX0ga2V5IC1cbiAgICogQHBhcmFtIHtCb29sZWFufSBmb3JjZSAtXG4gICAqL1xuICBhc3luYyBsb2FkKCkge1xuICAgIGNvbnN0IG1ldGFkYXRhID0gYXdhaXQgdGhpcy5xdWVyeSgpO1xuXG4gICAgY29uc3QgbWV0YWRhdGFBcnJheSA9IHRoaXMubWFwTWV0YWRhdGFDb2xsZWN0aW9uKG1ldGFkYXRhKTtcbiAgICBtZXRhZGF0YUFycmF5LmZvckVhY2goKG1ldGEpID0+IHtcbiAgICAgIHRoaXMubWV0YWRhdGEucHVzaChtZXRhKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JtYXQgdGhlIG1ldGFkYXRhIGJlZm9yZSBzYXZpbmcgdG8gdGhlIGRhdGFiYXNlLlxuICAgKiBAcGFyYW0ge1N0cmluZ3xOdW1iZXJ8Qm9vbGVhbn0gdmFsdWUgLVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVUeXBlIC1cbiAgICogQHJldHVybiB7U3RyaW5nfE51bWJlcnxCb29sZWFufSAtXG4gICAqL1xuICBzdGF0aWMgZm9ybWF0TWV0YVZhbHVlKHZhbHVlLCB2YWx1ZVR5cGUpIHtcbiAgICBsZXQgcGFyc2VkVmFsdWU7XG5cbiAgICBzd2l0Y2ggKHZhbHVlVHlwZSkge1xuICAgICAgY2FzZSAnbnVtYmVyJzpcbiAgICAgICAgcGFyc2VkVmFsdWUgPSBgJHt2YWx1ZX1gO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Jvb2xlYW4nOlxuICAgICAgICBwYXJzZWRWYWx1ZSA9IHZhbHVlID8gJzEnIDogJzAnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2pzb24nOlxuICAgICAgICBwYXJzZWRWYWx1ZSA9IEpTT04uc3RyaW5naWZ5KHBhcnNlZFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBwYXJzZWRWYWx1ZSA9IHZhbHVlO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHBhcnNlZFZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hcHBpbmcgYW5kIHBhcnNlIG1ldGFkYXRhIHRvIGNvbGxlY3Rpb24gZW50cmllcy5cbiAgICogQHBhcmFtIHtNZXRhfSBhdHRyIC1cbiAgICogQHBhcmFtIHtTdHJpbmd9IHBhcnNlVHlwZSAtXG4gICAqL1xuICBtYXBNZXRhZGF0YShhdHRyLCBwYXJzZVR5cGUgPSAncGFyc2UnKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGtleTogYXR0clt0aGlzLktFWV9DT0xVTU5dLFxuICAgICAgdmFsdWU6IChwYXJzZVR5cGUgPT09ICdwYXJzZScpXG4gICAgICAgID8gTWV0YWJsZUNvbGxlY3Rpb24ucGFyc2VNZXRhVmFsdWUoXG4gICAgICAgICAgYXR0clt0aGlzLlZBTFVFX0NPTFVNTl0sXG4gICAgICAgICAgdGhpcy5UWVBFX0NPTFVNTiA/IGF0dHJbdGhpcy5UWVBFX0NPTFVNTl0gOiBmYWxzZSxcbiAgICAgICAgKVxuICAgICAgICA6IE1ldGFibGVDb2xsZWN0aW9uLmZvcm1hdE1ldGFWYWx1ZShcbiAgICAgICAgICBhdHRyW3RoaXMuVkFMVUVfQ09MVU1OXSxcbiAgICAgICAgICB0aGlzLlRZUEVfQ09MVU1OID8gYXR0clt0aGlzLlRZUEVfQ09MVU1OXSA6IGZhbHNlLFxuICAgICAgICApLFxuICAgICAgLi4udGhpcy5leHRyYUNvbHVtbnMubWFwKChleHRyYUNvbCkgPT4gKHtcbiAgICAgICAgW2V4dHJhQ29sXTogYXR0cltleHRyYUNvbF0gfHwgbnVsbCxcbiAgICAgIH0pKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIHRoZSBtZXRhZGF0YSB0byB0aGUgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIHtBcnJheX0gY29sbGVjdGlvbiAtXG4gICAqL1xuICBtYXBNZXRhZGF0YVRvQ29sbGVjdGlvbihtZXRhZGF0YSwgcGFyc2VUeXBlID0gJ3BhcnNlJykge1xuICAgIHJldHVybiBtZXRhZGF0YS5tYXAoKG1vZGVsKSA9PiB0aGlzLm1hcE1ldGFkYXRhVG9Db2xsZWN0aW9uKG1vZGVsLCBwYXJzZVR5cGUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIG1ldGFkYXRhIHRvIHRoZSBtZXRhYmxlIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXl9IG1ldGEgLVxuICAgKi9cbiAgZnJvbShtZXRhKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkobWV0YSkpIHtcbiAgICAgIG1ldGEuZm9yRWFjaCgobSkgPT4geyB0aGlzLmZyb20obSk7IH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLm1ldGFkYXRhLnB1c2gobWV0YSk7XG4gIH1cblxuXG4gIHRvQXJyYXkoKSB7XG4gICAgcmV0dXJuIHRoaXMubWV0YWRhdGE7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGljIG1ldGhvZCB0byBsb2FkIG1ldGFkYXRhIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge0FycmF5fSBtZXRhIFxuICAgKi9cbiAgc3RhdGljIGZyb20obWV0YSkge1xuICAgIGNvbnN0IGNvbGxlY3Rpb24gPSBuZXcgTWV0YWJsZUNvbGxlY3Rpb24oKTtcbiAgICBjb2xsZWN0aW9uLmZyb20obWV0YSk7XG5cbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfVxufVxuIiwiaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgeyBMZXhlciB9IGZyb20gJ0AvbGliL0xvZ2ljRXZhbHVhdGlvbi9MZXhlcic7XG5pbXBvcnQgUGFyc2VyIGZyb20gJ0AvbGliL0xvZ2ljRXZhbHVhdGlvbi9QYXJzZXInO1xuaW1wb3J0IFF1ZXJ5UGFyc2VyIGZyb20gJ0AvbGliL0xvZ2ljRXZhbHVhdGlvbi9RdWVyeVBhcnNlcic7XG5pbXBvcnQgcmVzb3VyY2VGaWVsZHNLZXlzIGZyb20gJ0AvZGF0YS9SZXNvdXJjZUZpZWxkc0tleXMnO1xuXG4vLyAgY29uc3Qgcm9sZSA9IHtcbi8vICAgY29tcGF0b3RvcjogJycsXG4vLyAgIHZhbHVlOiAnJyxcbi8vICAgY29sdW1uS2V5OiAnJyxcbi8vICAgY29sdW1uU2x1ZzogJycsXG4vLyAgIGluZGV4OiAxLFxuLy8gfVxuXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRSb2xlUXVlcnkocm9sZSkge1xuICBjb25zdCBjb2x1bW5OYW1lID0gcmVzb3VyY2VGaWVsZHNLZXlzW3JvbGUuY29sdW1uS2V5XTtcblxuICBzd2l0Y2ggKHJvbGUuY29tcGFyYXRvcikge1xuICAgIGNhc2UgJ2VxdWFscyc6XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAoYnVpbGRlcikgPT4ge1xuICAgICAgICBidWlsZGVyLndoZXJlKGNvbHVtbk5hbWUsIHJvbGUudmFsdWUpO1xuICAgICAgfTtcbiAgICBjYXNlICdub3RfZXF1YWwnOlxuICAgIGNhc2UgJ25vdF9lcXVhbHMnOlxuICAgICAgcmV0dXJuIChidWlsZGVyKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIud2hlcmVOb3QoY29sdW1uTmFtZSwgcm9sZS52YWx1ZSk7XG4gICAgICB9O1xuICB9XG59XG5cbi8qKlxuICogQnVpbGRzIGRhdGFiYXNlIHF1ZXJ5IGZyb20gc3RvcmVkIHZpZXcgcm9sZXMuXG4gKlxuICogQHBhcmFtIHtBcnJheX0gcm9sZXMgLVxuICogQHJldHVybiB7RnVuY3Rpb259XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2aWV3Um9sZXNCdWlsZGVyKHJvbGVzLCBsb2dpY0V4cHJlc3Npb24gPSAnJykge1xuICBjb25zdCByb2xlc0luZGV4U2V0ID0ge307XG5cbiAgcm9sZXMuZm9yRWFjaCgocm9sZSkgPT4ge1xuICAgIHJvbGVzSW5kZXhTZXRbcm9sZS5pbmRleF0gPSBidWlsZFJvbGVRdWVyeShyb2xlKTtcbiAgfSk7XG4gIC8vIExleGVyIGZvciBsb2dpYyBleHByZXNzaW9uLlxuICBjb25zdCBsZXhlciA9IG5ldyBMZXhlcihsb2dpY0V4cHJlc3Npb24pO1xuICBjb25zdCB0b2tlbnMgPSBsZXhlci5nZXRUb2tlbnMoKTtcblxuICAvLyBQYXJzZSB0aGUgbG9naWMgZXhwcmVzc2lvbi5cbiAgY29uc3QgcGFyc2VyID0gbmV3IFBhcnNlcih0b2tlbnMpO1xuICBjb25zdCBwYXJzZWRUcmVlID0gcGFyc2VyLnBhcnNlKCk7XG5cbiAgY29uc3QgcXVlcnlQYXJzZXIgPSBuZXcgUXVlcnlQYXJzZXIocGFyc2VkVHJlZSwgcm9sZXNJbmRleFNldCk7XG4gIHJldHVybiBxdWVyeVBhcnNlci5wYXJzZSgpO1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgdmlldyBsb2dpYyBleHByZXNzaW9uLlxuICogQHBhcmFtIHtTdHJpbmd9IGxvZ2ljRXhwcmVzc2lvbiBcbiAqIEBwYXJhbSB7QXJyYXl9IGluZGV4ZXMgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVZpZXdMb2dpY0V4cHJlc3Npb24obG9naWNFeHByZXNzaW9uLCBpbmRleGVzKSB7XG4gIGNvbnN0IGxvZ2ljRXhwSW5kZXhlcyA9IGxvZ2ljRXhwcmVzc2lvbi5tYXRjaCgvXFxkKy9nKSB8fCBbXTtcbiAgcmV0dXJuICFkaWZmZXJlbmNlKGxvZ2ljRXhwSW5kZXhlcy5tYXAoTnVtYmVyKSwgaW5kZXhlcykubGVuZ3RoO1xufVxuXG4vKipcbiAqIFxuICogQHBhcmFtIHtBcnJheX0gcm9sZXMgLVxuICogQHBhcmFtIHtTdHJpbmd9IGxvZ2ljRXhwcmVzc2lvbiAtXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVWaWV3Um9sZXMocm9sZXMsIGxvZ2ljRXhwcmVzc2lvbikge1xuICByZXR1cm4gdmFsaWRhdGVWaWV3TG9naWNFeHByZXNzaW9uKGxvZ2ljRXhwcmVzc2lvbiwgcm9sZXMubWFwKChyKSA9PiByLmluZGV4KSk7XG59XG5cbi8qKlxuICogTWFwZXMgdGhlIHZpZXcgcm9sZXMgdG8gdmlldyBjb25kaXRpb25hbHMuXG4gKiBAcGFyYW0ge0FycmF5fSB2aWV3Um9sZXMgLVxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXBWaWV3Um9sZXNUb0NvbmRpdGlvbmFscyh2aWV3Um9sZXMpIHtcbiAgcmV0dXJuIHZpZXdSb2xlcy5tYXAoKHZpZXdSb2xlKSA9PiAoe1xuICAgIGNvbXBhcmF0b3I6IHZpZXdSb2xlLmNvbXBhcmF0b3IsXG4gICAgdmFsdWU6IHZpZXdSb2xlLnZhbHVlLFxuICAgIGNvbHVtbktleTogdmlld1JvbGUuZmllbGQuY29sdW1uS2V5LFxuICAgIHNsdWc6IHZpZXdSb2xlLmZpZWxkLnNsdWcsXG4gICAgaW5kZXg6IHZpZXdSb2xlLmluZGV4LFxuICB9KSk7XG59IiwiLyogZXNsaW50LWRpc2FibGUgZ2xvYmFsLXJlcXVpcmUgKi9cbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5pbXBvcnQge3ZpZXdSb2xlc0J1aWxkZXJ9IGZyb20gJ0AvbGliL1ZpZXdSb2xlc0J1aWxkZXInO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBY2NvdW50IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYWNjb3VudHMnO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vZGVsIG1vZGlmaWVycy5cbiAgICovXG4gIHN0YXRpYyBnZXQgbW9kaWZpZXJzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBmaWx0ZXJBY2NvdW50VHlwZXMocXVlcnksIHR5cGVzSWRzKSB7XG4gICAgICAgIGlmICh0eXBlc0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmVJbignYWNjb3VuX3R5cGVfaWQnLCB0eXBlc0lkcyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB2aWV3Um9sZXNCdWlsZGVyKHF1ZXJ5LCBjb25kaXRpb25hbHMsIGV4cHJlc3Npb24pIHtcbiAgICAgICAgdmlld1JvbGVzQnVpbGRlcihjb25kaXRpb25hbHMsIGV4cHJlc3Npb24pKHF1ZXJ5KTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBBY2NvdW50VHlwZSA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnRUeXBlJyk7XG4gICAgY29uc3QgQWNjb3VudEJhbGFuY2UgPSByZXF1aXJlKCdAL21vZGVscy9BY2NvdW50QmFsYW5jZScpO1xuICAgIGNvbnN0IEFjY291bnRUcmFuc2FjdGlvbiA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnRUcmFuc2FjdGlvbicpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogQWNjb3VudCBtb2RlbCBtYXkgYmVsb25ncyB0byBhY2NvdW50IHR5cGUuXG4gICAgICAgKi9cbiAgICAgIHR5cGU6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBBY2NvdW50VHlwZS5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRzLmFjY291bnRUeXBlSWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudF90eXBlcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIEFjY291bnQgbW9kZWwgbWF5IGhhcyBtYW55IGJhbGFuY2VzIGFjY291bnRzLlxuICAgICAgICovXG4gICAgICBiYWxhbmNlOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNPbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudEJhbGFuY2UuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdhY2NvdW50cy5pZCcsXG4gICAgICAgICAgdG86ICdhY2NvdW50X2JhbGFuY2VzLmFjY291bnRJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIEFjY291bnQgbW9kZWwgbWF5IGhhcyBtYW55IHRyYW5zYWN0aW9ucy5cbiAgICAgICAqL1xuICAgICAgdHJhbnNhY3Rpb25zOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNNYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IEFjY291bnRUcmFuc2FjdGlvbi5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRzLmlkJyxcbiAgICAgICAgICB0bzogJ2FjY291bnRzX3RyYW5zYWN0aW9ucy5hY2NvdW50SWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgc3RhdGljIGNvbGxlY3RKb3VybmFsRW50cmllcyhhY2NvdW50cykge1xuICAgIHJldHVybiBmbGF0dGVuKGFjY291bnRzLm1hcCgoYWNjb3VudCkgPT4gYWNjb3VudC50cmFuc2FjdGlvbnMubWFwKCh0cmFuc2FjdGlvbikgPT4gKHtcbiAgICAgIGFjY291bnRJZDogYWNjb3VudC5pZCxcbiAgICAgIC4uLnRyYW5zYWN0aW9uLFxuICAgICAgYWNjb3VudE5vcm1hbDogYWNjb3VudC50eXBlLm5vcm1hbCxcbiAgICB9KSkpKTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFjY291bnRCYWxhbmNlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYWNjb3VudF9iYWxhbmNlcyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgQWNjb3VudCA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnQnKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2NvdW50OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRfYmFsYW5jZS5hY2NvdW50X2lkJyxcbiAgICAgICAgICB0bzogJ2FjY291bnRzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFjY291bnRUcmFuc2FjdGlvbiBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ2FjY291bnRzX3RyYW5zYWN0aW9ucyc7XG4gIH1cblxuICAvKipcbiAgICogTW9kZWwgbW9kaWZpZXJzLlxuICAgKi9cbiAgc3RhdGljIGdldCBtb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbHRlckFjY291bnRzKHF1ZXJ5LCBhY2NvdW50c0lkcykge1xuICAgICAgICBpZiAoYWNjb3VudHNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlSW4oJ2FjY291bnRfaWQnLCBhY2NvdW50c0lkcyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBmaWx0ZXJUcmFuc2FjdGlvblR5cGVzKHF1ZXJ5LCB0eXBlcykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheSh0eXBlcykgJiYgdHlwZXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlSW4oJ3JlZmVyZW5jZV90eXBlJywgdHlwZXMpO1xuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0eXBlcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgncmVmZXJlbmNlX3R5cGUnLCB0eXBlcyk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBmaWx0ZXJEYXRlUmFuZ2UocXVlcnksIHN0YXJ0RGF0ZSwgZW5kRGF0ZSwgdHlwZSA9ICdkYXknKSB7XG4gICAgICAgIGNvbnN0IGRhdGVGb3JtYXQgPSAnWVlZWS1NTS1ERCBISDptbTpzcyc7XG4gICAgICAgIGNvbnN0IGZyb21EYXRlID0gbW9tZW50KHN0YXJ0RGF0ZSkuc3RhcnRPZih0eXBlKS5mb3JtYXQoZGF0ZUZvcm1hdCk7XG4gICAgICAgIGNvbnN0IHRvRGF0ZSA9IG1vbWVudChlbmREYXRlKS5lbmRPZih0eXBlKS5mb3JtYXQoZGF0ZUZvcm1hdCk7XG5cbiAgICAgICAgaWYgKHN0YXJ0RGF0ZSkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdkYXRlJywgJz49JywgZnJvbURhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbmREYXRlKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ2RhdGUnLCAnPD0nLCB0b0RhdGUpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZmlsdGVyQW1vdW50UmFuZ2UocXVlcnksIGZyb21BbW91bnQsIHRvQW1vdW50KSB7XG4gICAgICAgIGlmIChmcm9tQW1vdW50KSB7XG4gICAgICAgICAgcXVlcnkuYW5kV2hlcmUoKHEpID0+IHtcbiAgICAgICAgICAgIHEud2hlcmUoJ2NyZWRpdCcsICc+PScsIGZyb21BbW91bnQpO1xuICAgICAgICAgICAgcS5vcldoZXJlKCdkZWJpdCcsICc+PScsIGZyb21BbW91bnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b0Ftb3VudCkge1xuICAgICAgICAgIHF1ZXJ5LmFuZFdoZXJlKChxKSA9PiB7XG4gICAgICAgICAgICBxLndoZXJlKCdjcmVkaXQnLCAnPD0nLCB0b0Ftb3VudCk7XG4gICAgICAgICAgICBxLm9yV2hlcmUoJ2RlYml0JywgJzw9JywgdG9BbW91bnQpO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgc3VtYXRpb25DcmVkaXREZWJpdChxdWVyeSkge1xuICAgICAgICBxdWVyeS5zdW0oJ2NyZWRpdCBhcyBjcmVkaXQnKTtcbiAgICAgICAgcXVlcnkuc3VtKCdkZWJpdCBhcyBkZWJpdCcpO1xuICAgICAgICBxdWVyeS5ncm91cEJ5KCdhY2NvdW50X2lkJyk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgQWNjb3VudCA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnQnKTtcblxuICAgIHJldHVybiB7XG4gICAgICBhY2NvdW50OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRzX3RyYW5zYWN0aW9ucy5hY2NvdW50SWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCIvLyBpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBBY2NvdW50VHlwZSBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ2FjY291bnRfdHlwZXMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IEFjY291bnQgPSByZXF1aXJlKCdAL21vZGVscy9BY2NvdW50Jyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBBY2NvdW50IHR5cGUgbWF5IGhhcyBtYW55IGFzc29jaWF0ZWQgYWNjb3VudHMuXG4gICAgICAgKi9cbiAgICAgIGFjY291bnRzOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNNYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IEFjY291bnQuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdhY2NvdW50X3R5cGVzLmlkJyxcbiAgICAgICAgICB0bzogJ2FjY291bnRzLmFjY291bnRUeXBlSWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnVkZ2V0IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYnVkZ2V0cyc7XG4gIH1cblxuICBzdGF0aWMgZ2V0IHZpcnR1YWxBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ3JhbmdlQnknLCAncmFuZ2VJbmNyZW1lbnQnXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RlbCBtb2RpZmllcnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IG1vZGlmaWVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsdGVyQnlZZWFyKHF1ZXJ5LCB5ZWFyKSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKCd5ZWFyJywgeWVhcik7XG4gICAgICB9LFxuICAgICAgZmlsdGVyQnlJbmNvbWVTdGF0ZW1lbnQocXVlcnkpIHtcbiAgICAgICAgcXVlcnkud2hlcmUoJ2FjY291bnRfdHlwZXMnLCAnaW5jb21lX3N0YXRlbWVudCcpO1xuICAgICAgfSxcbiAgICAgIGZpbHRlckJ5UHJvZml0TG9zcyhxdWVyeSkge1xuICAgICAgICBxdWVyeS53aGVyZSgnYWNjb3VudHNfdHlwZXMnLCAncHJvZml0X2xvc3MnKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIGdldCByYW5nZUJ5KCkge1xuICAgIHN3aXRjaCAodGhpcy5wZXJpb2QpIHtcbiAgICAgIGNhc2UgJ2hhbGYteWVhcic6XG4gICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgcmV0dXJuICdtb250aCc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdGhpcy5wZXJpb2Q7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHJhbmdlSW5jcmVtZW50KCkge1xuICAgIHN3aXRjaCAodGhpcy5wZXJpb2QpIHtcbiAgICAgIGNhc2UgJ2hhbGYteWVhcic6XG4gICAgICAgIHJldHVybiA2O1xuICAgICAgY2FzZSAncXVhcnRlcic6XG4gICAgICAgIHJldHVybiAzO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIDE7XG4gICAgfVxuICB9XG5cbiAgZ2V0IHJhbmdlT2Zmc2V0KCkge1xuICAgIHN3aXRjaCAodGhpcy5wZXJpb2QpIHtcbiAgICAgIGNhc2UgJ2hhbGYteWVhcic6IHJldHVybiA1O1xuICAgICAgY2FzZSAncXVhcnRlcic6IHJldHVybiAyO1xuICAgICAgZGVmYXVsdDogcmV0dXJuIDA7XG4gICAgfVxuICB9XG59XG4iLCJpbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQnVkZ2V0IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYnVkZ2V0X2VudHJpZXMnO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcbmltcG9ydCB7dmlld1JvbGVzQnVpbGRlcn0gZnJvbSAnQC9saWIvVmlld1JvbGVzQnVpbGRlcic7XG5leHBvcnQgZGVmYXVsdCBjbGFzcyBFeHBlbnNlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnZXhwZW5zZXMnO1xuICB9XG5cbiAgc3RhdGljIGdldCByZWZlcmVuY2VUeXBlKCkge1xuICAgIHJldHVybiAnRXhwZW5zZSc7XG4gIH1cblxuICAvKipcbiAgICogTW9kZWwgbW9kaWZpZXJzLlxuICAgKi9cbiAgc3RhdGljIGdldCBtb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbHRlckJ5RGF0ZVJhbmdlKHF1ZXJ5LCBzdGFydERhdGUsIGVuZERhdGUpIHtcbiAgICAgICAgaWYgKHN0YXJ0RGF0ZSkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdkYXRlJywgJz49Jywgc3RhcnREYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZW5kRGF0ZSkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdkYXRlJywgJzw9JywgZW5kRGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBmaWx0ZXJCeUFtb3VudFJhbmdlKHF1ZXJ5LCBmcm9tLCB0bykge1xuICAgICAgICBpZiAoZnJvbSkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdhbW91bnQnLCAnPj0nLCBmcm9tKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodG8pIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnYW1vdW50JywgJzw9JywgdG8pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZmlsdGVyQnlFeHBlbnNlQWNjb3VudChxdWVyeSwgYWNjb3VudElkKSB7XG4gICAgICAgIGlmIChhY2NvdW50SWQpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnZXhwZW5zZV9hY2NvdW50X2lkJywgYWNjb3VudElkKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGZpbHRlckJ5UGF5bWVudEFjY291bnQocXVlcnksIGFjY291bnRJZCkge1xuICAgICAgICBpZiAoYWNjb3VudElkKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ3BheW1lbnRfYWNjb3VudF9pZCcsIGFjY291bnRJZCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIHZpZXdSb2xlc0J1aWxkZXIocXVlcnksIGNvbmRpdGlvbmFscywgZXhwcmVzc2lvbikge1xuICAgICAgICB2aWV3Um9sZXNCdWlsZGVyKGNvbmRpdGlvbmFscywgZXhwcmVzc2lvbikocXVlcnkpO1xuICAgICAgfSxcblxuICAgICAgb3JkZXJCeShxdWVyeSkge1xuICAgICAgICBcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IEFjY291bnQgPSByZXF1aXJlKCdAL21vZGVscy9BY2NvdW50Jyk7XG4gICAgY29uc3QgVXNlciA9IHJlcXVpcmUoJ0AvbW9kZWxzL1VzZXInKTtcblxuICAgIHJldHVybiB7XG4gICAgICBwYXltZW50QWNjb3VudDoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IEFjY291bnQuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdleHBlbnNlcy5wYXltZW50QWNjb3VudElkJyxcbiAgICAgICAgICB0bzogJ2FjY291bnRzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIGV4cGVuc2VBY2NvdW50OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2V4cGVuc2VzLmV4cGVuc2VBY2NvdW50SWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgdXNlcjoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFVzZXIuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdleHBlbnNlcy51c2VySWQnLFxuICAgICAgICAgIHRvOiAndXNlcnMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBJdGVtIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnaXRlbXMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIEl0ZW0gbWF5IGhhcyBtYW55IG1ldGEgZGF0YS5cbiAgICAgICAqL1xuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnSXRlbU1ldGFkYXRhJyksXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnaXRlbXMuaWQnLFxuICAgICAgICAgIHRvOiAnaXRlbXNfbWV0YWRhdGEuaXRlbV9pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIEl0ZW0gbWF5IGJlbG9uZ3MgdG8gY2F0ZW9nb3J5IG1vZGVsLlxuICAgICAgICovXG4gICAgICBjYXRlZ29yeToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQmFzZTogcGF0aC5qb2luKF9fZGlybmFtZSwgJ0l0ZW1DYXRlZ29yeScpLFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2l0ZW1zLmNhdGVnb3J5SWQnLFxuICAgICAgICAgIHRvOiAnaXRlbXNfY2F0ZWdvcmllcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEl0ZW1DYXRlZ29yeSBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdpdGVtc19jYXRlZ29yaWVzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBJdGVtIGNhdGVnb3J5IG1heSBoYXMgbWFueSBpdGVtcy5cbiAgICAgICAqL1xuICAgICAgaXRlbXM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnSXRlbScpLFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2l0ZW1zX2NhdGVnb3JpZXMuaXRlbV9pZCcsXG4gICAgICAgICAgdG86ICdpdGVtcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBKb3VybmFsRW50cnkgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnbWFudWFsX2pvdXJuYWxzJztcbiAgfVxufVxuIiwiaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1hbnVhbEpvdXJuYWwgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnbWFudWFsX2pvdXJuYWxzJztcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IHt0cmFuc2Zvcm0sIHNuYWtlQ2FzZX0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7bWFwS2V5c0RlZXB9IGZyb20gJ0AvdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNb2RlbEJhc2UgZXh0ZW5kcyBNb2RlbCB7XG4gIHN0YXRpYyBnZXQgY29sbGVjdGlvbigpIHtcbiAgICByZXR1cm4gQXJyYXk7XG4gIH1cblxuICBzdGF0aWMgcXVlcnkoLi4uYXJncykge1xuICAgIHJldHVybiBzdXBlci5xdWVyeSguLi5hcmdzKS5ydW5BZnRlcigocmVzdWx0KSA9PiB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXN1bHQpKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb24uZnJvbShyZXN1bHQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgfVxuXG4gICRmb3JtYXRKc29uKGpzb24sIG9wdCkge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVkID0gbWFwS2V5c0RlZXAoanNvbiwgKHZhbHVlLCBrZXkpID0+IHtcbiAgICAgIHJldHVybiBzbmFrZUNhc2Uoa2V5KTtcbiAgICB9KTtcbiAgICBjb25zdCBwYXJzZWRKc29uID0gc3VwZXIuJGZvcm1hdEpzb24odHJhbnNmb3JtZWQsIG9wdCk7XG5cbiAgICByZXR1cm4gcGFyc2VkSnNvbjtcbiAgfVxufVxuIiwiaW1wb3J0IHsgbWl4aW4gfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5pbXBvcnQgTWV0YWJsZUNvbGxlY3Rpb24gZnJvbSAnQC9saWIvTWV0YWJsZS9NZXRhYmxlQ29sbGVjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE9wdGlvbiBleHRlbmRzIG1peGluKEJhc2VNb2RlbCwgW21peGluXSkge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnb3B0aW9ucyc7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIG1vZGVsIHF1ZXJ5LlxuICAgKiBAcGFyYW0gIHsuLi5hbnl9IGFyZ3MgLVxuICAgKi9cbiAgc3RhdGljIHF1ZXJ5KC4uLmFyZ3MpIHtcbiAgICByZXR1cm4gc3VwZXIucXVlcnkoLi4uYXJncykucnVuQWZ0ZXIoKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdCBpbnN0YW5jZW9mIE1ldGFibGVDb2xsZWN0aW9uKSB7XG4gICAgICAgIHJlc3VsdC5zZXRNb2RlbChPcHRpb24pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgY29sbGVjdGlvbigpIHtcbiAgICByZXR1cm4gTWV0YWJsZUNvbGxlY3Rpb247XG4gIH1cbn1cbiIsImltcG9ydCBNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBhc3N3b3JkUmVzZXRzIGV4dGVuZHMgTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdwYXNzd29yZF9yZXNldHMnO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQZXJtaXNzaW9uIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUgb2YgUm9sZSBtb2RlbC5cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAncGVybWlzc2lvbnMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIFBlcm1pc3Npb24gbW9kZWwgbWF5IGJlbG9uZ3MgdG8gcm9sZSBtb2RlbC5cbiAgICAgICAqL1xuICAgICAgcm9sZToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQmFzZTogcGF0aC5qb2luKF9fZGlybmFtZSwgJ1JvbGUnKSxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdwZXJtaXNzaW9ucy5yb2xlX2lkJyxcbiAgICAgICAgICB0bzogJ3JvbGVzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8vIHJlc291cmNlOiB7XG4gICAgICAvLyAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgIC8vICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnUmVzb3VyY2UnKSxcbiAgICAgIC8vICAgam9pbjoge1xuICAgICAgLy8gICAgIGZyb206ICdwZXJtaXNzaW9ucy4nLFxuICAgICAgLy8gICAgIHRvOiAnJyxcbiAgICAgIC8vICAgfVxuICAgICAgLy8gfVxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3Jlc291cmNlcyc7XG4gIH1cblxuICAvKipcbiAgICogVGltZXN0YW1wIGNvbHVtbnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IGhhc1RpbWVzdGFtcHMoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IFZpZXcgPSByZXF1aXJlKCdAL21vZGVscy9WaWV3Jyk7XG4gICAgY29uc3QgUmVzb3VyY2VGaWVsZCA9IHJlcXVpcmUoJ0AvbW9kZWxzL1Jlc291cmNlRmllbGQnKTtcbiAgICBjb25zdCBQZXJtaXNzaW9uID0gcmVxdWlyZSgnQC9tb2RlbHMvUGVybWlzc2lvbicpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVzb3VyY2UgbW9kZWwgbWF5IGhhcyBtYW55IHZpZXdzLlxuICAgICAgICovXG4gICAgICB2aWV3czoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuSGFzTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBWaWV3LmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgICB0bzogJ3ZpZXdzLnJlc291cmNlSWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBSZXNvdXJjZSBtb2RlbCBtYXkgaGFzIG1hbnkgZmllbGRzLlxuICAgICAgICovXG4gICAgICBmaWVsZHM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogUmVzb3VyY2VGaWVsZC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3Jlc291cmNlcy5pZCcsXG4gICAgICAgICAgdG86ICdyZXNvdXJjZV9maWVsZHMucmVzb3VyY2VJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJlc291cmNlIG1vZGVsIG1heSBoYXMgbWFueSBhc3NvY2lhdGVkIHBlcm1pc3Npb25zLlxuICAgICAgICovXG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuTWFueVRvTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBQZXJtaXNzaW9uLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgICB0aHJvdWdoOiB7XG4gICAgICAgICAgICBmcm9tOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucmVzb3VyY2VJZCcsXG4gICAgICAgICAgICB0bzogJ3JvbGVfaGFzX3Blcm1pc3Npb25zLnBlcm1pc3Npb25JZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0bzogJ3Blcm1pc3Npb25zLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgc25ha2VDYXNlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlRmllbGQgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAncmVzb3VyY2VfZmllbGRzJztcbiAgfVxuXG4gIHN0YXRpYyBnZXQganNvbkF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnb3B0aW9ucyddO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vZGVsIG1vZGlmaWVycy5cbiAgICovXG4gIHN0YXRpYyBnZXQgbW9kaWZpZXJzKCkge1xuICAgIHJldHVybiB7XG4gICAgICB3aGVyZU5vdFByZWRlZmluZWQocXVlcnkpIHtcbiAgICAgICAgcXVlcnkud2hlcmVOb3QoJ3ByZWRlZmluZWQnLCB0cnVlKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgY29sdW1ucy5cbiAgICovXG4gIHN0YXRpYyBnZXQgaGFzVGltZXN0YW1wcygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogVmlydHVhbCBhdHRyaWJ1dGVzLlxuICAgKi9cbiAgc3RhdGljIGdldCB2aXJ0dWFsQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydrZXknXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvdXJjZSBmaWVsZCBrZXkuXG4gICAqL1xuICBrZXkoKSB7XG4gICAgcmV0dXJuIHNuYWtlQ2FzZSh0aGlzLmxhYmVsTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVzb3VyY2UgZmllbGQgbWF5IGJlbG9uZ3MgdG8gcmVzb3VyY2UgbW9kZWwuXG4gICAgICAgKi9cbiAgICAgIHJlc291cmNlOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnUmVzb3VyY2UnKSxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyZXNvdXJjZV9maWVsZHMucmVzb3VyY2VfaWQnLFxuICAgICAgICAgIHRvOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcbmltcG9ydCBSZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uIGZyb20gJ0AvY29sbGVjdGlvbi9SZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVzb3VyY2VGaWVsZE1ldGFkYXRhIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3Jlc291cmNlX2N1c3RvbV9maWVsZHNfbWV0YWRhdGEnO1xuICB9XG5cbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSByZXNvdXJjZSBmaWVsZCBtZXRhZGF0YSBjb2xsZWN0aW9uLlxuICAgKi9cbiAgc3RhdGljIGdldCBjb2xsZWN0aW9uKCkge1xuICAgIHJldHVybiBSZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIFJlc291cmNlIGZpZWxkIG1heSBiZWxvbmdzIHRvIHJlc291cmNlIG1vZGVsLlxuICAgICAgICovXG4gICAgICByZXNvdXJjZToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQmFzZTogcGF0aC5qb2luKF9fZGlybmFtZSwgJ1Jlc291cmNlJyksXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncmVzb3VyY2VfZmllbGRzLnJlc291cmNlX2lkJyxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSb2xlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUgb2YgUm9sZSBtb2RlbC5cbiAgICogQHR5cGUge1N0cmluZ31cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAncm9sZXMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRpbWVzdGFtcCBjb2x1bW5zLlxuICAgKi9cbiAgc3RhdGljIGdldCBoYXNUaW1lc3RhbXBzKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBQZXJtaXNzaW9uID0gcmVxdWlyZSgnQC9tb2RlbHMvUGVybWlzc2lvbicpO1xuICAgIGNvbnN0IFJlc291cmNlID0gcmVxdWlyZSgnQC9tb2RlbHMvUmVzb3VyY2UnKTtcbiAgICBjb25zdCBVc2VyID0gcmVxdWlyZSgnQC9tb2RlbHMvVXNlcicpO1xuICAgIGNvbnN0IFJlc291cmNlRmllbGQgPSByZXF1aXJlKCdAL21vZGVscy9SZXNvdXJjZUZpZWxkJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBSb2xlIG1heSBoYXMgbWFueSBwZXJtaXNzaW9ucy5cbiAgICAgICAqL1xuICAgICAgcGVybWlzc2lvbnM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLk1hbnlUb01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogUGVybWlzc2lvbi5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3JvbGVzLmlkJyxcbiAgICAgICAgICB0aHJvdWdoOiB7XG4gICAgICAgICAgICBmcm9tOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucm9sZUlkJyxcbiAgICAgICAgICAgIHRvOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucGVybWlzc2lvbklkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvOiAncGVybWlzc2lvbnMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBSb2xlIG1heSBoYXMgbWFueSByZXNvdXJjZXMuXG4gICAgICAgKi9cbiAgICAgIHJlc291cmNlczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuTWFueVRvTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBSZXNvdXJjZS5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3JvbGVzLmlkJyxcbiAgICAgICAgICB0aHJvdWdoOiB7XG4gICAgICAgICAgICBmcm9tOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucm9sZUlkJyxcbiAgICAgICAgICAgIHRvOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucmVzb3VyY2VJZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJvbGUgbWF5IGhhcyByZXNvdXJjZSBmaWVsZC5cbiAgICAgICAqL1xuICAgICAgZmllbGQ6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBSZXNvdXJjZUZpZWxkLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncm9sZXMuZmllbGRJZCcsXG4gICAgICAgICAgdG86ICdyZXNvdXJjZV9maWVsZHMuaWQnLFxuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJvbGUgbWF5IGhhcyBtYW55IGFzc29jaWF0ZWQgdXNlcnMuXG4gICAgICAgKi9cbiAgICAgIHVzZXJzOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5NYW55VG9NYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFVzZXIuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyb2xlcy5pZCcsXG4gICAgICAgICAgdGhyb3VnaDoge1xuICAgICAgICAgICAgZnJvbTogJ3VzZXJfaGFzX3JvbGVzLnJvbGVJZCcsXG4gICAgICAgICAgICB0bzogJ3VzZXJfaGFzX3JvbGVzLnVzZXJJZCcsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0bzogJ3VzZXJzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IGJjcnlwdCBmcm9tICdiY3J5cHRqcyc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcbi8vIGltcG9ydCBQZXJtaXNzaW9uc1NlcnZpY2UgZnJvbSAnQC9zZXJ2aWNlcy9QZXJtaXNzaW9uc1NlcnZpY2UnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBVc2VyIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLy8gLi4uUGVybWlzc2lvbnNTZXJ2aWNlXG5cbiAgc3RhdGljIGdldCB2aXJ0dWFsQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydmdWxsTmFtZSddO1xuICB9XG5cbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAndXNlcnMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IFJvbGUgPSByZXF1aXJlKCdAL21vZGVscy9Sb2xlJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcm9sZXM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLk1hbnlUb01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogUm9sZS5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3VzZXJzLmlkJyxcbiAgICAgICAgICB0aHJvdWdoOiB7XG4gICAgICAgICAgICBmcm9tOiAndXNlcl9oYXNfcm9sZXMudXNlcklkJyxcbiAgICAgICAgICAgIHRvOiAndXNlcl9oYXNfcm9sZXMucm9sZUlkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvOiAncm9sZXMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFZlcmlmeSB0aGUgcGFzc3dvcmQgb2YgdGhlIHVzZXIuXG4gICAqIEBwYXJhbSAge1N0cmluZ30gcGFzc3dvcmQgLSBUaGUgZ2l2ZW4gcGFzc3dvcmQuXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICB2ZXJpZnlQYXNzd29yZChwYXNzd29yZCkge1xuICAgIHJldHVybiBiY3J5cHQuY29tcGFyZVN5bmMocGFzc3dvcmQsIHRoaXMucGFzc3dvcmQpO1xuICB9XG5cbiAgZnVsbE5hbWUoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuZmlyc3ROYW1lfSAke3RoaXMubGFzdE5hbWV9YDtcbiAgfVxufVxuIiwiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlldyBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICd2aWV3cyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgUmVzb3VyY2UgPSByZXF1aXJlKCdAL21vZGVscy9SZXNvdXJjZScpO1xuICAgIGNvbnN0IFZpZXdDb2x1bW4gPSByZXF1aXJlKCdAL21vZGVscy9WaWV3Q29sdW1uJyk7XG4gICAgY29uc3QgVmlld1JvbGUgPSByZXF1aXJlKCdAL21vZGVscy9WaWV3Um9sZScpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogVmlldyBtb2RlbCBiZWxvbmdzIHRvIHJlc291cmNlIG1vZGVsLlxuICAgICAgICovXG4gICAgICByZXNvdXJjZToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFJlc291cmNlLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAndmlld3MucmVzb3VyY2VJZCcsXG4gICAgICAgICAgdG86ICdyZXNvdXJjZXMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgLyoqXG4gICAgICAgKiBWaWV3IG1vZGVsIG1heSBoYXMgbWFueSBjb2x1bW5zLlxuICAgICAgICovXG4gICAgICBjb2x1bW5zOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNNYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFZpZXdDb2x1bW4uZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICd2aWV3cy5pZCcsXG4gICAgICAgICAgdG86ICd2aWV3X2hhc19jb2x1bW5zLnZpZXdJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFZpZXcgbW9kZWwgbWF5IGhhcyBtYW55IHZpZXcgcm9sZXMuXG4gICAgICAgKi9cbiAgICAgIHJvbGVzOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNNYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFZpZXdSb2xlLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAndmlld3MuaWQnLFxuICAgICAgICAgIHRvOiAndmlld19yb2xlcy52aWV3SWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmlld0NvbHVtbiBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICd2aWV3X2hhc19jb2x1bW5zJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgY29sdW1ucy5cbiAgICovXG4gIHN0YXRpYyBnZXQgaGFzVGltZXN0YW1wcygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3Um9sZSBleHRlbmRzIEJhc2VNb2RlbCB7XG5cbiAgLyoqXG4gICAqIFZpcnR1YWwgYXR0cmlidXRlcy5cbiAgICovXG4gIHN0YXRpYyBnZXQgdmlydHVhbEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsnY29tcGFyYXRvcnMnXTtcbiAgfVxuXG4gIHN0YXRpYyBnZXQgY29tcGFyYXRvcnMoKSB7XG4gICAgcmV0dXJuIFtcbiAgICAgICdlcXVhbHMnLCAnbm90X2VxdWFsJywgJ2NvbnRhaW5zJywgJ25vdF9jb250YWluJyxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3ZpZXdfcm9sZXMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRpbWVzdGFtcCBjb2x1bW5zLlxuICAgKi9cbiAgc3RhdGljIGdldCBoYXNUaW1lc3RhbXBzKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBSZXNvdXJjZUZpZWxkID0gcmVxdWlyZSgnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZCcpO1xuICAgIGNvbnN0IFZpZXcgPSByZXF1aXJlKCdAL21vZGVscy9WaWV3Jyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBWaWV3IHJvbGUgbW9kZWwgbWF5IGJlbG9uZ3MgdG8gdmlldyBtb2RlbC5cbiAgICAgICAqL1xuICAgICAgdmlldzoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFZpZXcuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICd2aWV3X3JvbGVzLnZpZXdJZCcsXG4gICAgICAgICAgdG86ICd2aWV3cy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFZpZXcgcm9sZSBtb2RlbCBtYXkgYmVsb25ncyB0byByZXNvdXJjZSBmaWVsZCBtb2RlbC5cbiAgICAgICAqL1xuICAgICAgZmllbGQ6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBSZXNvdXJjZUZpZWxkLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAndmlld19yb2xlcy5maWVsZElkJyxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlX2ZpZWxkcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBrbmV4IGZyb20gJ0AvZGF0YWJhc2Uva25leCc7XG5cbi8vIEJpbmQgYWxsIE1vZGVscyB0byBhIGtuZXggaW5zdGFuY2UuIElmIHlvdSBvbmx5IGhhdmUgb25lIGRhdGFiYXNlIGluXG4vLyB5b3VyIHNlcnZlciB0aGlzIGlzIGFsbCB5b3UgaGF2ZSB0byBkby4gRm9yIG11bHRpIGRhdGFiYXNlIHN5c3RlbXMsIHNlZVxuLy8gdGhlIE1vZGVsLmJpbmRLbmV4KCkgbWV0aG9kLlxuTW9kZWwua25leChrbmV4KTtcbiIsImltcG9ydCBlcnJvckhhbmRsZXIgZnJvbSAnZXJyb3JoYW5kbGVyJztcbmltcG9ydCBhcHAgZnJvbSAnQC9hcHAnO1xuXG5hcHAudXNlKGVycm9ySGFuZGxlcik7XG5cbmNvbnN0IHNlcnZlciA9IGFwcC5saXN0ZW4oYXBwLmdldCgncG9ydCcpLCAoKSA9PiB7XG4gIGNvbnNvbGUubG9nKFxuICAgICcgIEFwcCBpcyBydW5uaW5nIGF0IGh0dHA6Ly9sb2NhbGhvc3Q6JWQgaW4gJXMgbW9kZScsXG4gICAgYXBwLmdldCgncG9ydCcpLFxuICAgIGFwcC5nZXQoJ2VudicpLFxuICApO1xuICBjb25zb2xlLmxvZygnICBQcmVzcyBDVFJMLUMgdG8gc3RvcCcpO1xufSk7XG5cbmV4cG9ydCBkZWZhdWx0IHNlcnZlcjtcbiIsIlxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSm91cm5hbEVudHJ5IHtcbiAgY29uc3RydWN0b3IoZW50cnkpIHtcbiAgICBjb25zdCBkZWZhdWx0cyA9IHtcbiAgICAgIGNyZWRpdDogMCxcbiAgICAgIGRlYml0OiAwLFxuICAgIH07XG4gICAgdGhpcy5lbnRyeSA9IHsgLi4uZGVmYXVsdHMsIC4uLmVudHJ5IH07XG4gIH1cbn1cbiIsImltcG9ydCB7IHBpY2sgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IEpvdXJuYWxFbnRyeSBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbEVudHJ5JztcbmltcG9ydCBBY2NvdW50VHJhbnNhY3Rpb24gZnJvbSAnQC9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uJztcbmltcG9ydCBBY2NvdW50QmFsYW5jZSBmcm9tICdAL21vZGVscy9BY2NvdW50QmFsYW5jZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEpvdXJuYWxQb3N0ZXIge1xuICAvKipcbiAgICogSm91cm5hbCBwb3N0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmVudHJpZXMgPSBbXTtcbiAgICB0aGlzLmJhbGFuY2VzQ2hhbmdlID0ge307XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIHRoZSBjcmVkaXQgZW50cnkgZm9yIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKiBAcGFyYW0ge0pvdXJuYWxFbnRyeX0gZW50cnkgLVxuICAgKi9cbiAgY3JlZGl0KGVudHJ5TW9kZWwpIHtcbiAgICBpZiAoZW50cnlNb2RlbCBpbnN0YW5jZW9mIEpvdXJuYWxFbnRyeSA9PT0gZmFsc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGVudHJ5IGlzIG5vdCBpbnN0YW5jZSBvZiBKb3VybmFsRW50cnkuJyk7XG4gICAgfVxuICAgIHRoaXMuZW50cmllcy5wdXNoKGVudHJ5TW9kZWwuZW50cnkpO1xuICAgIHRoaXMuc2V0QWNjb3VudEJhbGFuY2VDaGFuZ2UoZW50cnlNb2RlbC5lbnRyeSwgJ2NyZWRpdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyB0aGUgZGViaXQgZW50cnkgZm9yIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKiBAcGFyYW0ge0pvdXJuYWxFbnRyeX0gZW50cnkgLVxuICAgKi9cbiAgZGViaXQoZW50cnlNb2RlbCkge1xuICAgIGlmIChlbnRyeU1vZGVsIGluc3RhbmNlb2YgSm91cm5hbEVudHJ5ID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZW50cnkgaXMgbm90IGluc3RhbmNlIG9mIEpvdXJuYWxFbnRyeS4nKTtcbiAgICB9XG4gICAgdGhpcy5lbnRyaWVzLnB1c2goZW50cnlNb2RlbC5lbnRyeSk7XG4gICAgdGhpcy5zZXRBY2NvdW50QmFsYW5jZUNoYW5nZShlbnRyeU1vZGVsLmVudHJ5LCAnZGViaXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFjY291bnQgYmFsYW5jZSBjaGFuZ2UuXG4gICAqIEBwYXJhbSB7Sm91cm5hbEVudHJ5fSBlbnRyeVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKi9cbiAgc2V0QWNjb3VudEJhbGFuY2VDaGFuZ2UoZW50cnksIHR5cGUpIHtcbiAgICBpZiAoIXRoaXMuYmFsYW5jZXNDaGFuZ2VbZW50cnkuYWNjb3VudF0pIHtcbiAgICAgIHRoaXMuYmFsYW5jZXNDaGFuZ2VbZW50cnkuYWNjb3VudF0gPSAwO1xuICAgIH1cbiAgICBsZXQgY2hhbmdlID0gMDtcblxuICAgIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnY3JlZGl0Jykge1xuICAgICAgY2hhbmdlID0gKHR5cGUgPT09ICdjcmVkaXQnKSA/IGVudHJ5LmNyZWRpdCA6IC0xICogZW50cnkuZGViaXQ7XG4gICAgfSBlbHNlIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnZGViaXQnKSB7XG4gICAgICBjaGFuZ2UgPSAodHlwZSA9PT0gJ2RlYml0JykgPyBlbnRyeS5kZWJpdCA6IC0xICogZW50cnkuY3JlZGl0O1xuICAgIH1cbiAgICB0aGlzLmJhbGFuY2VzQ2hhbmdlW2VudHJ5LmFjY291bnRdICs9IGNoYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXBwaW5nIHRoZSBiYWxhbmNlIGNoYW5nZSB0byBsaXN0LlxuICAgKi9cbiAgbWFwQmFsYW5jZUNoYW5nZXNUb0xpc3QoKSB7XG4gICAgY29uc3QgbWFwcGVkTGlzdCA9IFtdO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5iYWxhbmNlc0NoYW5nZSkuZm9yRWFjaCgoYWNjb3VudElkKSA9PiB7XG4gICAgICBjb25zdCBiYWxhbmNlID0gdGhpcy5iYWxhbmNlc0NoYW5nZVthY2NvdW50SWRdO1xuXG4gICAgICBtYXBwZWRMaXN0LnB1c2goe1xuICAgICAgICBhY2NvdW50X2lkOiBhY2NvdW50SWQsXG4gICAgICAgIGFtb3VudDogYmFsYW5jZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBtYXBwZWRMaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBiYWxhbmNlIGNoYW5nZSBvZiBqb3VybmFsIGVudHJpZXMuXG4gICAqL1xuICBhc3luYyBzYXZlQmFsYW5jZSgpIHtcbiAgICBjb25zdCBiYWxhbmNlc0xpc3QgPSB0aGlzLm1hcEJhbGFuY2VDaGFuZ2VzVG9MaXN0KCk7XG4gICAgY29uc3QgYmFsYW5jZVVwZGF0ZU9wZXJzID0gW107XG4gICAgY29uc3QgYmFsYW5jZUluc2VydE9wZXJzID0gW107XG4gICAgY29uc3QgYmFsYW5jZUZpbmRPbmVPcGVycyA9IFtdO1xuICAgIGxldCBiYWxhbmNlQWNjb3VudHMgPSBbXTtcblxuICAgIGJhbGFuY2VzTGlzdC5mb3JFYWNoKChiYWxhbmNlKSA9PiB7XG4gICAgICBjb25zdCBvcGVyID0gQWNjb3VudEJhbGFuY2UucXVlcnkoKS5maW5kT25lKCdhY2NvdW50X2lkJywgYmFsYW5jZS5hY2NvdW50X2lkKTtcbiAgICAgIGJhbGFuY2VGaW5kT25lT3BlcnMucHVzaChvcGVyKTtcbiAgICB9KTtcbiAgICBiYWxhbmNlQWNjb3VudHMgPSBhd2FpdCBQcm9taXNlLmFsbChiYWxhbmNlRmluZE9uZU9wZXJzKTtcblxuICAgIGJhbGFuY2VzTGlzdC5mb3JFYWNoKChiYWxhbmNlKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2QgPSBiYWxhbmNlLmFtb3VudCA8IDAgPyAnZGVjcmVtZW50JyA6ICdpbmNyZW1lbnQnO1xuXG4gICAgICAvLyBEZXRhcm1pbmUgaWYgdGhlIGFjY291bnQgYmFsYW5jZSBpcyBhbHJlYWR5IGV4aXN0cyBvciBub3QuXG4gICAgICBjb25zdCBmb3VuZEFjY0JhbGFuY2UgPSBiYWxhbmNlQWNjb3VudHMuc29tZSgoYWNjb3VudCkgPT4gKFxuICAgICAgICBhY2NvdW50ICYmIGFjY291bnQuYWNjb3VudF9pZCA9PT0gYmFsYW5jZS5hY2NvdW50X2lkXG4gICAgICApKTtcbiAgICAgIGlmIChmb3VuZEFjY0JhbGFuY2UpIHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSBBY2NvdW50QmFsYW5jZVxuICAgICAgICAgIC5xdWVyeSgpW21ldGhvZF0oJ2Ftb3VudCcsIE1hdGguYWJzKGJhbGFuY2UuYW1vdW50KSlcbiAgICAgICAgICAud2hlcmUoJ2FjY291bnRfaWQnLCBiYWxhbmNlLmFjY291bnRfaWQpO1xuXG4gICAgICAgIGJhbGFuY2VVcGRhdGVPcGVycy5wdXNoKHF1ZXJ5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gQWNjb3VudEJhbGFuY2UucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAgIGFjY291bnRfaWQ6IGJhbGFuY2UuYWNjb3VudF9pZCxcbiAgICAgICAgICBhbW91bnQ6IGJhbGFuY2UuYW1vdW50LFxuICAgICAgICAgIGN1cnJlbmN5X2NvZGU6ICdVU0QnLFxuICAgICAgICB9KTtcbiAgICAgICAgYmFsYW5jZUluc2VydE9wZXJzLnB1c2gocXVlcnkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIC4uLmJhbGFuY2VVcGRhdGVPcGVycywgLi4uYmFsYW5jZUluc2VydE9wZXJzLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBzdGFja2VkIGpvdXJuYWwgZW50cmllcyB0byB0aGUgc3RvcmFnZS5cbiAgICovXG4gIGFzeW5jIHNhdmVFbnRyaWVzKCkge1xuICAgIGNvbnN0IHNhdmVPcGVyYXRpb25zID0gW107XG5cbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IG9wZXIgPSBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICBhY2NvdW50SWQ6IGVudHJ5LmFjY291bnQsXG4gICAgICAgIC4uLnBpY2soZW50cnksIFsnY3JlZGl0JywgJ2RlYml0JywgJ3RyYW5zYWN0aW9uVHlwZScsXG4gICAgICAgICAgJ3JlZmVyZW5jZVR5cGUnLCAncmVmZXJlbmNlSWQnLCAnbm90ZSddKSxcbiAgICAgIH0pO1xuICAgICAgc2F2ZU9wZXJhdGlvbnMucHVzaChvcGVyKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChzYXZlT3BlcmF0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogUmV2ZXJzZXMgdGhlIHN0YWNrZWQgam91cm5hbCBlbnRyaWVzLlxuICAgKi9cbiAgcmV2ZXJzZUVudHJpZXMoKSB7XG4gICAgY29uc3QgcmV2ZXJzZUVudHJpZXMgPSBbXTtcblxuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgY29uc3QgcmV2ZXJzZUVudHJ5ID0geyAuLi5lbnRyeSB9O1xuXG4gICAgICBpZiAoZW50cnkuY3JlZGl0KSB7XG4gICAgICAgIHJldmVyc2VFbnRyeS5kZWJpdCA9IGVudHJ5LmNyZWRpdDtcbiAgICAgIH1cbiAgICAgIGlmIChlbnRyeS5kZWJpdCkge1xuICAgICAgICByZXZlcnNlRW50cnkuY3JlZGl0ID0gZW50cnkuZGViaXQ7XG4gICAgICB9XG4gICAgICByZXZlcnNlRW50cmllcy5wdXNoKHJldmVyc2VFbnRyeSk7XG4gICAgfSk7XG4gICAgdGhpcy5lbnRyaWVzID0gcmV2ZXJzZUVudHJpZXM7XG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlbiBvciBhbGwgc3RhY2tlZCBlbnRyaWVzLlxuICAgKiBAcGFyYW0ge0FycmF5fSBpZHMgLVxuICAgKi9cbiAgYXN5bmMgZGVsZXRlRW50cmllcyhpZHMpIHtcbiAgICBjb25zdCBlbnRyaWVzSWRzID0gaWRzIHx8IHRoaXMuZW50cmllcy5tYXAoKGUpID0+IGUuaWQpO1xuXG4gICAgaWYgKGVudHJpZXNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KCkud2hlcmVJbignaWQnLCBlbnRyaWVzSWRzKS5kZWxldGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGNsb3NpbmcgYmFsYW5jZSBmb3IgdGhlIGdpdmVuIGFjY291bnQgYW5kIGNsb3NpbmcgZGF0ZS5cbiAgICogQHBhcmFtIHtOdW1iZXJ9IGFjY291bnRJZCAtXG4gICAqIEBwYXJhbSB7RGF0ZX0gY2xvc2luZ0RhdGUgLVxuICAgKi9cbiAgZ2V0Q2xvc2luZ0JhbGFuY2UoYWNjb3VudElkLCBjbG9zaW5nRGF0ZSwgZGF0ZVR5cGUgPSAnZGF5Jykge1xuICAgIGxldCBjbG9zaW5nQmFsYW5jZSA9IDA7XG4gICAgY29uc3QgbW9tZW50Q2xvc2luZ0RhdGUgPSBtb21lbnQoY2xvc2luZ0RhdGUpO1xuXG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAvLyBDYW4gbm90IGNvbnRpbnVlIGlmIG5vdCBiZWZvcmUgb3IgZXZlbnQgc2FtZSBjbG9zaW5nIGRhdGUuXG4gICAgICBpZiAoKCFtb21lbnRDbG9zaW5nRGF0ZS5pc0FmdGVyKGVudHJ5LmRhdGUsIGRhdGVUeXBlKVxuICAgICAgICAmJiAhbW9tZW50Q2xvc2luZ0RhdGUuaXNTYW1lKGVudHJ5LmRhdGUsIGRhdGVUeXBlKSlcbiAgICAgICAgfHwgKGVudHJ5LmFjY291bnQgIT09IGFjY291bnRJZCAmJiBhY2NvdW50SWQpKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnY3JlZGl0Jykge1xuICAgICAgICBjbG9zaW5nQmFsYW5jZSArPSAoZW50cnkuY3JlZGl0KSA/IGVudHJ5LmNyZWRpdCA6IC0xICogZW50cnkuZGViaXQ7XG4gICAgICB9IGVsc2UgaWYgKGVudHJ5LmFjY291bnROb3JtYWwgPT09ICdkZWJpdCcpIHtcbiAgICAgICAgY2xvc2luZ0JhbGFuY2UgKz0gKGVudHJ5LmRlYml0KSA/IGVudHJ5LmRlYml0IDogLTEgKiBlbnRyeS5jcmVkaXQ7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGNsb3NpbmdCYWxhbmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHRoZSBjcmVkaXQvZGViaXQgc3VtYXRpb24gZm9yIHRoZSBnaXZlbiBhY2NvdW50IGFuZCBkYXRlLlxuICAgKiBAcGFyYW0ge051bWJlcn0gYWNjb3VudCAtXG4gICAqIEBwYXJhbSB7RGF0ZXxTdHJpbmd9IGNsb3NpbmdEYXRlIC1cbiAgICovXG4gIGdldFRyaWFsQmFsYW5jZShhY2NvdW50SWQsIGNsb3NpbmdEYXRlLCBkYXRlVHlwZSkge1xuICAgIGNvbnN0IG1vbWVudENsb3NpbmdEYXRlID0gbW9tZW50KGNsb3NpbmdEYXRlKTtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICBjcmVkaXQ6IDAsXG4gICAgICBkZWJpdDogMCxcbiAgICAgIGJhbGFuY2U6IDAsXG4gICAgfTtcbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIGlmICgoIW1vbWVudENsb3NpbmdEYXRlLmlzQWZ0ZXIoZW50cnkuZGF0ZSwgZGF0ZVR5cGUpXG4gICAgICAgICYmICFtb21lbnRDbG9zaW5nRGF0ZS5pc1NhbWUoZW50cnkuZGF0ZSwgZGF0ZVR5cGUpKVxuICAgICAgICB8fCAoZW50cnkuYWNjb3VudCAhPT0gYWNjb3VudElkICYmIGFjY291bnRJZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmVzdWx0LmNyZWRpdCArPSBlbnRyeS5jcmVkaXQ7XG4gICAgICByZXN1bHQuZGViaXQgKz0gZW50cnkuZGViaXQ7XG5cbiAgICAgIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnY3JlZGl0Jykge1xuICAgICAgICByZXN1bHQuYmFsYW5jZSArPSAoZW50cnkuY3JlZGl0KSA/IGVudHJ5LmNyZWRpdCA6IC0xICogZW50cnkuZGViaXQ7XG4gICAgICB9IGVsc2UgaWYgKGVudHJ5LmFjY291bnROb3JtYWwgPT09ICdkZWJpdCcpIHtcbiAgICAgICAgcmVzdWx0LmJhbGFuY2UgKz0gKGVudHJ5LmRlYml0KSA/IGVudHJ5LmRlYml0IDogLTEgKiBlbnRyeS5jcmVkaXQ7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIGZldGNoZWQgYWNjb3VudHMgam91cm5hbCBlbnRyaWVzLlxuICAgKiBAcGFyYW0ge0FycmF5fSBlbnRyaWVzIC1cbiAgICovXG4gIGxvYWRFbnRyaWVzKGVudHJpZXMpIHtcbiAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICB0aGlzLmVudHJpZXMucHVzaCh7XG4gICAgICAgIC4uLmVudHJ5LFxuICAgICAgICBhY2NvdW50OiBlbnRyeS5hY2NvdW50ID8gZW50cnkuYWNjb3VudC5pZCA6IGVudHJ5LmFjY291bnRJZCxcbiAgICAgICAgYWNjb3VudE5vcm1hbDogKGVudHJ5LmFjY291bnQgJiYgZW50cnkuYWNjb3VudC50eXBlKVxuICAgICAgICAgID8gZW50cnkuYWNjb3VudC50eXBlLm5vcm1hbCA6IGVudHJ5LmFjY291bnROb3JtYWwsXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHN0YXRpYyBsb2FkQWNjb3VudHMoKSB7XG5cbiAgfVxufVxuIiwiaW1wb3J0IFJlc291cmNlIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlJztcbmltcG9ydCBSZXNvdXJjZUZpZWxkIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlRmllbGQnO1xuaW1wb3J0IFJlc291cmNlRmllbGRNZXRhZGF0YSBmcm9tICdAL21vZGVscy9SZXNvdXJjZUZpZWxkTWV0YWRhdGEnO1xuaW1wb3J0IFJlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24gZnJvbSAnQC9jb2xsZWN0aW9uL1Jlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXNvdXJjZUN1c3RvbUZpZWxkUmVwb3NpdG9yeSB7XG4gIC8qKlxuICAgKiBDbGFzcyBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG1vZGVsKSB7XG4gICAgaWYgKHR5cGVvZiBtb2RlbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgdGhpcy5yZXNvdXJjZU5hbWUgPSBtb2RlbC5uYW1lO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1vZGVsID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5yZXNvdXJjZU5hbWUgPSBtb2RlbDtcbiAgICB9XG4gICAgLy8gQ3VzdG9tIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAgdGhpcy5jdXN0b21GaWVsZHMgPSBbXTtcbiAgICB0aGlzLmZpbGxlZEN1c3RvbUZpZWxkcyA9IHt9O1xuXG4gICAgLy8gbWV0YWRhdGEgb2YgY3VzdG9tIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAgdGhpcy5maWVsZHNNZXRhZGF0YSA9IHt9O1xuICAgIHRoaXMucmVzb3VyY2UgPSB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIG1ldGFkYXRhIG9mIGN1c3RvbSBmaWVsZHMgb2YgdGhlIGdpdmVuIHJlc291cmNlLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gUmVzb3VyY2UgaXRlbSBpZC5cbiAgICovXG4gIGFzeW5jIGZldGNoQ3VzdG9tRmllbGRzTWV0YWRhdGEoaWQpIHtcbiAgICBpZiAodHlwZW9mIGlkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQbGVhc2UgZGVmaW5lIHRoZSByZXNvdXJjZSBpdGVtIGlkLicpO1xuICAgIH1cbiAgICBpZiAoIXRoaXMucmVzb3VyY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGFyZ2V0IHJlc291cmNlIG1vZGVsIGlzIG5vdCBmb3VuZC4nKTtcbiAgICB9XG4gICAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCBSZXNvdXJjZUZpZWxkTWV0YWRhdGEucXVlcnkoKVxuICAgICAgLndoZXJlKCdyZXNvdXJjZV9pZCcsIHRoaXMucmVzb3VyY2UuaWQpXG4gICAgICAud2hlcmUoJ3Jlc291cmNlX2l0ZW1faWQnLCBpZCk7XG5cbiAgICB0aGlzLmZpZWxkc01ldGFkYXRhW2lkXSA9IG1ldGFkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgcmVzb3VyY2UuXG4gICAqL1xuICBhc3luYyBsb2FkUmVzb3VyY2UoKSB7XG4gICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpLndoZXJlKCduYW1lJywgdGhpcy5yZXNvdXJjZU5hbWUpLmZpcnN0KCk7XG5cbiAgICBpZiAoIXJlc291cmNlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHN0b3JlZCByZXNvdXJjZSBpbiB0aGUgc3RvcmFnZSB3aXRoIHRoZSBnaXZlbiBtb2RlbCBuYW1lLicpO1xuICAgIH1cbiAgICB0aGlzLnNldFJlc291cmNlKHJlc291cmNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIG1ldGFkYXRhIG9mIHRoZSByZXNvdXJjZS5cbiAgICovXG4gIGFzeW5jIGxvYWRSZXNvdXJjZUN1c3RvbUZpZWxkcygpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMucmVzb3VyY2UuaWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBmZXRjaCByZXNvdXJjZSBkZXRhaWxzIGJlZm9yZSBmZXRjaCBjdXN0b20gZmllbGRzIG9mIHRoZSByZXNvdXJjZS4nKTtcbiAgICB9XG4gICAgY29uc3QgY3VzdG9tRmllbGRzID0gYXdhaXQgUmVzb3VyY2VGaWVsZC5xdWVyeSgpXG4gICAgICAud2hlcmUoJ3Jlc291cmNlX2lkJywgdGhpcy5yZXNvdXJjZS5pZClcbiAgICAgIC5tb2RpZnkoJ3doZXJlTm90UHJlZGVmaW5lZCcpO1xuXG4gICAgdGhpcy5zZXRSZXNvdXJjZUN1c3RvbUZpZWxkcyhjdXN0b21GaWVsZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcmVzb3VyY2UgbW9kZWwuXG4gICAqIEBwYXJhbSB7UmVzb3VyY2V9IHJlc291cmNlIC1cbiAgICovXG4gIHNldFJlc291cmNlKHJlc291cmNlKSB7XG4gICAgdGhpcy5yZXNvdXJjZSA9IHJlc291cmNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgcmVzb3VyY2UgY3VzdG9tIGZpZWxkcyBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge0FycmF5fSBjdXN0b21GaWVsZHMgLVxuICAgKi9cbiAgc2V0UmVzb3VyY2VDdXN0b21GaWVsZHMoY3VzdG9tRmllbGRzKSB7XG4gICAgdGhpcy5jdXN0b21GaWVsZHMgPSBjdXN0b21GaWVsZHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgbWV0YWRhdGEgb2YgdGhlIHJlc291cmNlIGN1c3RvbSBmaWVsZHMuXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaXRlbUlkIC1cbiAgICovXG4gIGdldE1ldGFkYXRhKGl0ZW1JZCkge1xuICAgIHJldHVybiB0aGlzLmZpZWxkc01ldGFkYXRhW2l0ZW1JZF0gfHwgdGhpcy5maWVsZHNNZXRhZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWxsIG1ldGFkYXRhIG9mIHRoZSBjdXN0b20gZmllbGRzIHRoYXQgYXNzb2NpYXRlZCB0byB0aGUgcmVzb3VyY2UuXG4gICAqIEBwYXJhbSB7SW50ZXJ9IGlkIC0gUmVzb3VyY2UgaXRlbSBpZC5cbiAgICogQHBhcmFtIHtBcnJheX0gYXR0cmlidXRlcyAtXG4gICAqL1xuICBmaWxsQ3VzdG9tRmllbGRzKGlkLCBhdHRyaWJ1dGVzKSB7XG4gICAgaWYgKHR5cGVvZiB0aGlzLmZpbGxlZEN1c3RvbUZpZWxkc1tpZF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLmZpbGxlZEN1c3RvbUZpZWxkc1tpZF0gPSBbXTtcbiAgICB9XG4gICAgYXR0cmlidXRlcy5mb3JFYWNoKChhdHRyKSA9PiB7XG4gICAgICB0aGlzLmZpbGxlZEN1c3RvbUZpZWxkc1tpZF0ucHVzaChhdHRyKTtcblxuICAgICAgaWYgKCF0aGlzLmZpZWxkc01ldGFkYXRhW2lkXSkge1xuICAgICAgICB0aGlzLmZpZWxkc01ldGFkYXRhW2lkXSA9IG5ldyBSZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmZpZWxkc01ldGFkYXRhW2lkXS5zZXRNZXRhKGF0dHIua2V5LCBhdHRyLnZhbHVlLCB7XG4gICAgICAgIHJlc291cmNlX2lkOiB0aGlzLnJlc291cmNlLmlkLFxuICAgICAgICByZXNvdXJjZV9pdGVtX2lkOiBpZCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBpbnN0ZXJlZCwgdXBkYXRlZCBhbmQgZGVsZXRlZCAgY3VzdG9tIGZpZWxkcyBtZXRhZGF0YS5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpZCAtIE9wdGlvbmFsIHJlc291cmNlIGl0ZW0gaWQuXG4gICAqL1xuICBhc3luYyBzYXZlQ3VzdG9tRmllbGRzKGlkKSB7XG4gICAgaWYgKGlkKSB7XG4gICAgICBpZiAodHlwZW9mIHRoaXMuZmllbGRzTWV0YWRhdGFbaWRdID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RoZXJlIGlzIG5vIHJlc291cmNlIGl0ZW0gd2l0aCB0aGUgZ2l2ZW4gaWQuJyk7XG4gICAgICB9XG4gICAgICBhd2FpdCB0aGlzLmZpZWxkc01ldGFkYXRhW2lkXS5zYXZlTWV0YSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBvcGVycyA9IFtdO1xuICAgICAgdGhpcy5maWVsZHNNZXRhZGF0YS5mb3JFYWNoKChtZXRhZGF0YSkgPT4ge1xuICAgICAgICBjb25zdCBvcGVyID0gbWV0YWRhdGEuc2F2ZU1ldGEoKTtcbiAgICAgICAgb3BlcnMucHVzaChvcGVyKTtcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwob3BlcnMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgdGhlIGV4aXN0IGN1c3RvbSBmaWVsZHMuXG4gICAqL1xuICB2YWxpZGF0ZUV4aXN0Q3VzdG9tRmllbGRzKCkge1xuXG4gIH1cblxuICB0b0FycmF5KCkge1xuICAgIHJldHVybiB0aGlzLmZpZWxkc01ldGFkYXRhLnRvQXJyYXkoKTtcbiAgfVxuXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgYXdhaXQgdGhpcy5sb2FkUmVzb3VyY2UoKTtcbiAgICBhd2FpdCB0aGlzLmxvYWRSZXNvdXJjZUN1c3RvbUZpZWxkcygpO1xuICB9XG5cbiAgc3RhdGljIGZvcmdlTWV0YWRhdGFDb2xsZWN0aW9uKCkge1xuXG4gIH1cbn1cbiIsImltcG9ydCBNb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IGV4dGVuZE1vbWVudCB9IGZyb20gJ21vbWVudC1yYW5nZSc7XG5cbmNvbnN0IG1vbWVudCA9IGV4dGVuZE1vbWVudChNb21lbnQpO1xuXG5leHBvcnQgZGVmYXVsdCBtb21lbnQ7XG4iLCJpbXBvcnQgbm9kZW1haWxlciBmcm9tICdub2RlbWFpbGVyJztcblxuLy8gY3JlYXRlIHJldXNhYmxlIHRyYW5zcG9ydGVyIG9iamVjdCB1c2luZyB0aGUgZGVmYXVsdCBTTVRQIHRyYW5zcG9ydFxuY29uc3QgdHJhbnNwb3J0ZXIgPSBub2RlbWFpbGVyLmNyZWF0ZVRyYW5zcG9ydCh7XG4gIGhvc3Q6IHByb2Nlc3MuZW52Lk1BSUxfSE9TVCxcbiAgcG9ydDogTnVtYmVyKHByb2Nlc3MuZW52Lk1BSUxfUE9SVCksXG4gIHNlY3VyZTogcHJvY2Vzcy5lbnYuTUFJTF9TRUNVUkUgPT09ICd0cnVlJywgLy8gdHJ1ZSBmb3IgNDY1LCBmYWxzZSBmb3Igb3RoZXIgcG9ydHNcbiAgYXV0aDoge1xuICAgIHVzZXI6IHByb2Nlc3MuZW52Lk1BSUxfVVNFUk5BTUUsXG4gICAgcGFzczogcHJvY2Vzcy5lbnYuTUFJTF9QQVNTV09SRCxcbiAgfSxcbn0pO1xuXG5leHBvcnQgZGVmYXVsdCB0cmFuc3BvcnRlcjtcbiIsImltcG9ydCBiY3J5cHQgZnJvbSAnYmNyeXB0anMnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmNvbnN0IHsgbWFwLCBpc0FycmF5LCBpc1BsYWluT2JqZWN0LCBtYXBLZXlzLCBtYXBWYWx1ZXMgfSA9IHJlcXVpcmUoJ2xvZGFzaCcpXG5cblxuY29uc3QgaGFzaFBhc3N3b3JkID0gKHBhc3N3b3JkKSA9PiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4ge1xuICBiY3J5cHQuZ2VuU2FsdCgxMCwgKGVycm9yLCBzYWx0KSA9PiB7XG4gICAgYmNyeXB0Lmhhc2gocGFzc3dvcmQsIHNhbHQsIChlcnIsIGhhc2gpID0+IHsgcmVzb2x2ZShoYXNoKTsgfSk7XG4gIH0pO1xufSk7XG5cbmNvbnN0IG9yaWdpbiA9IChyZXF1ZXN0KSA9PiBgJHtyZXF1ZXN0LnByb3RvY29sfTovLyR7cmVxdWVzdC5ob3N0bmFtZX1gO1xuXG5jb25zdCBkYXRlUmFuZ2VDb2xsZWN0aW9uID0gKGZyb21EYXRlLCB0b0RhdGUsIGFkZFR5cGUgPSAnZGF5JywgaW5jcmVtZW50ID0gMSkgPT4ge1xuICBjb25zdCBjb2xsZWN0aW9uID0gW107XG4gIGNvbnN0IG1vbWVudEZyb21EYXRlID0gbW9tZW50KGZyb21EYXRlKTtcbiAgbGV0IGRhdGVGb3JtYXQgPSAnJztcblxuICBzd2l0Y2ggKGFkZFR5cGUpIHtcbiAgICBjYXNlICdkYXknOlxuICAgIGRlZmF1bHQ6XG4gICAgICBkYXRlRm9ybWF0ID0gJ1lZWVktTU0tREQnOyBicmVhaztcbiAgICBjYXNlICdtb250aCc6XG4gICAgY2FzZSAncXVhcnRlcic6XG4gICAgICBkYXRlRm9ybWF0ID0gJ1lZWVktTU0nOyBicmVhaztcbiAgICBjYXNlICd5ZWFyJzpcbiAgICAgIGRhdGVGb3JtYXQgPSAnWVlZWSc7IGJyZWFrO1xuICB9XG4gIGZvciAobGV0IGkgPSBtb21lbnRGcm9tRGF0ZTtcbiAgICAoaS5pc0JlZm9yZSh0b0RhdGUsIGFkZFR5cGUpIHx8IGkuaXNTYW1lKHRvRGF0ZSwgYWRkVHlwZSkpO1xuICAgIGkuYWRkKGluY3JlbWVudCwgYCR7YWRkVHlwZX1zYCkpIHtcbiAgICBjb2xsZWN0aW9uLnB1c2goaS5lbmRPZihhZGRUeXBlKS5mb3JtYXQoZGF0ZUZvcm1hdCkpO1xuICB9XG4gIHJldHVybiBjb2xsZWN0aW9uO1xufTtcblxuY29uc3QgZGF0ZVJhbmdlRm9ybWF0ID0gKHJhbmdlVHlwZSkgPT4ge1xuICBzd2l0Y2ggKHJhbmdlVHlwZSkge1xuICAgIGNhc2UgJ3llYXInOlxuICAgICAgcmV0dXJuICdZWVlZJztcbiAgICBjYXNlICdtb250aCc6XG4gICAgY2FzZSAncXVhcnRlcic6XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiAnWVlZWS1NTSc7XG4gIH1cbn07XG5cblxuY29uc3QgbWFwS2V5c0RlZXAgPSAob2JqLCBjYikgPT4ge1xuICBpZiAoXy5pc0FycmF5KG9iaikpIHtcbiAgICAgIHJldHVybiBvYmoubWFwKGlubmVyT2JqID0+IG1hcEtleXNEZWVwKGlubmVyT2JqLCBjYikpO1xuICB9XG4gIGVsc2UgaWYgKF8uaXNPYmplY3Qob2JqKSkge1xuICAgICAgcmV0dXJuIF8ubWFwVmFsdWVzKFxuICAgICAgICAgIF8ubWFwS2V5cyhvYmosIGNiKSxcbiAgICAgICAgICB2YWwgPT4gbWFwS2V5c0RlZXAodmFsLCBjYiksXG4gICAgICApXG4gIH0gZWxzZSB7XG4gICAgICByZXR1cm4gb2JqO1xuICB9XG59XG5cbmNvbnN0IG1hcFZhbHVlc0RlZXAgPSAodiwgY2FsbGJhY2spID0+IChcbiAgXy5pc09iamVjdCh2KVxuICAgID8gXy5tYXBWYWx1ZXModiwgdiA9PiBtYXBWYWx1ZXNEZWVwKHYsIGNhbGxiYWNrKSlcbiAgICA6IGNhbGxiYWNrKHYpKTtcblxuZXhwb3J0IHtcbiAgaGFzaFBhc3N3b3JkLFxuICBvcmlnaW4sXG4gIGRhdGVSYW5nZUNvbGxlY3Rpb24sXG4gIGRhdGVSYW5nZUZvcm1hdCxcbiAgbWFwVmFsdWVzRGVlcCxcbiAgbWFwS2V5c0RlZXAsXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3BsdWdpbi10cmFuc2Zvcm0tcnVudGltZVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2FzeW5jVG9HZW5lcmF0b3JcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jbGFzc0NhbGxDaGVja1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2NyZWF0ZUNsYXNzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZGVmaW5lUHJvcGVydHlcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9nZXRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9nZXRQcm90b3R5cGVPZlwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2luaGVyaXRzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvcG9zc2libGVDb25zdHJ1Y3RvclJldHVyblwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3NsaWNlZFRvQXJyYXlcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy90b0NvbnN1bWFibGVBcnJheVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9yZWdlbmVyYXRvclwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJiY3J5cHRqc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJkb3RlbnZcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXJyb3JoYW5kbGVyXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3NcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZXhwcmVzcy1ib29tXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3MtdmFsaWRhdG9yXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImZzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImhlbG1ldFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJqc29ud2VidG9rZW5cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwia25leFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwibW9tZW50XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm1vbWVudC1yYW5nZVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJtdXN0YWNoZVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJub2RlbWFpbGVyXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm9iamVjdGlvblwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXRoXCIpOyJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNsRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2hEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDeEVBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQzNFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7O0FDWEE7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ1ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDL0lBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQzdCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFqRkE7QUFtRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3JOQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBbkJBO0FBQ0E7QUFDQTtBQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDaE1BO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNsUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUE3RUE7QUErRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFUQTs7Ozs7Ozs7Ozs7O0FDNUdBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDWkE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFoREE7QUFrREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBN0RBO0FBQ0E7QUErREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdkZBO0FBeUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDdGZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUN0T0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2pnQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3BMQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFuQ0E7QUFxQ0E7QUFDQTtBQUNBO0FBdkNBO0FBeUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQzlRQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3RFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUN6RkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaElBO0FBQ0E7QUFDQTtBQUNBO0FBa0lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3ZWQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ1JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMvT0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3ZRQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDcERBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNmQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBREE7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBM0JBO0FBK0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQTlFQTtBQW1GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBdkZBO0FBNEZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF0R0E7QUF3R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQWxIQTtBQW9IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaklBO0FBbUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDM0tBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDN0pBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEwQkE7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBcEVBO0FBd0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDalBBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7OztBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3hGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQXpFQTs7QUFPQTs7QUFnQkE7O0FBU0E7O0FBWUE7O0FBWUE7Ozs7Ozs7Ozs7OztBQ2xFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQy9FQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMvQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQXBEQTs7QUFXQTs7Ozs7Ozs7Ozs7O0FDakJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQzVGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3pDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDN0JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3pCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBZkE7QUFrQkE7QUFDQTs7Ozs7Ozs7Ozs7O0FDM0JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXBCQTtBQXNCQTs7Ozs7Ozs7Ozs7OztBQ3ZDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNwRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUEzQ0E7O0FBR0E7O0FBV0E7O0FBV0E7O0FBT0E7O0FBbUJBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ2xFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7OztBQ3JDQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3pGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUE1Q0E7O0FBT0E7O0FBT0E7Ozs7Ozs7Ozs7OztBQ3RCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDekRBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDZkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDaEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ05BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQy9PQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDeEpBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ25FQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7Ozs7Ozs7Ozs7QUNBQTs7OztBIiwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVuZGxlLmpzIiwic291cmNlcyI6WyJ3ZWJwYWNrL2Jvb3RzdHJhcCIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9jb25maWcvaW5kZXguanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIva25leGZpbGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2FwcC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvY29sbGVjdGlvbi9CdWRnZXRFbnRyaWVzU2V0LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9jb2xsZWN0aW9uL05lc3RlZFNldC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvY29sbGVjdGlvbi9SZXNvdXJjZUZpZWxkTWV0YWRhdGFDb2xsZWN0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9kYXRhL1Jlc291cmNlRmllbGRzS2V5cy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvZGF0YWJhc2Uva25leC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9BY2NvdW50T3BlbmluZ0JhbGFuY2UuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudFR5cGVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRpbmcuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQXV0aGVudGljYXRpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQmlsbHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQnVkZ2V0LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0J1ZGdldFJlcG9ydHMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQ3VycmVuY2llcy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9DdXJyZW5jeUFkanVzdG1lbnQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvQ3VzdG9tZXJzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0V4cGVuc2VzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0ZpZWxkcy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9GaW5hbmNpYWxTdGF0ZW1lbnRzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0l0ZW1DYXRlZ29yaWVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL0l0ZW1zLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL09wdGlvbnMuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvY29udHJvbGxlcnMvUmVzb3VyY2VzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL1JvbGVzLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9odHRwL2NvbnRyb2xsZXJzL1N1cHBsaWVycy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9Vc2Vycy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9jb250cm9sbGVycy9WaWV3cy5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvaHR0cC9taWRkbGV3YXJlL2F1dGhvcml6YXRpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9saWIvTG9naWNFdmFsdWF0aW9uL0xleGVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9saWIvTG9naWNFdmFsdWF0aW9uL1BhcnNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbGliL0xvZ2ljRXZhbHVhdGlvbi9RdWVyeVBhcnNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbGliL01ldGFibGUvTWV0YWJsZUNvbGxlY3Rpb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL2xpYi9WaWV3Um9sZXNCdWlsZGVyL2luZGV4LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL0FjY291bnRCYWxhbmNlLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvQWNjb3VudFR5cGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9CdWRnZXQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9CdWRnZXRFbnRyeS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL0V4cGVuc2UuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9JdGVtLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvSXRlbUNhdGVnb3J5LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvSm91cm5hbEVudHJ5LmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvTWFudWFsSm91cm5hbC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL01vZGVsLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvT3B0aW9uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvUGFzc3dvcmRSZXNldC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1Blcm1pc3Npb24uanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9SZXNvdXJjZS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1Jlc291cmNlRmllbGQuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9SZXNvdXJjZUZpZWxkTWV0YWRhdGEuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9Sb2xlLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvVXNlci5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvbW9kZWxzL1ZpZXcuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9WaWV3Q29sdW1uLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9tb2RlbHMvVmlld1JvbGUuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL21vZGVscy9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxFbnRyeS5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsUG9zdGVyLmpzIiwiL1VzZXJzL2FobWVkL0RvY3VtZW50cy9SYXR0ZWIvc2VydmVyL3NyYy9zZXJ2aWNlcy9DdXN0b21GaWVsZHMvUmVzb3VyY2VDdXN0b21GaWVsZFJlcG9zaXRvcnkuanMiLCIvVXNlcnMvYWhtZWQvRG9jdW1lbnRzL1JhdHRlYi9zZXJ2ZXIvc3JjL3NlcnZpY2VzL01vbWVudC9pbmRleC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvc2VydmljZXMvbWFpbC5qcyIsIi9Vc2Vycy9haG1lZC9Eb2N1bWVudHMvUmF0dGViL3NlcnZlci9zcmMvdXRpbHMvaW5kZXguanMiLCJleHRlcm5hbCBcIkBiYWJlbC9wbHVnaW4tdHJhbnNmb3JtLXJ1bnRpbWVcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzc1wiIiwiZXh0ZXJuYWwgXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2ZcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0c1wiIiwiZXh0ZXJuYWwgXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIiLCJleHRlcm5hbCBcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXlcIiIsImV4dGVybmFsIFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIiIsImV4dGVybmFsIFwiYmNyeXB0anNcIiIsImV4dGVybmFsIFwiZG90ZW52XCIiLCJleHRlcm5hbCBcImVycm9yaGFuZGxlclwiIiwiZXh0ZXJuYWwgXCJleHByZXNzXCIiLCJleHRlcm5hbCBcImV4cHJlc3MtYm9vbVwiIiwiZXh0ZXJuYWwgXCJleHByZXNzLXZhbGlkYXRvclwiIiwiZXh0ZXJuYWwgXCJmc1wiIiwiZXh0ZXJuYWwgXCJoZWxtZXRcIiIsImV4dGVybmFsIFwiaTE4blwiIiwiZXh0ZXJuYWwgXCJqc29ud2VidG9rZW5cIiIsImV4dGVybmFsIFwia25leFwiIiwiZXh0ZXJuYWwgXCJsb2Rhc2hcIiIsImV4dGVybmFsIFwibW9tZW50XCIiLCJleHRlcm5hbCBcIm1vbWVudC1yYW5nZVwiIiwiZXh0ZXJuYWwgXCJtdXN0YWNoZVwiIiwiZXh0ZXJuYWwgXCJub2RlbWFpbGVyXCIiLCJleHRlcm5hbCBcIm9iamVjdGlvblwiIiwiZXh0ZXJuYWwgXCJwYXRoXCIiXSwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7IGVudW1lcmFibGU6IHRydWUsIGdldDogZ2V0dGVyIH0pO1xuIFx0XHR9XG4gXHR9O1xuXG4gXHQvLyBkZWZpbmUgX19lc01vZHVsZSBvbiBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIgPSBmdW5jdGlvbihleHBvcnRzKSB7XG4gXHRcdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuIFx0XHR9XG4gXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG4gXHR9O1xuXG4gXHQvLyBjcmVhdGUgYSBmYWtlIG5hbWVzcGFjZSBvYmplY3RcbiBcdC8vIG1vZGUgJiAxOiB2YWx1ZSBpcyBhIG1vZHVsZSBpZCwgcmVxdWlyZSBpdFxuIFx0Ly8gbW9kZSAmIDI6IG1lcmdlIGFsbCBwcm9wZXJ0aWVzIG9mIHZhbHVlIGludG8gdGhlIG5zXG4gXHQvLyBtb2RlICYgNDogcmV0dXJuIHZhbHVlIHdoZW4gYWxyZWFkeSBucyBvYmplY3RcbiBcdC8vIG1vZGUgJiA4fDE6IGJlaGF2ZSBsaWtlIHJlcXVpcmVcbiBcdF9fd2VicGFja19yZXF1aXJlX18udCA9IGZ1bmN0aW9uKHZhbHVlLCBtb2RlKSB7XG4gXHRcdGlmKG1vZGUgJiAxKSB2YWx1ZSA9IF9fd2VicGFja19yZXF1aXJlX18odmFsdWUpO1xuIFx0XHRpZihtb2RlICYgOCkgcmV0dXJuIHZhbHVlO1xuIFx0XHRpZigobW9kZSAmIDQpICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgdmFsdWUuX19lc01vZHVsZSkgcmV0dXJuIHZhbHVlO1xuIFx0XHR2YXIgbnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLnIobnMpO1xuIFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkobnMsICdkZWZhdWx0JywgeyBlbnVtZXJhYmxlOiB0cnVlLCB2YWx1ZTogdmFsdWUgfSk7XG4gXHRcdGlmKG1vZGUgJiAyICYmIHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgZm9yKHZhciBrZXkgaW4gdmFsdWUpIF9fd2VicGFja19yZXF1aXJlX18uZChucywga2V5LCBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHZhbHVlW2tleV07IH0uYmluZChudWxsLCBrZXkpKTtcbiBcdFx0cmV0dXJuIG5zO1xuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJkaXN0L1wiO1xuXG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMCk7XG4iLCJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBkb3RlbnYgZnJvbSAnZG90ZW52JztcblxuZG90ZW52LmNvbmZpZyh7XG4gIHBhdGg6IHBhdGgucmVzb2x2ZShwcm9jZXNzLmN3ZCgpLCAnLmVudi50ZXN0JyksXG59KTtcbiIsInJlcXVpcmUoJ2RvdGVudicpLmNvbmZpZygpO1xuXG5jb25zdCBNSUdSQVRJT05TX0RJUiA9ICcuL3NyYy9kYXRhYmFzZS9taWdyYXRpb25zJztcbmNvbnN0IFNFRURTX0RJUiA9ICcuL3NyYy9kYXRhYmFzZS9zZWVkcyc7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICB0ZXN0OiB7XG4gICAgY2xpZW50OiBwcm9jZXNzLmVudi5EQl9DTElFTlQsXG4gICAgbWlncmF0aW9uczoge1xuICAgICAgZGlyZWN0b3J5OiBNSUdSQVRJT05TX0RJUixcbiAgICB9LFxuICAgIGNvbm5lY3Rpb246IHtcbiAgICAgIGhvc3Q6IHByb2Nlc3MuZW52LkRCX0hPU1QsXG4gICAgICB1c2VyOiBwcm9jZXNzLmVudi5EQl9VU0VSLFxuICAgICAgcGFzc3dvcmQ6IHByb2Nlc3MuZW52LkRCX1BBU1NXT1JELFxuICAgICAgZGF0YWJhc2U6IHByb2Nlc3MuZW52LkRCX05BTUUsXG4gICAgICBjaGFyc2V0OiAndXRmOCcsXG4gICAgfSxcbiAgfSxcbiAgZGV2ZWxvcG1lbnQ6IHtcbiAgICBjbGllbnQ6IHByb2Nlc3MuZW52LkRCX0NMSUVOVCxcbiAgICBjb25uZWN0aW9uOiB7XG4gICAgICBob3N0OiBwcm9jZXNzLmVudi5EQl9IT1NULFxuICAgICAgdXNlcjogcHJvY2Vzcy5lbnYuREJfVVNFUixcbiAgICAgIHBhc3N3b3JkOiBwcm9jZXNzLmVudi5EQl9QQVNTV09SRCxcbiAgICAgIGRhdGFiYXNlOiBwcm9jZXNzLmVudi5EQl9OQU1FLFxuICAgICAgY2hhcnNldDogJ3V0ZjgnLFxuICAgIH0sXG4gICAgbWlncmF0aW9uczoge1xuICAgICAgZGlyZWN0b3J5OiBNSUdSQVRJT05TX0RJUixcbiAgICB9LFxuICAgIHNlZWRzOiB7XG4gICAgICBkaXJlY3Rvcnk6IFNFRURTX0RJUixcbiAgICB9LFxuICB9LFxuICBwcm9kdWN0aW9uOiB7XG4gICAgY2xpZW50OiBwcm9jZXNzLmVudi5EQl9DTElFTlQsXG4gICAgY29ubmVjdGlvbjoge1xuICAgICAgaG9zdDogcHJvY2Vzcy5lbnYuREJfSE9TVCxcbiAgICAgIHVzZXI6IHByb2Nlc3MuZW52LkRCX1VTRVIsXG4gICAgICBwYXNzd29yZDogcHJvY2Vzcy5lbnYuREJfUEFTU1dPUkQsXG4gICAgICBkYXRhYmFzZTogcHJvY2Vzcy5lbnYuREJfTkFNRSxcbiAgICAgIGNoYXJzZXQ6ICd1dGY4JyxcbiAgICB9LFxuICAgIG1pZ3JhdGlvbnM6IHtcbiAgICAgIGRpcmVjdG9yeTogTUlHUkFUSU9OU19ESVIsXG4gICAgfSxcbiAgICBzZWVkczoge1xuICAgICAgZGlyZWN0b3J5OiBTRUVEU19ESVIsXG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCBoZWxtZXQgZnJvbSAnaGVsbWV0JztcbmltcG9ydCBib29tIGZyb20gJ2V4cHJlc3MtYm9vbSc7XG5pbXBvcnQgaTE4biBmcm9tICdpMThuJztcbmltcG9ydCAnLi4vY29uZmlnJztcbmltcG9ydCByb3V0ZXMgZnJvbSAnQC9odHRwJztcbmltcG9ydCAnQC9tb2RlbHMnO1xuXG5jb25zdCBhcHAgPSBleHByZXNzKCk7XG5cbi8vIGkxOG4uY29uZmlndXJlKHtcbi8vICAgLy8gc2V0dXAgc29tZSBsb2NhbGVzIC0gb3RoZXIgbG9jYWxlcyBkZWZhdWx0IHRvIGVuIHNpbGVudGx5XG4vLyAgIGxvY2FsZXM6IFsnZW4nXSxcblxuLy8gICAvLyBzZXRzIGEgY3VzdG9tIGNvb2tpZSBuYW1lIHRvIHBhcnNlIGxvY2FsZSBzZXR0aW5ncyBmcm9tLlxuLy8gICBjb29raWU6ICd5b3VyY29va2llbmFtZScsXG5cbi8vICAgLy8gd2hlcmUgdG8gc3RvcmUganNvbiBmaWxlcyAtIGRlZmF1bHRzIHRvICcuL2xvY2FsZXMnXG4vLyAgIGRpcmVjdG9yeTogYCR7X19kaXJuYW1lfS9yZXNvdXJjZXMvbG9jYWxlYCxcbi8vIH0pO1xuXG4vLyBpMThuIGluaXQgcGFyc2VzIHJlcSBmb3IgbGFuZ3VhZ2UgaGVhZGVycywgY29va2llcywgZXRjLlxuLy8gYXBwLnVzZShpMThuLmluaXQpO1xuXG4vLyBFeHByZXNzIGNvbmZpZ3VyYXRpb25cbmFwcC5zZXQoJ3BvcnQnLCBwcm9jZXNzLmVudi5QT1JUIHx8IDMwMDApO1xuXG5hcHAudXNlKGhlbG1ldCgpKTtcbmFwcC51c2UoYm9vbSgpKTtcbmFwcC51c2UoZXhwcmVzcy5qc29uKCkpO1xuXG5yb3V0ZXMoYXBwKTtcblxuZXhwb3J0IGRlZmF1bHQgYXBwO1xuIiwiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEJ1ZGdldEVudHJpZXNTZXQge1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuYWNjb3VudHMgPSB7fTsgXG4gICAgdGhpcy50b3RhbFN1bW1hcnkgPSB7fVxuICAgIHRoaXMub3JkZXJTaXplID0gbnVsbDtcbiAgfVxuXG4gIHNldFplcm9QbGFjZWhvbGRlcigpIHtcbiAgICBpZiAoIXRoaXMub3JkZXJTaXplKSB7IHJldHVybjsgfVxuXG4gICAgT2JqZWN0LnZhbHVlcyh0aGlzLmFjY291bnRzKS5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IHRoaXMub3JkZXJTaXplLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYWNjb3VudFtpXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgICBhY2NvdW50W2ldID0geyBhbW91bnQ6IDAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGZyb20oYWNjb3VudHMsIGNvbmZpZ3MpIHtcbiAgICBjb25zdCBjb2xsZWN0aW9uID0gbmV3IHRoaXMoY29uZmlncyk7XG5cbiAgICBhY2NvdW50cy5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLmFjY291bnRzW2VudHJ5LmFjY291bnRJZF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNvbGxlY3Rpb24uYWNjb3VudHNbZW50cnkuYWNjb3VudElkXSA9IHt9O1xuICAgICAgfVxuICAgICAgaWYgKGVudHJ5Lm9yZGVyKSB7XG4gICAgICAgIGNvbGxlY3Rpb24uYWNjb3VudHNbZW50cnkuYWNjb3VudElkXVtlbnRyeS5vcmRlcl0gPSBlbnRyeTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY29sbGVjdGlvbjtcbiAgfVxuXG4gIHRvQXJyYXkoKSB7XG4gICAgY29uc3Qgb3V0cHV0ID0gW107XG5cbiAgICBPYmplY3Qua2V5KHRoaXMuYWNjb3VudHMpLmZvckVhY2goKGFjY291bnRJZCkgPT4ge1xuICAgICAgY29uc3QgZW50cmllcyA9IHRoaXMuYWNjb3VudHNbYWNjb3VudElkXTtcbiAgICAgIG91dHB1dC5wdXNoKHtcbiAgICAgICAgYWNjb3VudF9pZDogYWNjb3VudElkLFxuICAgICAgICBlbnRyaWVzOiBbXG4gICAgICAgICAgLi4uT2JqZWN0LmtleShlbnRyaWVzKS5tYXAoKG9yZGVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBlbnRyeSA9IGVudHJpZXNbb3JkZXJdO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgb3JkZXIsXG4gICAgICAgICAgICAgIGFtb3VudDogZW50cnkuYW1vdW50LFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgY2FsY1RvdGFsU3VtbWFyeSgpIHtcbiAgICBjb25zdCB0b3RhbFN1bW1hcnkgPSB7fTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5vcmRlclNpemUubGVuZ3RoOyBpKyspIHtcbiAgICAgIE9iamVjdC52YWx1ZSh0aGlzLmFjY291bnRzKS5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdG90YWxTdW1tYXJ5W2ldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgIHRvdGFsU3VtbWFyeVtpXSA9IHsgYW1vdW50OiAwLCBvcmRlcjogaSB9O1xuICAgICAgICB9XG4gICAgICAgIHRvdGFsU3VtbWFyeVtpXS5hbW91bnQgKz0gYWNjb3VudFtpXS5hbW91bnQ7XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy50b3RhbFN1bW1hcnkgPSB0b3RhbFN1bW1hcnk7XG4gIH1cblxuICB0b0FycmF5VG90YWxTdW1tYXJ5KCkge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMudG90YWxTdW1tYXJ5KTtcbiAgfVxuXG59XG4iLCJcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE5lc3RlZFNldCB7XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RvciBtZXRob2QuXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC1cbiAgICovXG4gIGNvbnN0cnVjdG9yKGl0ZW1zLCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0ge1xuICAgICAgcGFyZW50SWQ6ICdwYXJlbnRfaWQnLFxuICAgICAgaWQ6ICdpZCcsXG4gICAgICAuLi5vcHRpb25zLFxuICAgIH07XG4gICAgdGhpcy5pdGVtcyA9IGl0ZW1zO1xuICAgIHRoaXMuY29sbGVjdGlvbiA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIExpbmsgbm9kZXMgY2hpbGRyZW4uXG4gICAqL1xuICBsaW5rQ2hpbGRyZW4oKSB7XG4gICAgaWYgKHRoaXMuaXRlbXMubGVuZ3RoIDw9IDApIHJldHVybiBmYWxzZTtcblxuICAgIGNvbnN0IG1hcCA9IHt9O1xuICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgbWFwW2l0ZW0uaWRdID0gaXRlbTtcbiAgICAgIG1hcFtpdGVtLmlkXS5jaGlsZHJlbiA9IFtdO1xuICAgIH0pO1xuXG4gICAgdGhpcy5pdGVtcy5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICBjb25zdCBwYXJlbnROb2RlSWQgPSBpdGVtW3RoaXMub3B0aW9ucy5wYXJlbnRJZF07XG4gICAgICBpZiAocGFyZW50Tm9kZUlkKSB7XG4gICAgICAgIG1hcFtwYXJlbnROb2RlSWRdLmNoaWxkcmVuLnB1c2goaXRlbSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHRvVHJlZSgpIHtcbiAgICBjb25zdCBtYXAgPSB0aGlzLmxpbmtDaGlsZHJlbigpO1xuICAgIGNvbnN0IHRyZWUgPSB7fTtcblxuICAgIHRoaXMuaXRlbXMuZm9yRWFjaCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgcGFyZW50Tm9kZUlkID0gaXRlbVt0aGlzLm9wdGlvbnMucGFyZW50SWRdO1xuICAgICAgaWYgKCFwYXJlbnROb2RlSWQpIHtcbiAgICAgICAgdHJlZVtpdGVtLmlkXSA9IG1hcFtpdGVtLmlkXTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB0aGlzLmNvbGxlY3Rpb24gPSBPYmplY3QudmFsdWVzKHRyZWUpO1xuICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb247XG4gIH1cblxuICBnZXRUcmVlKCkge1xuICAgIHJldHVybiB0aGlzLmNvbGxlY3Rpb247XG4gIH1cblxuICBmbGF0dGVuVHJlZShub2RlTWFwcGVyKSB7XG4gICAgY29uc3QgZmxhdHRlblRyZWUgPSBbXTtcblxuICAgIGNvbnN0IHRyYXZlcnNhbCA9IChub2RlcywgcGFyZW50Tm9kZSkgPT4ge1xuICAgICAgbm9kZXMuZm9yRWFjaCgobm9kZSkgPT4ge1xuICAgICAgICBsZXQgbm9kZU1hcHBlZCA9IG5vZGU7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBub2RlTWFwcGVyID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgbm9kZU1hcHBlZCA9IG5vZGVNYXBwZXIobm9kZU1hcHBlZCwgcGFyZW50Tm9kZSk7XG4gICAgICAgIH1cbiAgICAgICAgZmxhdHRlblRyZWUucHVzaChub2RlTWFwcGVkKTtcblxuICAgICAgICBpZiAobm9kZS5jaGlsZHJlbiAmJiBub2RlLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0cmF2ZXJzYWwobm9kZS5jaGlsZHJlbiwgbm9kZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG4gICAgdHJhdmVyc2FsKHRoaXMuY29sbGVjdGlvbik7XG5cbiAgICByZXR1cm4gZmxhdHRlblRyZWU7XG4gIH1cbn1cbiIsImltcG9ydCBNZXRhYmxlQ29sbGVjdGlvbiBmcm9tICdAL2xpYi9NZXRhYmxlL01ldGFibGVDb2xsZWN0aW9uJztcbmltcG9ydCBSZXNvdXJjZUZpZWxkTWV0YWRhdGEgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZE1ldGFkYXRhJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVzb3VyY2VGaWVsZE1ldGFkYXRhQ29sbGVjdGlvbiBleHRlbmRzIE1ldGFibGVDb2xsZWN0aW9uIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIG1ldGhvZC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLnNldE1vZGVsKFJlc291cmNlRmllbGRNZXRhZGF0YSk7XG4gICAgdGhpcy5leHRyYUNvbHVtbnMgPSBbJ3Jlc291cmNlX2lkJywgJ3Jlc291cmNlX2l0ZW1faWQnXTtcbiAgfVxufVxuIiwiXG5leHBvcnQgZGVmYXVsdCB7XG4gIFwiZXhwZW5zZV9hY2NvdW50XCI6ICdleHBlbnNlX2FjY291bnRfaWQnLFxuICBcInBheW1lbnRfYWNjb3VudFwiOiAncGF5bWVudF9hY2NvdW50X2lkJyxcbiAgXCJhY2NvdW50X3R5cGVcIjogXCJhY2NvdW50X3R5cGVfaWRcIlxufSIsImltcG9ydCBLbmV4IGZyb20gJ2tuZXgnO1xuaW1wb3J0IHsga25leFNuYWtlQ2FzZU1hcHBlcnMgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IGtuZXhmaWxlIGZyb20gJ0AvLi4va25leGZpbGUnO1xuXG5jb25zdCBjb25maWcgPSBrbmV4ZmlsZVtwcm9jZXNzLmVudi5OT0RFX0VOVl07XG5jb25zdCBrbmV4ID0gS25leCh7XG4gIC4uLmNvbmZpZyxcbiAgLi4ua25leFNuYWtlQ2FzZU1hcHBlcnMoeyB1cHBlckNhc2U6IHRydWUgfSksXG59KTtcblxuZXhwb3J0IGRlZmF1bHQga25leDtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgY2hlY2ssIHZhbGlkYXRpb25SZXN1bHQsIG9uZU9mIH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgSm91cm5hbFBvc3RlciBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbFBvc3Rlcic7XG5pbXBvcnQgSm91cm5hbEVudHJ5IGZyb20gJ0Avc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsRW50cnknO1xuaW1wb3J0IE1hbnVhbEpvdXJuYWwgZnJvbSAnQC9tb2RlbHMvTWFudWFsSm91cm5hbCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnVzZShqd3RBdXRoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHRoaXMub3BlbmluZ0JhbG5hY2UudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm9wZW5pbmdCYWxuYWNlLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIE9wZW5pbmcgYmFsYW5jZSB0byB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICogQHBhcmFtIHtSZXF1ZXN0fSByZXEgLVxuICAgKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXMgLVxuICAgKi9cbiAgb3BlbmluZ0JhbG5hY2U6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnZGF0ZScpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnbm90ZScpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ2JhbGFuY2VfYWRqdXN0bWVudF9hY2NvdW50JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50cycpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgICBjaGVjaygnYWNjb3VudHMuKi5pZCcpLmV4aXN0cygpLmlzSW50KCksXG4gICAgICBvbmVPZihbXG4gICAgICAgIGNoZWNrKCdhY2NvdW50cy4qLmRlYml0JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgICBjaGVjaygnYWNjb3VudHMuKi5jcmVkaXQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgICBdKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgYWNjb3VudHMgfSA9IHJlcS5ib2R5O1xuICAgICAgY29uc3QgeyB1c2VyIH0gPSByZXE7XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgZGF0ZSA9IG1vbWVudChmb3JtLmRhdGUpLmZvcm1hdCgnWVlZWS1NTS1ERCcpO1xuXG4gICAgICBjb25zdCBhY2NvdW50c0lkcyA9IGFjY291bnRzLm1hcCgoYWNjb3VudCkgPT4gYWNjb3VudC5pZCk7XG4gICAgICBjb25zdCBzdG9yZWRBY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKVxuICAgICAgICAuc2VsZWN0KFsnaWQnXSkud2hlcmVJbignaWQnLCBhY2NvdW50c0lkcylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3R5cGUnKTtcblxuICAgICAgY29uc3QgYWNjb3VudHNDb2xsZWN0aW9uID0gbmV3IE1hcChzdG9yZWRBY2NvdW50cy5tYXAoaSA9PiBbaS5pZCwgaV0pKTtcblxuICAgICAgLy8gR2V0IHRoZSBzdG9yZWQgYWNjb3VudHMgSWRzIGFuZCBkaWZmZXJlbmNlIHdpdGggc3VibWl0IGFjY291bnRzLlxuICAgICAgY29uc3QgYWNjb3VudHNTdG9yZWRJZHMgPSBzdG9yZWRBY2NvdW50cy5tYXAoKGFjY291bnQpID0+IGFjY291bnQuaWQpO1xuICAgICAgY29uc3Qgbm90Rm91bmRBY2NvdW50c0lkcyA9IGRpZmZlcmVuY2UoYWNjb3VudHNJZHMsIGFjY291bnRzU3RvcmVkSWRzKTtcbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuXG4gICAgICBpZiAobm90Rm91bmRBY2NvdW50c0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IGlkcyA9IG5vdEZvdW5kQWNjb3VudHNJZHMubWFwKChhKSA9PiBwYXJzZUludChhLCAxMCkpO1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdOT1RfRk9VTkRfQUNDT1VOVCcsIGNvZGU6IDEwMCwgaWRzIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGZvcm0uYmFsYW5jZV9hZGp1c3RtZW50X2FjY291bnQpIHtcbiAgICAgICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IEFjY291bnQucXVlcnkoKS5maW5kQnlJZChmb3JtLmJhbGFuY2VfYWRqdXN0bWVudF9hY2NvdW50KTtcblxuICAgICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdCQUxBTkNFLkFESlVTVE1FTlQuQUNDT1VOVC5OT1QuRVhJU1QnLCBjb2RlOiAzMDAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBqb3VybmFsRW50cmllcyA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG5cbiAgICAgIGFjY291bnRzLmZvckVhY2goKGFjY291bnQpID0+IHtcbiAgICAgICAgY29uc3Qgc3RvcmVkQWNjb3VudCA9IGFjY291bnRzQ29sbGVjdGlvbi5nZXQoYWNjb3VudC5pZCk7XG5cbiAgICAgICAgLy8gQ2FuJ3QgY29udGludWUgaW4gY2FzZSB0aGUgc3RvcmVkIGFjY291bnQgd2FzIG5vdCBmb3VuZC5cbiAgICAgICAgaWYgKCFzdG9yZWRBY2NvdW50KSB7IHJldHVybjsgfVxuXG4gICAgICAgIGNvbnN0IGVudHJ5TW9kZWwgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgICByZWZlcmVuY2VUeXBlOiAnT3BlbmluZ0JhbGFuY2UnLFxuICAgICAgICAgIGFjY291bnQ6IGFjY291bnQuaWQsXG4gICAgICAgICAgYWNjb3VudE5vcm1hbDogc3RvcmVkQWNjb3VudC50eXBlLm5vcm1hbCxcbiAgICAgICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoYWNjb3VudC5jcmVkaXQpIHtcbiAgICAgICAgICBlbnRyeU1vZGVsLmVudHJ5LmNyZWRpdCA9IGFjY291bnQuY3JlZGl0O1xuICAgICAgICAgIGpvdXJuYWxFbnRyaWVzLmNyZWRpdChlbnRyeU1vZGVsKTtcbiAgICAgICAgfSBlbHNlIGlmIChhY2NvdW50LmRlYml0KSB7XG4gICAgICAgICAgZW50cnlNb2RlbC5lbnRyeS5kZWJpdCA9IGFjY291bnQuZGViaXQ7XG4gICAgICAgICAgam91cm5hbEVudHJpZXMuZGViaXQoZW50cnlNb2RlbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gQ2FsY3VsYXRlcyB0aGUgY3JlZGl0IGFuZCBkZWJpdCBiYWxhbmNlIG9mIHN0YWNrZWQgZW50cmllcy5cbiAgICAgIGNvbnN0IHRyaWFsID0gam91cm5hbEVudHJpZXMuZ2V0VHJpYWxCYWxhbmNlKCk7XG5cbiAgICAgIGlmICh0cmlhbC5jcmVkaXQgIT09IHRyaWFsLmRlYml0KSB7XG4gICAgICAgIGNvbnN0IGVudHJ5TW9kZWwgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgICByZWZlcmVuY2VUeXBlOiAnT3BlbmluZ0JhbGFuY2UnLFxuICAgICAgICAgIGFjY291bnQ6IGZvcm0uYmFsYW5jZV9hZGp1c3RtZW50X2FjY291bnQsXG4gICAgICAgICAgYWNjb3VudE5vcm1hbDogJ2NyZWRpdCcsXG4gICAgICAgICAgdXNlcklkOiB1c2VyLmlkLFxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAodHJpYWwuY3JlZGl0ID4gdHJpYWwuZGViaXQpIHtcbiAgICAgICAgICBlbnRyeU1vZGVsLmVudHJ5LmNyZWRpdCA9IE1hdGguYWJzKHRyaWFsLmNyZWRpdCk7XG4gICAgICAgICAgam91cm5hbEVudHJpZXMuY3JlZGl0KGVudHJ5TW9kZWwpO1xuXG4gICAgICAgIH0gZWxzZSBpZiAodHJpYWwuY3JlZGl0IDwgdHJpYWwuZGViaXQpIHtcbiAgICAgICAgICBlbnRyeU1vZGVsLmVudHJ5LmRlYml0ID0gTWF0aC5hYnModHJpYWwuZGViaXQpO1xuICAgICAgICAgIGpvdXJuYWxFbnRyaWVzLmRlYml0KGVudHJ5TW9kZWwpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBtYW51YWxKb3VybmFsID0gYXdhaXQgTWFudWFsSm91cm5hbC5xdWVyeSgpLmluc2VydCh7XG4gICAgICAgIGFtb3VudDogTWF0aC5tYXgodHJpYWwuY3JlZGl0LCB0cmlhbC5kZWJpdCksXG4gICAgICAgIHRyYW5zYWN0aW9uX3R5cGU6ICdPcGVuaW5nQmFsYW5jZScsXG4gICAgICAgIGRhdGUsXG4gICAgICAgIG5vdGU6IGZvcm0ubm90ZSxcbiAgICAgICAgdXNlcl9pZDogdXNlci5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBqb3VybmFsRW50cmllcy5lbnRyaWVzID0gam91cm5hbEVudHJpZXMuZW50cmllcy5tYXAoKGVudHJ5KSA9PiAoe1xuICAgICAgICAuLi5lbnRyeSxcbiAgICAgICAgcmVmZXJlbmNlSWQ6IG1hbnVhbEpvdXJuYWwuaWQsXG4gICAgICB9KSk7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGpvdXJuYWxFbnRyaWVzLnNhdmVFbnRyaWVzKCksXG4gICAgICAgIGpvdXJuYWxFbnRyaWVzLnNhdmVCYWxhbmNlKCksXG4gICAgICBdKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBtYW51YWxKb3VybmFsLmlkIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgSldUQXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBBY2NvdW50VHlwZSBmcm9tICdAL21vZGVscy9BY2NvdW50VHlwZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIHJvdXRlci51c2UoSldUQXV0aCk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHRoaXMuZ2V0QWNjb3VudFR5cGVzTGlzdC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0QWNjb3VudFR5cGVzTGlzdC5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhY2NvdW50cyB0eXBlcyBsaXN0LlxuICAgKi9cbiAgZ2V0QWNjb3VudFR5cGVzTGlzdDoge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IGFjY291bnRUeXBlcyA9IGF3YWl0IEFjY291bnRUeXBlLnF1ZXJ5KCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGFjY291bnRfdHlwZXM6IGFjY291bnRUeXBlcyxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IHsgY2hlY2ssIHF1ZXJ5LCBvbmVPZiwgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgQWNjb3VudCBmcm9tICdAL21vZGVscy9BY2NvdW50JztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBKV1RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IEpvdXJuYWxFbnRyeSBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbEVudHJ5JztcbmltcG9ydCBNYW51YWxKb3VybmFsIGZyb20gJ0AvbW9kZWxzL0pvdXJuYWxFbnRyeSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIHJvdXRlci51c2UoSldUQXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnL21ha2Utam91cm5hbC1lbnRyaWVzJyxcbiAgICAgIHRoaXMubWFrZUpvdXJuYWxFbnRyaWVzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5tYWtlSm91cm5hbEVudHJpZXMuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9yZWN1cnJpbmctam91cm5hbC1lbnRyaWVzJyxcbiAgICAgIHRoaXMucmVjdXJyaW5nSm91cm5hbEVudHJpZXMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlY3VycmluZ0pvdXJuYWxFbnRyaWVzLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCdxdWljay1qb3VybmFsLWVudHJpZXMnLFxuICAgICAgdGhpcy5xdWlja0pvdXJuYWxFbnRyaWVzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5xdWlja0pvdXJuYWxFbnRyaWVzLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIE1ha2Ugam91cm5hbCBlbnRyaXJlcy5cbiAgICovXG4gIG1ha2VKb3VybmFsRW50cmllczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdkYXRlJykuaXNJU084NjAxKCksXG4gICAgICBjaGVjaygncmVmZXJlbmNlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygnbWVtbycpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ2VudHJpZXMnKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2VudHJpZXMuKi5jcmVkaXQnKS5vcHRpb25hbCh7IG51bGxhYmxlOiB0cnVlIH0pLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZW50cmllcy4qLmRlYml0Jykub3B0aW9uYWwoeyBudWxsYWJsZTogdHJ1ZSB9KS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2VudHJpZXMuKi5hY2NvdW50X2lkJykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLioubm90ZScpLm9wdGlvbmFsKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZm9ybSA9IHtcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgLi4ucmVxLmJvZHksXG4gICAgICB9O1xuXG4gICAgICBsZXQgdG90YWxDcmVkaXQgPSAwO1xuICAgICAgbGV0IHRvdGFsRGViaXQgPSAwO1xuXG4gICAgICBjb25zdCB7IHVzZXIgfSA9IHJlcTtcbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3QgZW50cmllcyA9IGZvcm0uZW50cmllcy5maWx0ZXIoKGVudHJ5KSA9PiAoZW50cnkuY3JlZGl0IHx8IGVudHJ5LmRlYml0KSk7XG4gICAgICBjb25zdCBmb3JtYXR0ZWREYXRlID0gbW9tZW50KGZvcm0uZGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG5cbiAgICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKGVudHJ5LmNyZWRpdCA+IDApIHtcbiAgICAgICAgICB0b3RhbENyZWRpdCArPSBlbnRyeS5jcmVkaXQ7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVudHJ5LmRlYml0ID4gMCkge1xuICAgICAgICAgIHRvdGFsRGViaXQgKz0gZW50cnkuZGViaXQ7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAodG90YWxDcmVkaXQgPD0gMCB8fCB0b3RhbERlYml0IDw9IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdDUkVESVQuREVCSVQuU1VNQVRJT04uU0hPVUxELk5PVC5FUVVBTC5aRVJPJyxcbiAgICAgICAgICBjb2RlOiA0MDAsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHRvdGFsQ3JlZGl0ICE9PSB0b3RhbERlYml0KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0NSRURJVC5ERUJJVC5OT1QuRVFVQUxTJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYWNjb3VudHNJZHMgPSBlbnRyaWVzLm1hcCgoZW50cnkpID0+IGVudHJ5LmFjY291bnRfaWQpO1xuICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkud2hlcmVJbignaWQnLCBhY2NvdW50c0lkcylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3R5cGUnKTtcblxuICAgICAgY29uc3Qgc3RvcmVkQWNjb3VudHNJZHMgPSBhY2NvdW50cy5tYXAoKGFjY291bnQpID0+IGFjY291bnQuaWQpO1xuXG4gICAgICBpZiAoZGlmZmVyZW5jZShhY2NvdW50c0lkcywgc3RvcmVkQWNjb3VudHNJZHMpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQUNDT1VOVFMuSURTLk5PVC5GT1VORCcsIGNvZGU6IDIwMCB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgam91cm5hbFJlZmVyZW5jZSA9IGF3YWl0IE1hbnVhbEpvdXJuYWwucXVlcnkoKS53aGVyZSgncmVmZXJlbmNlJywgZm9ybS5yZWZlcmVuY2UpO1xuXG4gICAgICBpZiAoam91cm5hbFJlZmVyZW5jZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1JFRkVSRU5DRS5BTFJFQURZLkVYSVNUUycsIGNvZGU6IDMwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gU2F2ZSBtYW51YWwgam91cm5hbCB0cmFuc2FjdGlvbi5cbiAgICAgIGNvbnN0IG1hbnVhbEpvdXJuYWwgPSBhd2FpdCBNYW51YWxKb3VybmFsLnF1ZXJ5KCkuaW5zZXJ0KHtcbiAgICAgICAgcmVmZXJlbmNlOiBmb3JtLnJlZmVyZW5jZSxcbiAgICAgICAgdHJhbnNhY3Rpb25fdHlwZTogJ0pvdXJuYWwnLFxuICAgICAgICBhbW91bnQ6IHRvdGFsQ3JlZGl0LFxuICAgICAgICBkYXRlOiBmb3JtYXR0ZWREYXRlLFxuICAgICAgICBub3RlOiBmb3JtLm1lbW8sXG4gICAgICAgIHVzZXJfaWQ6IHVzZXIuaWQsXG4gICAgICB9KTtcbiAgICAgIGNvbnN0IGpvdXJuYWxQb3N0ZXIgPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuXG4gICAgICBlbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICAgIGNvbnN0IGFjY291bnQgPSBhY2NvdW50cy5maW5kKChhKSA9PiBhLmlkID09PSBlbnRyeS5hY2NvdW50X2lkKTtcblxuICAgICAgICBjb25zdCBqb3VyYW5sRW50cnkgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgICBkZWJpdDogZW50cnkuZGViaXQsXG4gICAgICAgICAgY3JlZGl0OiBlbnRyeS5jcmVkaXQsXG4gICAgICAgICAgYWNjb3VudDogYWNjb3VudC5pZCxcbiAgICAgICAgICB0cmFuc2FjdGlvblR5cGU6ICdKb3VybmFsJyxcbiAgICAgICAgICBhY2NvdW50Tm9ybWFsOiBhY2NvdW50LnR5cGUubm9ybWFsLFxuICAgICAgICAgIG5vdGU6IGVudHJ5Lm5vdGUsXG4gICAgICAgICAgZGF0ZTogZm9ybWF0dGVkRGF0ZSxcbiAgICAgICAgICB1c2VySWQ6IHVzZXIuaWQsXG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoZW50cnkuZGViaXQpIHtcbiAgICAgICAgICBqb3VybmFsUG9zdGVyLmRlYml0KGpvdXJhbmxFbnRyeSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgam91cm5hbFBvc3Rlci5jcmVkaXQoam91cmFubEVudHJ5KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFNhdmVzIHRoZSBqb3VybmFsIGVudHJpZXMgYW5kIGFjY291bnRzIGJhbGFuY2UgY2hhbmdlcy5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgam91cm5hbFBvc3Rlci5zYXZlRW50cmllcygpLFxuICAgICAgICBqb3VybmFsUG9zdGVyLnNhdmVCYWxhbmNlKCksXG4gICAgICBdKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBtYW51YWxKb3VybmFsLmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFNhdmVzIHJlY3VycmluZyBqb3VybmFsIGVudHJpZXMgdGVtcGxhdGUuXG4gICAqL1xuICByZWN1cnJpbmdKb3VybmFsRW50cmllczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCd0ZW1wbGF0ZV9uYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygncmVjdXJyZW5jZScpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ2FjdGl2ZScpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBjaGVjaygnZW50cmllcycpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgICBjaGVjaygnZW50cmllcy4qLmNyZWRpdCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZW50cmllcy4qLmRlYml0JykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdlbnRyaWVzLiouYWNjb3VudF9pZCcpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZW50cmllcy4qLm5vdGUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgIH0sXG4gIH0sXG5cbiAgcmVjdXJyaW5nSm91cm5hbHNMaXN0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcXVlcnkoJ3BhZ2UnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgncGFnZV9zaXplJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ3RlbXBsYXRlX25hbWUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICB9LFxuXG4gIHF1aWNrSm91cm5hbEVudHJpZXM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnZGF0ZScpLmV4aXN0cygpLmlzSVNPODYwMSgpLFxuICAgICAgY2hlY2soJ2Ftb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdjcmVkaXRfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGViaXRfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygndHJhbnNhY3Rpb25fdHlwZScpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ25vdGUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3QgZm9ybSA9IHsgLi4ucmVxLmJvZHkgfTtcblxuICAgICAgY29uc3QgZm91bmRBY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ2lkJywgZm9ybS5jcmVkaXRfYWNjb3VudF9pZClcbiAgICAgICAgLm9yV2hlcmUoJ2lkJywgZm9ybS5kZWJpdF9hY2NvdW50X2lkKTtcblxuICAgICAgY29uc3QgY3JlZGl0QWNjb3VudCA9IGZvdW5kQWNjb3VudHMuZmluZCgoYSkgPT4gYS5pZCA9PT0gZm9ybS5jcmVkaXRfYWNjb3VudF9pZCk7XG4gICAgICBjb25zdCBkZWJpdEFjY291bnQgPSBmb3VuZEFjY291bnRzLmZpbmQoKGEpID0+IGEuaWQgPT09IGZvcm0uZGViaXRfYWNjb3VudF9pZCk7XG5cbiAgICAgIGlmICghY3JlZGl0QWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdDUkVESVRfQUNDT1VOVC5OT1QuRVhJU1QnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIWRlYml0QWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdERUJJVF9BQ0NPVU5ULk5PVC5FWElTVCcsIGNvZGU6IDIwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3Qgam91cm5hbFBvc3RlciA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG4gICAgICAvLyBjb25zdCBqb3VybmFsQ3JlZGl0ID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAvLyAgIGRlYml0OiBcbiAgICAgIC8vICAgYWNjb3VudDogZGViaXRBY2NvdW50LmlkLFxuICAgICAgLy8gICByZWZlcmVuY2VJZDogXG4gICAgICAvLyB9KVxuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgY2hlY2ssIHZhbGlkYXRpb25SZXN1bHQsIHBhcmFtLCBxdWVyeSB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBBY2NvdW50IGZyb20gJ0AvbW9kZWxzL0FjY291bnQnO1xuaW1wb3J0IEFjY291bnRUeXBlIGZyb20gJ0AvbW9kZWxzL0FjY291bnRUeXBlJztcbmltcG9ydCBBY2NvdW50VHJhbnNhY3Rpb24gZnJvbSAnQC9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uJztcbmltcG9ydCBKb3VybmFsUG9zdGVyIGZyb20gJ0Avc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsUG9zdGVyJztcbmltcG9ydCBBY2NvdW50QmFsYW5jZSBmcm9tICdAL21vZGVscy9BY2NvdW50QmFsYW5jZSc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IFZpZXcgZnJvbSAnQC9tb2RlbHMvVmlldyc7XG5pbXBvcnQgSldUQXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBOZXN0ZWRTZXQgZnJvbSAnLi4vLi4vY29sbGVjdGlvbi9OZXN0ZWRTZXQnO1xuaW1wb3J0IHtcbiAgbWFwVmlld1JvbGVzVG9Db25kaXRpb25hbHMsXG4gIHZhbGlkYXRlVmlld1JvbGVzLFxufSBmcm9tICdAL2xpYi9WaWV3Um9sZXNCdWlsZGVyJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yIG1ldGhvZC5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnVzZShKV1RBdXRoKTtcbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLm5ld0FjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm5ld0FjY291bnQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgdGhpcy5lZGl0QWNjb3VudC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdEFjY291bnQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLzppZCcsXG4gICAgICB0aGlzLmdldEFjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldEFjY291bnQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLycsXG4gICAgICB0aGlzLmdldEFjY291bnRzTGlzdC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0QWNjb3VudHNMaXN0LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5kZWxldGUoJy86aWQnLFxuICAgICAgdGhpcy5kZWxldGVBY2NvdW50LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVBY2NvdW50LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvOmlkL2FjdGl2ZScsXG4gICAgICB0aGlzLmFjdGl2ZUFjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmFjdGl2ZUFjY291bnQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQvaW5hY3RpdmUnLFxuICAgICAgdGhpcy5pbmFjdGl2ZUFjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmluYWN0aXZlQWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZC9yZWNhbGN1bGF0ZS1iYWxhbmNlJyxcbiAgICAgIHRoaXMucmVjYWxjdWFsdGVCYWxhbmFjZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMucmVjYWxjdWFsdGVCYWxhbmFjZS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZC90cmFuc2Zlcl9hY2NvdW50Lzp0b0FjY291bnQnLFxuICAgICAgdGhpcy50cmFuc2ZlclRvQW5vdGhlckFjY291bnQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnRyYW5zZmVyVG9Bbm90aGVyQWNjb3VudC5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGFjY291bnQuXG4gICAqL1xuICBuZXdBY2NvdW50OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKS5pc0xlbmd0aCh7IG1pbjogMyB9KS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnY29kZScpLmV4aXN0cygpLmlzTGVuZ3RoKHsgbWF4OiAxMCB9KS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnYWNjb3VudF90eXBlX2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG5cbiAgICAgIGNvbnN0IGZvdW5kQWNjb3VudENvZGVQcm9taXNlID0gZm9ybS5jb2RlXG4gICAgICAgID8gQWNjb3VudC5xdWVyeSgpLndoZXJlKCdjb2RlJywgZm9ybS5jb2RlKSA6IG51bGw7XG5cbiAgICAgIGNvbnN0IGZvdW5kQWNjb3VudFR5cGVQcm9taXNlID0gQWNjb3VudFR5cGUucXVlcnkoKVxuICAgICAgICAuZmluZEJ5SWQoZm9ybS5hY2NvdW50X3R5cGVfaWQpO1xuXG4gICAgICBjb25zdCBbZm91bmRBY2NvdW50Q29kZSwgZm91bmRBY2NvdW50VHlwZV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGZvdW5kQWNjb3VudENvZGVQcm9taXNlLCBmb3VuZEFjY291bnRUeXBlUHJvbWlzZSxcbiAgICAgIF0pO1xuXG4gICAgICBpZiAoZm91bmRBY2NvdW50Q29kZVByb21pc2UgJiYgZm91bmRBY2NvdW50Q29kZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdOT1RfVU5JUVVFX0NPREUnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFmb3VuZEFjY291bnRUeXBlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdOT1RfRVhJU1RfQUNDT1VOVF9UWVBFJywgY29kZTogMjAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IEFjY291bnQucXVlcnkoKS5pbnNlcnQoeyAuLi5mb3JtIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpdGVtOiB7IH0gfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRWRpdCB0aGUgZ2l2ZW4gYWNjb3VudCBkZXRhaWxzLlxuICAgKi9cbiAgZWRpdEFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKS5pc0xlbmd0aCh7IG1pbjogMyB9KS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnY29kZScpLmV4aXN0cygpLmlzTGVuZ3RoKHsgbWF4OiAxMCB9KS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnYWNjb3VudF90eXBlX2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgYWNjb3VudCA9IGF3YWl0IEFjY291bnQucXVlcnkoKS5maW5kQnlJZChpZCk7XG5cbiAgICAgIGlmICghYWNjb3VudCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvdW5kQWNjb3VudENvZGVQcm9taXNlID0gKGZvcm0uY29kZSAmJiBmb3JtLmNvZGUgIT09IGFjY291bnQuY29kZSlcbiAgICAgICAgPyBBY2NvdW50LnF1ZXJ5KCkud2hlcmUoJ2NvZGUnLCBmb3JtLmNvZGUpLndoZXJlTm90KCdpZCcsIGFjY291bnQuaWQpIDogbnVsbDtcblxuICAgICAgY29uc3QgZm91bmRBY2NvdW50VHlwZVByb21pc2UgPSAoZm9ybS5hY2NvdW50X3R5cGVfaWQgIT09IGFjY291bnQuYWNjb3VudF90eXBlX2lkKVxuICAgICAgICA/IEFjY291bnRUeXBlLnF1ZXJ5KCkud2hlcmUoJ2lkJywgZm9ybS5hY2NvdW50X3R5cGVfaWQpIDogbnVsbDtcblxuICAgICAgY29uc3QgW2ZvdW5kQWNjb3VudENvZGUsIGZvdW5kQWNjb3VudFR5cGVdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBmb3VuZEFjY291bnRDb2RlUHJvbWlzZSwgZm91bmRBY2NvdW50VHlwZVByb21pc2UsXG4gICAgICBdKTtcbiAgICAgIGlmIChmb3VuZEFjY291bnRDb2RlLmxlbmd0aCA+IDAgJiYgZm91bmRBY2NvdW50Q29kZVByb21pc2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ05PVF9VTklRVUVfQ09ERScsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZm91bmRBY2NvdW50VHlwZS5sZW5ndGggPD0gMCAmJiBmb3VuZEFjY291bnRUeXBlUHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnTk9UX0VYSVNUX0FDQ09VTlRfVFlQRScsIGNvZGU6IDExMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBhY2NvdW50LnBhdGNoKHsgLi4uZm9ybSB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogR2V0IGRldGFpbHMgb2YgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICBnZXRBY2NvdW50OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLndoZXJlKCdpZCcsIGlkKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIWFjY291bnQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBhY2NvdW50OiB7IC4uLmFjY291bnQgfSB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICBkZWxldGVBY2NvdW50OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBhY2NvdW50ID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgY29uc3QgYWNjb3VudFRyYW5zYWN0aW9ucyA9IGF3YWl0IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnYWNjb3VudF9pZCcsIGFjY291bnQuaWQpO1xuXG4gICAgICBpZiAoYWNjb3VudFRyYW5zYWN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdBQ0NPVU5ULkhBUy5BU1NPQ0lBVEVELlRSQU5TQUNUSU9OUycsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBBY2NvdW50LnF1ZXJ5KCkuZGVsZXRlQnlJZChhY2NvdW50LmlkKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgYWNjb3VudHMgbGlzdC5cbiAgICovXG4gIGdldEFjY291bnRzTGlzdDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdkaXNwbGF5X3R5cGUnKS5vcHRpb25hbCgpLmlzSW4oWyd0cmVlJywgJ2ZsYXQnXSksXG4gICAgICBxdWVyeSgnYWNjb3VudF90eXBlcycpLm9wdGlvbmFsKCkuaXNBcnJheSgpLFxuICAgICAgcXVlcnkoJ2FjY291bnRfdHlwZXMuKicpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdjdXN0b21fdmlld19pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgYWNjb3VudF90eXBlczogW10sXG4gICAgICAgIGRpc3BsYXlfdHlwZTogJ3RyZWUnLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCB2aWV3Q29uZGl0aW9uYWxzID0gW107XG4gICAgICBjb25zdCBhY2NvdW50c1Jlc291cmNlID0gYXdhaXQgUmVzb3VyY2UucXVlcnkoKS53aGVyZSgnbmFtZScsICdhY2NvdW50cycpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghYWNjb3VudHNSZXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0FDQ09VTlRTX1JFU09VUkNFX05PVF9GT1VORCcsIGNvZGU6IDIwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB2aWV3ID0gYXdhaXQgVmlldy5xdWVyeSgpLm9uQnVpbGQoKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlci5jdXN0b21fdmlld19pZCkge1xuICAgICAgICAgIGJ1aWxkZXIud2hlcmUoJ2lkJywgZmlsdGVyLmN1c3RvbV92aWV3X2lkKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBidWlsZGVyLndoZXJlKCdmYXZvdXJpdGUnLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBidWlsZGVyLndoZXJlKCdyZXNvdXJjZV9pZCcsIGFjY291bnRzUmVzb3VyY2UuaWQpO1xuICAgICAgICBidWlsZGVyLndpdGhHcmFwaEZldGNoZWQoJ3JvbGVzLmZpZWxkJyk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgnY29sdW1ucycpO1xuICAgICAgICBidWlsZGVyLmZpcnN0KCk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKHZpZXcgJiYgdmlldy5yb2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZpZXdDb25kaXRpb25hbHMucHVzaChcbiAgICAgICAgICAuLi5tYXBWaWV3Um9sZXNUb0NvbmRpdGlvbmFscyh2aWV3LnJvbGVzKSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKCF2YWxpZGF0ZVZpZXdSb2xlcyh2aWV3Q29uZGl0aW9uYWxzLCB2aWV3LnJvbGVzTG9naWNFeHByZXNzaW9uKSkge1xuICAgICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1ZJRVcuTE9HSUMuRVhQUkVTU0lPTi5JTlZBTElEJywgY29kZTogNDAwIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKS5vbkJ1aWxkKChidWlsZGVyKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJBY2NvdW50VHlwZXMnLCBmaWx0ZXIuYWNjb3VudF90eXBlcyk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgndHlwZScpO1xuXG4gICAgICAgIGlmICh2aWV3Q29uZGl0aW9uYWxzLmxlbmd0aCkge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCd2aWV3Um9sZXNCdWlsZGVyJywgdmlld0NvbmRpdGlvbmFscywgdmlldy5yb2xlc0xvZ2ljRXhwcmVzc2lvbik7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBuZXN0ZWRBY2NvdW50cyA9IG5ldyBOZXN0ZWRTZXQoYWNjb3VudHMsIHsgcGFyZW50SWQ6ICdwYXJlbnRBY2NvdW50SWQnIH0pO1xuICAgICAgY29uc3QgZ3JvdXBzQWNjb3VudHMgPSBuZXN0ZWRBY2NvdW50cy50b1RyZWUoKTtcbiAgICAgIGNvbnN0IGFjY291bnRzTGlzdCA9IFtdO1xuXG4gICAgICBpZiAoZmlsdGVyLmRpc3BsYXlfdHlwZSA9PT0gJ3RyZWUnKSB7XG4gICAgICAgIGFjY291bnRzTGlzdC5wdXNoKC4uLmdyb3Vwc0FjY291bnRzKTtcbiAgICAgIH0gZWxzZSBpZiAoZmlsdGVyLmRpc3BsYXlfdHlwZSA9PT0gJ2ZsYXQnKSB7XG4gICAgICAgIGNvbnN0IGZsYXR0ZW5BY2NvdW50cyA9IG5lc3RlZEFjY291bnRzLmZsYXR0ZW5UcmVlKChhY2NvdW50LCBwYXJlbnRBY2NvdW50KSA9PiB7XG4gICAgICAgICAgaWYgKHBhcmVudEFjY291bnQpIHtcbiAgICAgICAgICAgIGFjY291bnQubmFtZSA9IGAke3BhcmVudEFjY291bnQubmFtZX0g4oCVICR7YWNjb3VudC5uYW1lfWA7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBhY2NvdW50O1xuICAgICAgICB9KTtcbiAgICAgICAgYWNjb3VudHNMaXN0LnB1c2goLi4uZmxhdHRlbkFjY291bnRzKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGFjY291bnRzOiBhY2NvdW50c0xpc3QsXG4gICAgICAgIC4uLih2aWV3KSA/IHtcbiAgICAgICAgICBjdXN0b21WaWV3SWQ6IHZpZXcuaWQsXG4gICAgICAgIH0gOiB7fSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJlLWNhbGN1bGF0ZXMgYmFsYW5jZSBvZiB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIHJlY2FsY3VhbHRlQmFsYW5hY2U6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnQUNDT1VOVC5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgYWNjb3VudFRyYW5zYWN0aW9ucyA9IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnYWNjb3VudF9pZCcsIGFjY291bnQuaWQpO1xuXG4gICAgICBjb25zdCBqb3VybmFsRW50cmllcyA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG4gICAgICBqb3VybmFsRW50cmllcy5sb2FkRnJvbUNvbGxlY3Rpb24oYWNjb3VudFRyYW5zYWN0aW9ucyk7XG5cbiAgICAgIC8vIERlbGV0ZSB0aGUgYmFsYW5jZSBvZiB0aGUgZ2l2ZW4gYWNjb3VudCBpZC5cbiAgICAgIGF3YWl0IEFjY291bnRCYWxhbmNlLnF1ZXJ5KCkud2hlcmUoJ2FjY291bnRfaWQnLCBhY2NvdW50LmlkKS5kZWxldGUoKTtcblxuICAgICAgLy8gU2F2ZSBjYWxjdWFsdGVkIGFjY291bnQgYmFsYW5jZS5cbiAgICAgIGF3YWl0IGpvdXJuYWxFbnRyaWVzLnNhdmVCYWxhbmNlKCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEFjdGl2ZSB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGFjdGl2ZUFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnQUNDT1VOVC5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgYWNjb3VudC5wYXRjaCh7IGFjdGl2ZTogdHJ1ZSB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGFjY291bnQuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogSW5hY3RpdmUgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICBpbmFjdGl2ZUFjY291bnQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGFjY291bnQgPSBhd2FpdCBBY2NvdW50LmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFhY2NvdW50KSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnQUNDT1VOVC5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgYWNjb3VudC5wYXRjaCh7IGFjdGl2ZTogZmFsc2UgfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBhY2NvdW50LmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFRyYW5zZmVyIGFsbCBqb3VybmFsIGVudHJpZXMgb2YgdGhlIGdpdmVuIGFjY291bnQgdG8gYW5vdGhlciBhY2NvdW50LlxuICAgKi9cbiAgdHJhbnNmZXJUb0Fub3RoZXJBY2NvdW50OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHBhcmFtKCd0b0FjY291bnQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uc3QgeyBpZCwgdG9BY2NvdW50OiB0b0FjY291bnRJZCB9ID0gcmVxLnBhcmFtcztcblxuICAgICAgLy8gY29uc3QgW2Zyb21BY2NvdW50LCB0b0FjY291bnRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgLy8gICBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoaWQpLFxuICAgICAgLy8gICBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQodG9BY2NvdW50SWQpLFxuICAgICAgLy8gXSk7XG5cbiAgICAgIC8vIGNvbnN0IGZyb21BY2NvdW50VHJhbnNhY3Rpb25zID0gYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgIC8vICAgLndoZXJlKCdhY2NvdW50X2lkJywgZnJvbUFjY291bnQpO1xuXG4gICAgICAvLyByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxufTtcbiIsIlxuaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IGZzIGZyb20gJ2ZzJztcbmltcG9ydCBNdXN0YWNoZSBmcm9tICdtdXN0YWNoZSc7XG5pbXBvcnQgand0IGZyb20gJ2pzb253ZWJ0b2tlbic7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBVc2VyIGZyb20gJ0AvbW9kZWxzL1VzZXInO1xuaW1wb3J0IFBhc3N3b3JkUmVzZXQgZnJvbSAnQC9tb2RlbHMvUGFzc3dvcmRSZXNldCc7XG5pbXBvcnQgbWFpbCBmcm9tICdAL3NlcnZpY2VzL21haWwnO1xuaW1wb3J0IHsgaGFzaFBhc3N3b3JkIH0gZnJvbSAnQC91dGlscyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdG9yIG1ldGhvZC5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9sb2dpbicsXG4gICAgICB0aGlzLmxvZ2luLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5sb2dpbi5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnL3NlbmRfcmVzZXRfcGFzc3dvcmQnLFxuICAgICAgdGhpcy5zZW5kUmVzZXRQYXNzd29yZC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuc2VuZFJlc2V0UGFzc3dvcmQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy9yZXNldC86dG9rZW4nLFxuICAgICAgdGhpcy5yZXNldFBhc3N3b3JkLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5yZXNldFBhc3N3b3JkLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFVzZXIgbG9naW4gYXV0aGVudGljYXRpb24gcmVxdWVzdC5cbiAgICovXG4gIGxvZ2luOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ2NyZWRpZW50aWFsJykuZXhpc3RzKCkuaXNFbWFpbCgpLFxuICAgICAgY2hlY2soJ3Bhc3N3b3JkJykuZXhpc3RzKCkuaXNMZW5ndGgoeyBtaW46IDQgfSksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBjcmVkaWVudGlhbCwgcGFzc3dvcmQgfSA9IHJlcS5ib2R5O1xuICAgICAgY29uc3QgeyBKV1RfU0VDUkVUX0tFWSB9ID0gcHJvY2Vzcy5lbnY7XG5cbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBVc2VyLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdlbWFpbCcsIGNyZWRpZW50aWFsKVxuICAgICAgICAub3JXaGVyZSgncGhvbmVfbnVtYmVyJywgY3JlZGllbnRpYWwpXG4gICAgICAgIC5maXJzdCgpO1xuXG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0lOVkFMSURfREVUQUlMUycsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIXVzZXIudmVyaWZ5UGFzc3dvcmQocGFzc3dvcmQpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdJTlZBTElEX0RFVEFJTFMnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCF1c2VyLmFjdGl2ZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnVVNFUl9JTkFDVElWRScsIGNvZGU6IDExMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyB1c2VyLnVwZGF0ZSh7IGxhc3RfbG9naW5fYXQ6IG5ldyBEYXRlKCkgfSk7XG5cbiAgICAgIGNvbnN0IHRva2VuID0gand0LnNpZ24oe1xuICAgICAgICBlbWFpbDogdXNlci5lbWFpbCxcbiAgICAgICAgX2lkOiB1c2VyLmlkLFxuICAgICAgfSwgSldUX1NFQ1JFVF9LRVksIHtcbiAgICAgICAgZXhwaXJlc0luOiAnMWQnLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB0b2tlbiwgdXNlciB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBTZW5kIHJlc2V0IHBhc3N3b3JkIGxpbmsgdmlhIGVtYWlsIG9yIFNNUy5cbiAgICovXG4gIHNlbmRSZXNldFBhc3N3b3JkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ2VtYWlsJykuZXhpc3RzKCkuaXNFbWFpbCgpLFxuICAgIF0sXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNvbnNpc3RlbnQtcmV0dXJuXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgZW1haWwgfSA9IHJlcS5ib2R5O1xuICAgICAgY29uc3QgdXNlciA9IGF3YWl0IFVzZXIud2hlcmUoJ2VtYWlsJywgZW1haWwpLmZldGNoKCk7XG5cbiAgICAgIGlmICghdXNlcikge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MjIpLnNlbmQoKTtcbiAgICAgIH1cbiAgICAgIC8vIERlbGV0ZSBhbGwgc3RvcmVkIHRva2VucyBvZiByZXNldCBwYXNzd29yZCB0aGF0IGFzc29jaWF0ZSB0byB0aGUgZ2l2ZSBlbWFpbC5cbiAgICAgIGF3YWl0IFBhc3N3b3JkUmVzZXQud2hlcmUoeyBlbWFpbCB9KS5kZXN0cm95KHsgcmVxdWlyZTogZmFsc2UgfSk7XG5cbiAgICAgIGNvbnN0IHBhc3N3b3JkUmVzZXQgPSBQYXNzd29yZFJlc2V0LmZvcmdlKHtcbiAgICAgICAgZW1haWwsXG4gICAgICAgIHRva2VuOiAnMTIzMTIzJyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgcGFzc3dvcmRSZXNldC5zYXZlKCk7XG5cbiAgICAgIGNvbnN0IGZpbGVQYXRoID0gcGF0aC5qb2luKF9fZGlybmFtZSwgJy4uLy4uL3ZpZXdzL21haWwvUmVzZXRQYXNzd29yZC5odG1sJyk7XG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCwgJ3V0ZjgnKTtcbiAgICAgIGNvbnN0IHJlbmRlcmVkID0gTXVzdGFjaGUucmVuZGVyKHRlbXBsYXRlLCB7XG4gICAgICAgIHVybDogYCR7cmVxLnByb3RvY29sfTovLyR7cmVxLmhvc3RuYW1lfS9yZXNldC8ke3Bhc3N3b3JkUmVzZXQuYXR0cmlidXRlcy50b2tlbn1gLFxuICAgICAgICBmaXJzdF9uYW1lOiB1c2VyLmF0dHJpYnV0ZXMuZmlyc3RfbmFtZSxcbiAgICAgICAgbGFzdF9uYW1lOiB1c2VyLmF0dHJpYnV0ZXMubGFzdF9uYW1lLFxuICAgICAgICBjb250YWN0X3VzX2VtYWlsOiBwcm9jZXNzLmVudi5DT05UQUNUX1VTX0VNQUlMLFxuICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IG1haWxPcHRpb25zID0ge1xuICAgICAgICB0bzogdXNlci5hdHRyaWJ1dGVzLmVtYWlsLFxuICAgICAgICBmcm9tOiBgJHtwcm9jZXNzLmVudi5NQUlMX0ZST01fTkFNRX0gJHtwcm9jZXNzLmVudi5NQUlMX0ZST01fQUREUkVTU31gLFxuICAgICAgICBzdWJqZWN0OiAnUmF0dGViIFBhc3N3b3JkIFJlc2V0JyxcbiAgICAgICAgaHRtbDogcmVuZGVyZWQsXG4gICAgICB9O1xuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY29uc2lzdGVudC1yZXR1cm5cbiAgICAgIG1haWwuc2VuZE1haWwobWFpbE9wdGlvbnMsIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGRhdGE6IHsgZW1haWw6IHBhc3N3b3JkUmVzZXQuYXR0cmlidXRlcy5lbWFpbCB9IH0pO1xuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmVzZXQgcGFzc3dvcmQuXG4gICAqL1xuICByZXNldFBhc3N3b3JkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ3Bhc3N3b3JkJykuZXhpc3RzKCkuaXNMZW5ndGgoeyBtaW46IDUgfSkuY3VzdG9tKCh2YWx1ZSwgeyByZXEgfSkgPT4ge1xuICAgICAgICBpZiAodmFsdWUgIT09IHJlcS5ib2R5LmNvbmZpcm1fcGFzc3dvcmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJQYXNzd29yZHMgZG9uJ3QgbWF0Y2hcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICB9XG4gICAgICB9KSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICdWQUxJREFUSU9OX0VSUk9SJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IHRva2VuIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgeyBwYXNzd29yZCB9ID0gcmVxLmJvZHk7XG5cbiAgICAgIGNvbnN0IHRva2VuTW9kZWwgPSBhd2FpdCBQYXNzd29yZFJlc2V0LnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCd0b2tlbicsIHRva2VuKVxuICAgICAgICAud2hlcmUoJ2NyZWF0ZWRfYXQnLCAnPj0nLCBEYXRlLm5vdygpIC0gMzYwMDAwMClcbiAgICAgICAgLmZpcnN0KCk7XG5cbiAgICAgIGlmICghdG9rZW5Nb2RlbCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnVE9LRU5fSU5WQUxJRCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci53aGVyZSh7XG4gICAgICAgIGVtYWlsOiB0b2tlbk1vZGVsLmVtYWlsLFxuICAgICAgfSk7XG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1VTRVJfTk9UX0ZPVU5EJywgY29kZTogMTIwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGhhc2hlZFBhc3N3b3JkID0gYXdhaXQgaGFzaFBhc3N3b3JkKHBhc3N3b3JkKTtcblxuICAgICAgdXNlci5wYXNzd29yZCA9IGhhc2hlZFBhc3N3b3JkO1xuICAgICAgYXdhaXQgdXNlci5zYXZlKCk7XG5cbiAgICAgIGF3YWl0IFBhc3N3b3JkUmVzZXQud2hlcmUoJ2VtYWlsJywgdXNlci5nZXQoJ2VtYWlsJykpLmRlc3Ryb3koeyByZXF1aXJlOiBmYWxzZSB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHt9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHtcbiAgY2hlY2ssXG4gIHF1ZXJ5LFxuICBwYXJhbSxcbiAgdmFsaWRhdGlvblJlc3VsdCxcbn0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IHsgcGljaywgZGlmZmVyZW5jZSwgZ3JvdXBCeSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gXCJAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmVcIjtcbmltcG9ydCBKV1RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEJ1ZGdldCBmcm9tICdAL21vZGVscy9CdWRnZXQnO1xuaW1wb3J0IEJ1ZGdldEVudHJ5IGZyb20gJ0AvbW9kZWxzL0J1ZGdldEVudHJ5JztcbmltcG9ydCBBY2NvdW50IGZyb20gJ0AvbW9kZWxzL0FjY291bnQnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdAL3NlcnZpY2VzL01vbWVudCc7XG5pbXBvcnQgQnVkZ2V0RW50cmllc1NldCBmcm9tICdAL2NvbGxlY3Rpb24vQnVkZ2V0RW50cmllc1NldCc7XG5pbXBvcnQgQWNjb3VudFR5cGUgZnJvbSAnQC9tb2RlbHMvQWNjb3VudFR5cGUnO1xuaW1wb3J0IE5lc3RlZFNldCBmcm9tICdAL2NvbGxlY3Rpb24vTmVzdGVkU2V0JztcbmltcG9ydCB7IGRhdGVSYW5nZUZvcm1hdCB9IGZyb20gJ0AvdXRpbHMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnVzZShKV1RBdXRoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHRoaXMubmV3QnVkZ2V0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdCdWRnZXQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLzppZCcsXG4gICAgICB0aGlzLmdldEJ1ZGdldC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0QnVkZ2V0LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy86aWQnLFxuICAgICAgdGhpcy5kZWxldGVCdWRnZXQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZUJ1ZGdldC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvJyxcbiAgICAgIHRoaXMubGlzdEJ1ZGdldHMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmxpc3RCdWRnZXRzLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGJ1ZGdldCBkZXRhaWxzIG9mIHRoZSBnaXZlbiBpZC5cbiAgICovXG4gIGdldEJ1ZGdldDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGJ1ZGdldCA9IGF3YWl0IEJ1ZGdldC5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFidWRnZXQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdidWRnZXQubm90LmZvdW5kJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGFjY291bnRUeXBlcyA9IGF3YWl0IEFjY291bnRUeXBlLnF1ZXJ5KCkud2hlcmUoJ2JhbGFuY2Vfc2hlZXQnLCB0cnVlKTtcblxuICAgICAgY29uc3QgW2J1ZGdldEVudHJpZXMsIGFjY291bnRzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgQnVkZ2V0RW50cnkucXVlcnkoKS53aGVyZSgnYnVkZ2V0X2lkJywgYnVkZ2V0LmlkKSxcbiAgICAgICAgQWNjb3VudC5xdWVyeSgpLndoZXJlSW4oJ2FjY291bnRfdHlwZV9pZCcsIGFjY291bnRUeXBlcy5tYXAoKGEpID0+IGEuaWQpKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBhY2NvdW50c05lc3RlZFNldCA9IG5ldyBOZXN0ZWRTZXQoYWNjb3VudHMpO1xuXG4gICAgICBjb25zdCBjb2x1bW5zID0gW107XG4gICAgICBjb25zdCBmcm9tRGF0ZSA9IG1vbWVudChidWRnZXQueWVhcikuc3RhcnRPZigneWVhcicpXG4gICAgICAgIC5hZGQoYnVkZ2V0LnJhbmdlT2Zmc2V0LCBidWRnZXQucmFuZ2VCeSkudG9EYXRlKCk7XG5cbiAgICAgIGNvbnN0IHRvRGF0ZSA9IG1vbWVudChidWRnZXQueWVhcikuZW5kT2YoJ3llYXInKS50b0RhdGUoKTtcblxuICAgICAgY29uc3QgZGF0ZVJhbmdlID0gbW9tZW50LnJhbmdlKGZyb21EYXRlLCB0b0RhdGUpO1xuICAgICAgY29uc3QgZGF0ZVJhbmdlQ29sbGVjdGlvbiA9IEFycmF5LmZyb20oZGF0ZVJhbmdlLmJ5KGJ1ZGdldC5yYW5nZUJ5LCB7XG4gICAgICAgIHN0ZXA6IGJ1ZGdldC5yYW5nZUluY3JlbWVudCwgZXhjbHVkZUVuZDogZmFsc2UsIGV4Y2x1ZGVTdGFydDogZmFsc2UsXG4gICAgICB9KSk7XG5cbiAgICAgIGRhdGVSYW5nZUNvbGxlY3Rpb24uZm9yRWFjaCgoZGF0ZSkgPT4ge1xuICAgICAgICBjb2x1bW5zLnB1c2goZGF0ZS5mb3JtYXQoZGF0ZVJhbmdlRm9ybWF0KGJ1ZGdldC5yYW5nZUJ5KSkpO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBidWRnZXRFbnRyaWVzU2V0ID0gQnVkZ2V0RW50cmllc1NldC5mcm9tKGJ1ZGdldEVudHJpZXMsIHtcbiAgICAgICAgb3JkZXJTaXplOiBjb2x1bW5zLmxlbmd0aCxcbiAgICAgIH0pO1xuICAgICAgYnVkZ2V0RW50cmllc1NldC5zZXRaZXJvUGxhY2Vob2xkZXIoKTtcbiAgICAgIGJ1ZGdldEVudHJpZXNTZXQuY2FsY1RvdGFsU3VtbWFyeSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBjb2x1bW5zLFxuICAgICAgICBhY2NvdW50czogYnVkZ2V0RW50cmllc1NldC50b0FycmF5KCksXG4gICAgICAgIHRvdGFsOiBidWRnZXRFbnRyaWVzU2V0LnRvQXJyYXlUb3RhbFN1bW1hcnkoKSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZW4gYnVkZ2V0LlxuICAgKi9cbiAgZGVsZXRlQnVkZ2V0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgYnVkZ2V0ID0gYXdhaXQgQnVkZ2V0LnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWJ1ZGdldCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ2J1ZGdldC5ub3QuZm91bmQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgYXdhaXQgQnVkZ2V0RW50cnkucXVlcnkoKS53aGVyZSgnYnVkZ2V0X2lkJywgYnVkZ2V0LmlkKS5kZWxldGUoKTtcbiAgICAgIGF3YWl0IGJ1ZGdldC5kZWxldGUoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogU2F2ZXMgdGhlIG5ldyBidWRnZXQuXG4gICAqL1xuICBuZXdCdWRnZXQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ2Zpc2NhbF95ZWFyJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygncGVyaW9kJykuZXhpc3RzKCkuaXNJbihbJ3llYXInLCAnbW9udGgnLCAncXVhcnRlcicsICdoYWxmLXllYXInXSksXG4gICAgICBjaGVjaygnYWNjb3VudHNfdHlwZScpLmV4aXN0cygpLmlzSW4oWydiYWxhbmNlX3NoZWV0JywgJ3Byb2ZpdF9sb3NzJ10pLFxuICAgICAgY2hlY2soJ2FjY291bnRzJykuaXNBcnJheSgpLFxuICAgICAgY2hlY2soJ2FjY291bnRzLiouYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnYWNjb3VudHMuKi5lbnRyaWVzJykuZXhpc3RzKCkuaXNBcnJheSgpLFxuICAgICAgY2hlY2soJ2FjY291bnRzLiouZW50cmllcy4qLmFtb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdhY2NvdW50cy4qLmVudHJpZXMuKi5vcmRlcicpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3Qgc3VibWl0QWNjb3VudHNJZHMgPSBmb3JtLmFjY291bnRzLm1hcCgoYSkgPT4gYS5hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IHN0b3JlZEFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLndoZXJlSW4oJ2lkJywgc3VibWl0QWNjb3VudHNJZHMpO1xuICAgICAgY29uc3Qgc3RvcmVkQWNjb3VudHNJZHMgPSBzdG9yZWRBY2NvdW50cy5tYXAoKGEpID0+IGEuaWQpO1xuXG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcbiAgICAgIGNvbnN0IG5vdEZvdW5kQWNjb3VudHNJZHMgPSBkaWZmZXJlbmNlKHN1Ym1pdEFjY291bnRzSWRzLCBzdG9yZWRBY2NvdW50c0lkcyk7XG5cbiAgICAgIGlmIChub3RGb3VuZEFjY291bnRzSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdBQ0NPVU5ULk5PVC5GT1VORCcsIGNvZGU6IDIwMCwgYWNjb3VudHM6IG5vdEZvdW5kQWNjb3VudHNJZHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuICAgICAgLy8gdmFsaWRhdGlvbiBlbnRyaWVzIG9yZGVyLlxuICAgICAgY29uc3QgYnVkZ2V0ID0gYXdhaXQgQnVkZ2V0LnF1ZXJ5KCkuaW5zZXJ0KHtcbiAgICAgICAgLi4ucGljayhmb3JtLCBbJ25hbWUnLCAnZmlzY2FsX3llYXInLCAncGVyaW9kJywgJ2FjY291bnRzX3R5cGUnXSksXG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcHJvbWlzZU9wZXJzID0gW107XG5cbiAgICAgIGZvcm0uYWNjb3VudHMuZm9yRWFjaCgoYWNjb3VudCkgPT4ge1xuICAgICAgICBhY2NvdW50LmVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgICAgICBjb25zdCBidWRnZXRFbnRyeSA9IEJ1ZGdldEVudHJ5LnF1ZXJ5KCkuaW5zZXJ0KHtcbiAgICAgICAgICAgIGFjY291bnRfaWQ6IGFjY291bnQuYWNjb3VudF9pZCxcbiAgICAgICAgICAgIGFtb3VudDogZW50cnkuYW1vdW50LFxuICAgICAgICAgICAgb3JkZXI6IGVudHJ5Lm9yZGVyLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHByb21pc2VPcGVycy5wdXNoKGJ1ZGdldEVudHJ5KTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VPcGVycyk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBidWRnZXQuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogTGlzdCBvZiBwYWdpbmF0ZWQgYnVkZ2V0cyBpdGVtcy5cbiAgICovXG4gIGxpc3RCdWRnZXRzOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcXVlcnkoJ3llYXInKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ2luY29tZV9zdGF0ZW1lbnQnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgICAgcXVlcnkoJ3Byb2ZpdF9sb3NzJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdwYWdlJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ3BhZ2Vfc2l6ZScpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgnY3VzdG9tX3ZpZXdfaWQnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIHBhZ2Vfc2l6ZTogMTAsXG4gICAgICAgIHBhZ2U6IDEsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG4gICAgICBjb25zdCBidWRnZXRzID0gYXdhaXQgQnVkZ2V0LnF1ZXJ5KCkucnVuQmVmb3JlKChyZXN1bHQsIHEpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlci5wcm9maXRfbG9zcykge1xuICAgICAgICAgIHEubW9kaWZ5KCdmaWx0ZXJCeVllYXInLCBmaWx0ZXIueWVhcik7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5pbmNvbWVfc3RhdGVtZW50KSB7XG4gICAgICAgICAgcS5tb2RpZnkoJ2ZpbHRlckJ5SW5jb21lU3RhdGVtZW50JywgZmlsdGVyLmluY29tZV9zdGF0ZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChmaWx0ZXIucHJvZml0X2xvc3MpIHtcbiAgICAgICAgICBxLm1vZGlmeSgnZmlsdGVyQnlQcm9maXRMb3NzJywgZmlsdGVyLnByb2ZpdF9sb3NzKTtcbiAgICAgICAgfVxuICAgICAgICBxLnBhZ2UoZmlsdGVyLnBhZ2UsIGZpbHRlci5wYWdlX3NpemUpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBpdGVtczogYnVkZ2V0cy5pdGVtcyxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBxdWVyeSwgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IEJ1ZGdldCBmcm9tICdAL21vZGVscy9CdWRnZXQnO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgQWNjb3VudFR5cGUgZnJvbSAnQC9tb2RlbHMvQWNjb3VudFR5cGUnO1xuaW1wb3J0IE5lc3RlZFNldCBmcm9tICdAL2NvbGxlY3Rpb24vTmVzdGVkU2V0JztcbmltcG9ydCBCdWRnZXRFbnRyeSBmcm9tICdAL21vZGVscy9CdWRnZXRFbnRyeSc7XG5pbXBvcnQgeyBkYXRlUmFuZ2VGb3JtYXQgfSBmcm9tICdAL3V0aWxzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvYnVkZ2V0X3ZlcnNlc19hY3R1YWwvOnJlcG9ydElkJyxcbiAgICAgIHRoaXMuYnVkZ2V0VmVyc2VzQWN0dWFsLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5idWRnZXRWZXJzZXNBY3R1YWwuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICBidWRnZXRWZXJzZXNBY3R1YWw6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnYmFzaXMnKS5vcHRpb25hbCgpLmlzSW4oWydjYXNoJywgJ2FjY3VyYWwnXSksXG4gICAgICBxdWVyeSgncGVyaW9kJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdhY3RpdmVfYWNjb3VudHMnKS5vcHRpb25hbCgpLnRvQm9vbGVhbigpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgcmVwb3J0SWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBmb3JtID0geyAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG5cbiAgICAgIGNvbnN0IGJ1ZGdldCA9IGF3YWl0IEJ1ZGdldC5xdWVyeSgpLmZpbmRCeUlkKHJlcG9ydElkKTtcblxuICAgICAgaWYgKCFidWRnZXQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQlVER0VUX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJ1ZGdldEVudHJpZXMgPSBhd2FpdCBCdWRnZXRFbnRyeS5xdWVyeSgpLndoZXJlKCdidWRnZXRfaWQnLCBidWRnZXQuaWQpO1xuXG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBhY2NvdW50VHlwZXMgPSBhd2FpdCBBY2NvdW50VHlwZS5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnYmFsYW5jZV9zaGVldCcsIGJ1ZGdldC5hY2NvdW50VHlwZXMgPT09ICdiYWxhbmNlX3NoZWV0JylcbiAgICAgICAgLndoZXJlKCdpbmNvbWVfc2hlZXQnLCBidWRnZXQuYWNjb3VudFR5cGVzID09PSAncHJvZml0X2xvc3NzJyk7XG5cbiAgICAgIGNvbnN0IGFjY291bnRzID0gYXdhaXQgQWNjb3VudC5xdWVyeSgpLnJ1bkJlZm9yZSgocmVzdWx0LCBxKSA9PiB7XG4gICAgICAgIGNvbnN0IGFjY291bnRUeXBlc0lkcyA9IGFjY291bnRUeXBlcy5tYXAoKHQpID0+IHQuaWQpO1xuXG4gICAgICAgIGlmIChhY2NvdW50VHlwZXNJZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHEud2hlcmVJbignYWNjb3VudF90eXBlX2lkJywgYWNjb3VudFR5cGVzSWRzKTtcbiAgICAgICAgfVxuICAgICAgICBxLndoZXJlKCdhY3RpdmUnLCBmb3JtLmFjdGl2ZV9hY2NvdW50cyA9PT0gdHJ1ZSk7XG4gICAgICAgIHEud2l0aEdyYXBoRmV0Y2hlZCgndHJhbnNhY3Rpb25zJyk7XG4gICAgICB9KTtcbiAgICAgICAgXG4gICAgICAvLyBjb25zdCBhY2NvdW50c05lc3RlZFNldCA9IE5lc3RlZFNldC5mcm9tKGFjY291bnRzKTtcblxuICAgICAgY29uc3QgZnJvbURhdGUgPSBtb21lbnQoYnVkZ2V0LnllYXIpLnN0YXJ0T2YoJ3llYXInKVxuICAgICAgICAuYWRkKGJ1ZGdldC5yYW5nZU9mZnNldCwgYnVkZ2V0LnJhbmdlQnkpLnRvRGF0ZSgpO1xuXG4gICAgICBjb25zdCB0b0RhdGUgPSBtb21lbnQoYnVkZ2V0LnllYXIpLmVuZE9mKCd5ZWFyJykudG9EYXRlKCk7XG5cbiAgICAgIGNvbnN0IGRhdGVSYW5nZSA9IG1vbWVudC5yYW5nZShmcm9tRGF0ZSwgdG9EYXRlKTtcbiAgICAgIGNvbnN0IGRhdGVSYW5nZUNvbGxlY3Rpb24gPSBBcnJheS5mcm9tKGRhdGVSYW5nZS5ieShidWRnZXQucmFuZ2VCeSwge1xuICAgICAgICBzdGVwOiBidWRnZXQucmFuZ2VJbmNyZW1lbnQsIGV4Y2x1ZGVFbmQ6IGZhbHNlLCBleGNsdWRlU3RhcnQ6IGZhbHNlLFxuICAgICAgfSkpO1xuXG4gICAgLy8gICAvLyBjb25zdCBhY2NvdW50cyA9IHtcbiAgICAvLyAgIC8vICAgYXNzZXRzOiBbXG4gICAgLy8gICAvLyAgICAge1xuICAgIC8vICAgLy8gICAgICAgbmFtZTogJycsXG4gICAgLy8gICAvLyAgICAgICBjb2RlOiAnJyxcbiAgICAvLyAgIC8vICAgICAgIHRvdGFsRW50cmllczogW1xuICAgIC8vICAgLy8gICAgICAgICB7XG5cbiAgICAvLyAgIC8vICAgICAgICAgfVxuICAgIC8vICAgLy8gICAgICAgXSxcbiAgICAvLyAgIC8vICAgICAgIGNoaWxkcmVuOiBbXG4gICAgLy8gICAvLyAgICAgICAgIHtcbiAgICAvLyAgIC8vICAgICAgICAgICBuYW1lOiAnJyxcbiAgICAvLyAgIC8vICAgICAgICAgICBjb2RlOiAnJyxcbiAgICAvLyAgIC8vICAgICAgICAgICBlbnRyaWVzOiBbXG4gICAgLy8gICAvLyAgICAgICAgICAgICB7XG5cbiAgICAvLyAgIC8vICAgICAgICAgICAgIH1cbiAgICAvLyAgIC8vICAgICAgICAgICBdXG4gICAgLy8gICAvLyAgICAgICAgIH1cbiAgICAvLyAgIC8vICAgICAgIF1cbiAgICAvLyAgIC8vICAgICB9XG4gICAgLy8gICAvLyAgIF1cbiAgICAvLyAgIC8vIH1cblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgY29sdW1uczogZGF0ZVJhbmdlQ29sbGVjdGlvbi5tYXAoZCA9PiBkLmZvcm1hdChkYXRlUmFuZ2VGb3JtYXQoYnVkZ2V0LnJhbmdlQnkpKSksXG4gICAgICAgIC8vIGFjY291bnRzOiB7XG4gICAgICAgIC8vICAgYXNzZXQ6IFtdLFxuICAgICAgICAvLyAgIGxpYWJpbGl0aWVzOiBbXSxcbiAgICAgICAgLy8gICBlcXVhaXR5OiBbXSxcblxuICAgICAgICAvLyAgIGluY29tZTogW10sXG4gICAgICAgIC8vICAgZXhwZW5zZXM6IFtdLFxuICAgICAgICAvLyB9XG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxufSIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgY2hlY2ssIHZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcblxuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci5nZXQoJy9hbGwnLFxuICAgICAgdGhpcy5hbGwudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmFsbC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvcmVnaXN0ZXJlZCcsXG4gICAgICB0aGlzLnJlZ2lzdGVyZWQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnJlZ2lzdGVyZWQuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICBhbGw6IHtcbiAgICB2YWxpZGF0aW9uOiBbXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIGN1cnJlbmNpZXM6IFtcbiAgICAgICAgICB7IGN1cnJlbmN5X2NvZGU6ICdVU0QnLCBjdXJyZW5jeV9zaWduOiAnJCcgfSxcbiAgICAgICAgICB7IGN1cnJlbmN5X2NvZGU6ICdMWUQnLCBjdXJyZW5jeV9zaWduOiAnJyB9LFxuICAgICAgICBdLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICByZWdpc3RlcmVkOiB7XG4gICAgdmFsaWRhdGlvbjogW10sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBjdXJyZW5jaWVzOiBbXG4gICAgICAgICAgeyBjdXJyZW5jeV9jb2RlOiAnVVNEJywgY3VycmVuY3lfc2lnbjogJyQnIH0sXG4gICAgICAgICAgeyBjdXJyZW5jeV9jb2RlOiAnTFlEJywgY3VycmVuY3lfc2lnbjogJycgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59OyIsIlxuZXhwb3J0IGRlZmF1bHQge1xuXG5cbiAgcm91dGVyKCkge1xuXG4gIH0sXG4gIFxuICBhZGRFeGNoYW5nZVByaWNlOiB7XG4gICAgdmFsaWRhdGlvbjoge1xuICAgICAgXG4gICAgfSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG5cbiAgICB9LFxuICB9LFxufSIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHtcbiAgY2hlY2ssXG4gIHBhcmFtLFxuICBxdWVyeSxcbiAgdmFsaWRhdGlvblJlc3VsdCxcbn0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLm5ld0N1c3RvbWVyLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdDdXN0b21lci5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICB0aGlzLmVkaXRDdXN0b21lci52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdEN1c3RvbWVyLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgbmV3Q3VzdG9tZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnY3VzdG9tX3R5cGUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnZmlyc3RfbmFtZScpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdsYXN0X25hbWUnKSxcbiAgICAgIGNoZWNrKCdjb21wYW55X25hbWUnKSxcbiAgICAgIGNoZWNrKCdlbWFpbCcpLFxuICAgICAgY2hlY2soJ3dvcmtfcGhvbmUnKSxcbiAgICAgIGNoZWNrKCdwZXJzb25hbF9waG9uZScpLFxuXG4gICAgICBjaGVjaygnYmlsbGluZ19hZGRyZXNzLmNvdW50cnknKSxcbiAgICAgIGNoZWNrKCdiaWxsaW5nX2FkZHJlc3MuYWRkcmVzcycpLFxuICAgICAgY2hlY2soJ2JpbGxpbmdfYWRkcmVzcy5jaXR5JyksXG4gICAgICBjaGVjaygnYmlsbGluZ19hZGRyZXNzLnBob25lJyksXG4gICAgICBjaGVjaygnYmlsbGluZ19hZGRyZXNzLnppcF9jb2RlJyksXG5cbiAgICAgIGNoZWNrKCdzaGlwaW5nX2FkZHJlc3MuY291bnRyeScpLFxuICAgICAgY2hlY2soJ3NoaXBpbmdfYWRkcmVzcy5hZGRyZXNzJyksXG4gICAgICBjaGVjaygnc2hpcGluZ19hZGRyZXNzLmNpdHknKSxcbiAgICAgIGNoZWNrKCdzaGlwaW5nX2FkZHJlc3MucGhvbmUnKSxcbiAgICAgIGNoZWNrKCdzaGlwaW5nX2FkZHJlc3MuemlwX2NvZGUnKSxcblxuICAgICAgY2hlY2soJ2NvbnRhY3QuYWRkaXRpb25hbF9waG9uZScpLFxuICAgICAgY2hlY2soJ2NvbnRhY3QuYWRkaXRpb25hbF9lbWFpbCcpLFxuXG4gICAgICBjaGVjaygnY3VzdG9tX2ZpZWxkcycpLm9wdGlvbmFsKCkuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzLioua2V5JykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ2N1c3RvbV9maWVsZHMuKi52YWx1ZScpLmV4aXN0cygpLFxuXG4gICAgICBjaGVjaygnaW5hY3RpdmUnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgIF0sXG5cbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG5cbiAgICB9LFxuICB9LFxuXG4gIGVkaXRDdXN0b21lcjoge1xuICAgIHZhbGlkYXRpb246IFtcblxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuXG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7XG4gIGNoZWNrLFxuICBwYXJhbSxcbiAgcXVlcnksXG4gIHZhbGlkYXRpb25SZXN1bHQsXG59IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50JztcbmltcG9ydCB7IGRpZmZlcmVuY2UsIGNoYWluLCBvbWl0IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBFeHBlbnNlIGZyb20gJ0AvbW9kZWxzL0V4cGVuc2UnO1xuaW1wb3J0IEFjY291bnQgZnJvbSAnQC9tb2RlbHMvQWNjb3VudCc7XG5pbXBvcnQgSm91cm5hbFBvc3RlciBmcm9tICdAL3NlcnZpY2VzL0FjY291bnRpbmcvSm91cm5hbFBvc3Rlcic7XG5pbXBvcnQgSm91cm5hbEVudHJ5IGZyb20gJ0Avc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsRW50cnknO1xuaW1wb3J0IEpXVEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgQWNjb3VudFRyYW5zYWN0aW9uIGZyb20gJ0AvbW9kZWxzL0FjY291bnRUcmFuc2FjdGlvbic7XG5pbXBvcnQgVmlldyBmcm9tICdAL21vZGVscy9WaWV3JztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICcuLi8uLi9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IFJlc291cmNlQ3VzdG9tRmllbGRSZXBvc2l0b3J5IGZyb20gJ0Avc2VydmljZXMvQ3VzdG9tRmllbGRzL1Jlc291cmNlQ3VzdG9tRmllbGRSZXBvc2l0b3J5JztcbmltcG9ydCB7XG4gIHZhbGlkYXRlVmlld1JvbGVzLFxuICBtYXBWaWV3Um9sZXNUb0NvbmRpdGlvbmFscyxcbn0gZnJvbSAnQC9saWIvVmlld1JvbGVzQnVpbGRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIHJvdXRlci51c2UoSldUQXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLm5ld0V4cGVuc2UudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm5ld0V4cGVuc2UuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQvcHVibGlzaCcsXG4gICAgICB0aGlzLnB1Ymxpc2hFeHBlbnNlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5wdWJsaXNoRXhwZW5zZS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOmlkJyxcbiAgICAgIHRoaXMuZGVsZXRlRXhwZW5zZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlRXhwZW5zZS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnL2J1bGsnLFxuICAgICAgdGhpcy5idWxrQWRkRXhwZW5zZXMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmJ1bGtBZGRFeHBlbnNlcy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICB0aGlzLnVwZGF0ZUV4cGVuc2UudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnVwZGF0ZUV4cGVuc2UuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLycsXG4gICAgICB0aGlzLmxpc3RFeHBlbnNlcy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubGlzdEV4cGVuc2VzLmhhbmRsZXIpKTtcblxuICAgIC8vIHJvdXRlci5nZXQoJy86aWQnLFxuICAgIC8vICAgdGhpcy5nZXRFeHBlbnNlLnZhbGlkYXRpb24sXG4gICAgLy8gICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRFeHBlbnNlLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIFNhdmVzIGEgbmV3IGV4cGVuc2UuXG4gICAqL1xuICBuZXdFeHBlbnNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ2RhdGUnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ3BheW1lbnRfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZXhwZW5zZV9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnYW1vdW50JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgY2hlY2soJ2N1cnJlbmN5X2NvZGUnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2V4Y2hhbmdlX3JhdGUnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdwdWJsaXNoJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzJykub3B0aW9uYWwoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2N1c3RvbV9maWVsZHMuKi5rZXknKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnY3VzdG9tX2ZpZWxkcy4qLnZhbHVlJykuZXhpc3RzKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZm9ybSA9IHtcbiAgICAgICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICAgICAgcHVibGlzaGVkOiBmYWxzZSxcbiAgICAgICAgY3VzdG9tX2ZpZWxkczogW10sXG4gICAgICAgIC4uLnJlcS5ib2R5LFxuICAgICAgfTtcbiAgICAgIC8vIENvbnZlcnQgdGhlIGRhdGUgdG8gdGhlIGdlbmVyYWwgZm9ybWF0LlxuICAgICAgZm9ybS5kYXRlID0gbW9tZW50KGZvcm0uZGF0ZSkuZm9ybWF0KCdZWVlZLU1NLUREJyk7XG5cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuICAgICAgY29uc3QgcGF5bWVudEFjY291bnQgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KClcbiAgICAgICAgLmZpbmRCeUlkKGZvcm0ucGF5bWVudF9hY2NvdW50X2lkKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXBheW1lbnRBY2NvdW50KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1BBWU1FTlQuQUNDT1VOVC5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBleHBlbnNlQWNjb3VudCA9IGF3YWl0IEFjY291bnQucXVlcnkoKS5maW5kQnlJZChmb3JtLmV4cGVuc2VfYWNjb3VudF9pZCkuZmlyc3QoKTtcblxuICAgICAgaWYgKCFleHBlbnNlQWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdFWFBFTlNFLkFDQ09VTlQuTk9ULkZPVU5EJywgY29kZTogMjAwIH0pO1xuICAgICAgfVxuICAgICAgLy8gY29uc3QgY3VzdG9tRmllbGRzID0gbmV3IFJlc291cmNlQ3VzdG9tRmllbGRSZXBvc2l0b3J5KEV4cGVuc2UpO1xuICAgICAgLy8gYXdhaXQgY3VzdG9tRmllbGRzLmxvYWQoKTtcblxuICAgICAgLy8gaWYgKGN1c3RvbUZpZWxkcy52YWxpZGF0ZUV4aXN0Q3VzdG9tRmllbGRzKCkpIHtcbiAgICAgIC8vICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQ1VTVE9NLkZJRUxEUy5TTFVHUy5OT1QuRVhJU1RTJywgY29kZTogNDAwIH0pO1xuICAgICAgLy8gfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZXhwZW5zZVRyYW5zYWN0aW9uID0gYXdhaXQgRXhwZW5zZS5xdWVyeSgpLmluc2VydEFuZEZldGNoKHtcbiAgICAgICAgLi4ub21pdChmb3JtLCBbJ2N1c3RvbV9maWVsZHMnXSksXG4gICAgICB9KTtcbiAgICAgIC8vIGN1c3RvbUZpZWxkcy5maWxsQ3VzdG9tRmllbGRzKGV4cGVuc2VUcmFuc2FjdGlvbi5pZCwgZm9ybS5jdXN0b21fZmllbGRzKTtcblxuICAgICAgY29uc3Qgam91cm5hbEVudHJpZXMgPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuICAgICAgY29uc3QgY3JlZGl0RW50cnkgPSBuZXcgSm91cm5hbEVudHJ5KHtcbiAgICAgICAgY3JlZGl0OiBmb3JtLmFtb3VudCxcbiAgICAgICAgcmVmZXJlbmNlSWQ6IGV4cGVuc2VUcmFuc2FjdGlvbi5pZCxcbiAgICAgICAgcmVmZXJlbmNlVHlwZTogRXhwZW5zZS5yZWZlcmVuY2VUeXBlLFxuICAgICAgICBkYXRlOiBmb3JtLmRhdGUsXG4gICAgICAgIGFjY291bnQ6IGV4cGVuc2VBY2NvdW50LmlkLFxuICAgICAgICBhY2NvdW50Tm9ybWFsOiAnZGViaXQnLFxuICAgICAgICBkcmFmdDogIWZvcm0ucHVibGlzaGVkLFxuICAgICAgfSk7XG4gICAgICBjb25zdCBkZWJpdEVudHJ5ID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAgIGRlYml0OiBmb3JtLmFtb3VudCxcbiAgICAgICAgcmVmZXJlbmNlSWQ6IGV4cGVuc2VUcmFuc2FjdGlvbi5pZCxcbiAgICAgICAgcmVmZXJlbmNlVHlwZTogRXhwZW5zZS5yZWZlcmVuY2VUeXBlLFxuICAgICAgICBkYXRlOiBmb3JtLmRhdGUsXG4gICAgICAgIGFjY291bnQ6IHBheW1lbnRBY2NvdW50LmlkLFxuICAgICAgICBhY2NvdW50Tm9ybWFsOiAnZGViaXQnLFxuICAgICAgICBkcmFmdDogIWZvcm0ucHVibGlzaGVkLFxuICAgICAgfSk7XG4gICAgICBqb3VybmFsRW50cmllcy5jcmVkaXQoY3JlZGl0RW50cnkpO1xuICAgICAgam91cm5hbEVudHJpZXMuZGViaXQoZGViaXRFbnRyeSk7XG5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgLy8gY3VzdG9tRmllbGRzLnNhdmVDdXN0b21GaWVsZHMoZXhwZW5zZVRyYW5zYWN0aW9uLmlkKSxcbiAgICAgICAgam91cm5hbEVudHJpZXMuc2F2ZUVudHJpZXMoKSxcbiAgICAgICAgam91cm5hbEVudHJpZXMuc2F2ZUJhbGFuY2UoKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGV4cGVuc2VUcmFuc2FjdGlvbi5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBCdWxrIGFkZCBleHBuZXNlcyB0byB0aGUgZ2l2ZW4gYWNjb3VudHMuXG4gICAqL1xuICBidWxrQWRkRXhwZW5zZXM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnZXhwZW5zZXMnKS5leGlzdHMoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2V4cGVuc2VzLiouZGF0ZScpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBjaGVjaygnZXhwZW5zZXMuKi5wYXltZW50X2FjY291bnRfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2V4cGVuc2VzLiouZXhwZW5zZV9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmRlc2NyaXB0aW9uJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmFtb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdleHBlbnNlcy4qLmN1cnJlbmN5X2NvZGUnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2V4cGVuc2VzLiouZXhjaGFuZ2VfcmF0ZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcblxuICAgICAgY29uc3QgcGF5bWVudEFjY291bnRzSWRzID0gY2hhaW4oZm9ybS5leHBlbnNlcylcbiAgICAgICAgLm1hcCgoZSkgPT4gZS5wYXltZW50X2FjY291bnRfaWQpLnVuaXEoKS52YWx1ZSgpO1xuICAgICAgY29uc3QgZXhwZW5zZUFjY291bnRzSWRzID0gY2hhaW4oZm9ybS5leHBlbnNlcylcbiAgICAgICAgLm1hcCgoZSkgPT4gZS5leHBlbnNlX2FjY291bnRfaWQpLnVuaXEoKS52YWx1ZSgpO1xuXG4gICAgICBjb25zdCBbZXhwZW5zZXNBY2NvdW50cywgcGF5bWVudEFjY291bnRzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgQWNjb3VudC5xdWVyeSgpLndoZXJlSW4oJ2lkJywgZXhwZW5zZUFjY291bnRzSWRzKSxcbiAgICAgICAgQWNjb3VudC5xdWVyeSgpLndoZXJlSW4oJ2lkJywgcGF5bWVudEFjY291bnRzSWRzKSxcbiAgICAgIF0pO1xuICAgICAgY29uc3Qgc3RvcmVkRXhwZW5zZXNBY2NvdW50c0lkcyA9IGV4cGVuc2VzQWNjb3VudHMubWFwKChhKSA9PiBhLmlkKTtcbiAgICAgIGNvbnN0IHN0b3JlZFBheW1lbnRBY2NvdW50c0lkcyA9IHBheW1lbnRBY2NvdW50cy5tYXAoKGEpID0+IGEuaWQpO1xuXG4gICAgICBjb25zdCBub3RGb3VuZFBheW1lbnRBY2NvdW50c0lkcyA9IGRpZmZlcmVuY2UoZXhwZW5zZUFjY291bnRzSWRzLCBzdG9yZWRFeHBlbnNlc0FjY291bnRzSWRzKTtcbiAgICAgIGNvbnN0IG5vdEZvdW5kRXhwZW5zZUFjY291bnRzSWRzID0gZGlmZmVyZW5jZShwYXltZW50QWNjb3VudHNJZHMsIHN0b3JlZFBheW1lbnRBY2NvdW50c0lkcyk7XG5cbiAgICAgIGlmIChub3RGb3VuZFBheW1lbnRBY2NvdW50c0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnUEFZTUVOWS5BQ0NPVU5UUy5OT1QuRk9VTkQnLFxuICAgICAgICAgIGNvZGU6IDEwMCxcbiAgICAgICAgICBhY2NvdW50czogbm90Rm91bmRQYXltZW50QWNjb3VudHNJZHMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKG5vdEZvdW5kRXhwZW5zZUFjY291bnRzSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdFWFBFTlNFLkFDQ09VTlRTLk5PVC5GT1VORCcsXG4gICAgICAgICAgY29kZTogMjAwLFxuICAgICAgICAgIGFjY291bnRzOiBub3RGb3VuZEV4cGVuc2VBY2NvdW50c0lkcyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwgeyByZWFzb25zOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBleHBlbnNlU2F2ZU9wZXJzID0gW107XG4gICAgICBjb25zdCBqb3VybmFsUG9zdGVyID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcblxuICAgICAgZm9ybS5leHBlbnNlcy5mb3JFYWNoKGFzeW5jIChleHBlbnNlKSA9PiB7XG4gICAgICAgIGNvbnN0IGV4cGVuc2VTYXZlT3BlciA9IEV4cGVuc2UucXVlcnkoKS5pbnNlcnQoeyAuLi5leHBlbnNlIH0pO1xuICAgICAgICBleHBlbnNlU2F2ZU9wZXJzLnB1c2goZXhwZW5zZVNhdmVPcGVyKTtcbiAgICAgIH0pO1xuICAgICAgLy8gV2FpdCB1bml0IHNhdmUgYWxsIGV4cGVuc2UgdHJhbnNhY3Rpb25zLlxuICAgICAgY29uc3Qgc2F2ZWRFeHBlbnNlVHJhbnNhY3Rpb25zID0gYXdhaXQgUHJvbWlzZS5hbGwoZXhwZW5zZVNhdmVPcGVycyk7XG5cbiAgICAgIHNhdmVkRXhwZW5zZVRyYW5zYWN0aW9ucy5mb3JFYWNoKChleHBlbnNlKSA9PiB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBtb21lbnQoZXhwZW5zZS5kYXRlKS5mb3JtYXQoJ1lZWVktREQtTU0nKTtcblxuICAgICAgICBjb25zdCBkZWJpdCA9IG5ldyBKb3VybmFsRW50cnkoe1xuICAgICAgICAgIGRlYml0OiBleHBlbnNlLmFtb3VudCxcbiAgICAgICAgICByZWZlcmVuY2VJZDogZXhwZW5zZS5pZCxcbiAgICAgICAgICByZWZlcmVuY2VUeXBlOiBFeHBlbnNlLnJlZmVyZW5jZVR5cGUsXG4gICAgICAgICAgYWNjb3VudDogZXhwZW5zZS5wYXltZW50X2FjY291bnRfaWQsXG4gICAgICAgICAgYWNjb3VudE5vcm1hbDogJ2RlYml0JyxcbiAgICAgICAgICBkYXRlLFxuICAgICAgICB9KTtcbiAgICAgICAgY29uc3QgY3JlZGl0ID0gbmV3IEpvdXJuYWxFbnRyeSh7XG4gICAgICAgICAgY3JlZGl0OiBleHBlbnNlLmFtb3VudCxcbiAgICAgICAgICByZWZlcmVuY2VJZDogZXhwZW5zZS5pZCxcbiAgICAgICAgICByZWZlcmVuY2VUeXBlOiBFeHBlbnNlLnJlZmVyZW5jZUlkLFxuICAgICAgICAgIGFjY291bnQ6IGV4cGVuc2UuZXhwZW5zZV9hY2NvdW50X2lkLFxuICAgICAgICAgIGFjY291bnROb3JtYWw6ICdkZWJpdCcsXG4gICAgICAgICAgZGF0ZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGpvdXJuYWxQb3N0ZXIuY3JlZGl0KGNyZWRpdCk7XG4gICAgICAgIGpvdXJuYWxQb3N0ZXIuZGViaXQoZGViaXQpO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIFNhdmUgZXhwZW5zZSBqb3VybmFsIGVudHJpZXMgYW5kIGJhbGFuY2UgY2hhbmdlLlxuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBqb3VybmFsUG9zdGVyLnNhdmVFbnRyaWVzKCksXG4gICAgICAgIGpvdXJuYWxQb3N0ZXIuc2F2ZUJhbGFuY2UoKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUHVibGlzaCB0aGUgZ2l2ZW4gZXhwZW5zZSBpZC5cbiAgICovXG4gIHB1Ymxpc2hFeHBlbnNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcbiAgICAgIGNvbnN0IGV4cGVuc2UgPSBhd2FpdCBFeHBlbnNlLnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWV4cGVuc2UpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnRVhQRU5TRS5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChleHBlbnNlLnB1Ymxpc2hlZCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdFWFBFTlNFLkFMUkVBRFkuUFVCTElTSEVEJywgY29kZTogMjAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwMCkuc2VuZCh7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ3JlZmVyZW5jZV9pZCcsIGV4cGVuc2UuaWQpXG4gICAgICAgIC53aGVyZSgncmVmZXJlbmNlX3R5cGUnLCAnRXhwZW5zZScpXG4gICAgICAgIC5wYXRjaCh7XG4gICAgICAgICAgZHJhZnQ6IGZhbHNlLFxuICAgICAgICB9KTtcblxuICAgICAgYXdhaXQgRXhwZW5zZS5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnaWQnLCBleHBlbnNlLmlkKVxuICAgICAgICAudXBkYXRlKHsgcHVibGlzaGVkOiB0cnVlIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBwYWdpbmF0ZWQgZXhwZW5zZXMgbGlzdC5cbiAgICovXG4gIGxpc3RFeHBlbnNlczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdleHBlbnNlX2FjY291bnRfaWQnKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgncGF5bWVudF9hY2NvdW50X2lkJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ25vdGUnKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ3JhbmdlX2Zyb20nKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIHF1ZXJ5KCdyYW5nZV90bycpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9GbG9hdCgpLFxuICAgICAgcXVlcnkoJ2RhdGVfZnJvbScpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBxdWVyeSgnZGF0ZV90bycpLm9wdGlvbmFsKCkuaXNJU084NjAxKCksXG4gICAgICBxdWVyeSgnY29sdW1uX3NvcnRfb3JkZXInKS5vcHRpb25hbCgpLmlzSW4oWydjcmVhdGVkX2F0JywgJ2RhdGUnLCAnYW1vdW50J10pLFxuICAgICAgcXVlcnkoJ3NvcnRfb3JkZXInKS5vcHRpb25hbCgpLmlzSW4oWydkZXNjJywgJ2FzYyddKSxcbiAgICAgIHF1ZXJ5KCdwYWdlJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgcXVlcnkoJ3BhZ2Vfc2l6ZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdjdXN0b21fdmlld19pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIHBhZ2Vfc2l6ZTogMTAsXG4gICAgICAgIHBhZ2U6IDEsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG4gICAgICBjb25zdCBlcnJvclJlYXNvbnMgPSBbXTtcbiAgICAgIGNvbnN0IGV4cGVuc2VSZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KCkud2hlcmUoJ25hbWUnLCAnZXhwZW5zZXMnKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIWV4cGVuc2VSZXNvdXJjZSkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdFWFBFTlNFX1JFU09VUkNFX05PVF9GT1VORCcsIGNvZGU6IDMwMCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBWaWV3LnF1ZXJ5KCkub25CdWlsZCgoYnVpbGRlcikgPT4ge1xuICAgICAgICBpZiAoZmlsdGVyLmN1c3RvbV92aWV3X2lkKSB7XG4gICAgICAgICAgYnVpbGRlci53aGVyZSgnaWQnLCBmaWx0ZXIuY3VzdG9tX3ZpZXdfaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1aWxkZXIud2hlcmUoJ2Zhdm91cml0ZScsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIGJ1aWxkZXIud2hlcmUoJ3Jlc291cmNlX2lkJywgZXhwZW5zZVJlc291cmNlLmlkKTtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCd2aWV3Um9sZXMuZmllbGQnKTtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCdjb2x1bW5zJyk7XG5cbiAgICAgICAgYnVpbGRlci5maXJzdCgpO1xuICAgICAgfSk7XG4gICAgICBsZXQgdmlld0NvbmRpdGlvbmFscyA9IFtdO1xuXG4gICAgICBpZiAodmlldyAmJiB2aWV3LnZpZXdSb2xlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHZpZXdDb25kaXRpb25hbHMgPSBtYXBWaWV3Um9sZXNUb0NvbmRpdGlvbmFscyh2aWV3LnZpZXdSb2xlcyk7XG5cbiAgICAgICAgaWYgKCF2YWxpZGF0ZVZpZXdSb2xlcyh2aWV3Q29uZGl0aW9uYWxzLCB2aWV3LnJvbGVzTG9naWNFeHByZXNzaW9uKSkge1xuICAgICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1ZJRVcuTE9HSUMuRVhQUkVTU0lPTi5JTlZBTElEJywgY29kZTogNDAwIH0pXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghdmlldyAmJiBmaWx0ZXIuY3VzdG9tX3ZpZXdfaWQpIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnVklFV19OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwgeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhwZW5zZXMgPSBhd2FpdCBFeHBlbnNlLnF1ZXJ5KCkub25CdWlsZCgoYnVpbGRlcikgPT4ge1xuICAgICAgICBidWlsZGVyLndpdGhHcmFwaEZldGNoZWQoJ3BheW1lbnRBY2NvdW50Jyk7XG4gICAgICAgIGJ1aWxkZXIud2l0aEdyYXBoRmV0Y2hlZCgnZXhwZW5zZUFjY291bnQnKTtcbiAgICAgICAgYnVpbGRlci53aXRoR3JhcGhGZXRjaGVkKCd1c2VyJyk7XG5cbiAgICAgICAgaWYgKHZpZXdDb25kaXRpb25hbHMubGVuZ3RoKSB7XG4gICAgICAgICAgYnVpbGRlci5tb2RpZnkoJ3ZpZXdSb2xlc0J1aWxkZXInLCB2aWV3Q29uZGl0aW9uYWxzLCB2aWV3LnJvbGVzTG9naWNFeHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyQnlBbW91bnRSYW5nZScsIGZpbHRlci5yYW5nZV9mcm9tLCBmaWx0ZXIudG9fcmFuZ2UpO1xuICAgICAgICBidWlsZGVyLm1vZGlmeSgnZmlsdGVyQnlEYXRlUmFuZ2UnLCBmaWx0ZXIuZGF0ZV9mcm9tLCBmaWx0ZXIuZGF0ZV90byk7XG4gICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJCeUV4cGVuc2VBY2NvdW50JywgZmlsdGVyLmV4cGVuc2VfYWNjb3VudF9pZCk7XG4gICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJCeVBheW1lbnRBY2NvdW50JywgZmlsdGVyLnBheW1lbnRfYWNjb3VudF9pZCk7XG4gICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdvcmRlckJ5JywgZmlsdGVyLmNvbHVtbl9zb3J0X29yZGVyLCBmaWx0ZXIuc29ydF9vcmRlcik7XG4gICAgICB9KS5wYWdlKGZpbHRlci5wYWdlIC0gMSwgZmlsdGVyLnBhZ2Vfc2l6ZSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIC4uLih2aWV3KSA/IHtcbiAgICAgICAgICBjdXN0b21WaWV3SWQ6IHZpZXcuaWQsIFxuICAgICAgICAgIHZpZXdDb2x1bW5zOiB2aWV3LmNvbHVtbnMsXG4gICAgICAgICAgdmlld0NvbmRpdGlvbmFscyxcbiAgICAgICAgfSA6IHt9LFxuICAgICAgICBleHBlbnNlcyxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGRlbGV0ZUV4cGVuc2U6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBleHBlbnNlVHJhbnNhY3Rpb24gPSBhd2FpdCBFeHBlbnNlLnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWV4cGVuc2VUcmFuc2FjdGlvbikge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDQpLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0VYUEVOU0UuVFJBTlNBQ1RJT04uTk9ULkZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4cGVuc2VFbnRyaWVzID0gYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdyZWZlcmVuY2VfdHlwZScsICdFeHBlbnNlJylcbiAgICAgICAgLndoZXJlKCdyZWZlcmVuY2VfaWQnLCBleHBlbnNlVHJhbnNhY3Rpb24uaWQpO1xuXG4gICAgICBjb25zdCBleHBlbnNlRW50cmllc0NvbGxlY3QgPSBuZXcgSm91cm5hbFBvc3RlcigpO1xuICAgICAgZXhwZW5zZUVudHJpZXNDb2xsZWN0LmxvYWRFbnRyaWVzKGV4cGVuc2VFbnRyaWVzKTtcbiAgICAgIGV4cGVuc2VFbnRyaWVzQ29sbGVjdC5yZXZlcnNlRW50cmllcygpO1xuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIEV4cGVuc2UucXVlcnkoKS5maW5kQnlJZChleHBlbnNlVHJhbnNhY3Rpb24uaWQpLmRlbGV0ZSgpLFxuICAgICAgICBleHBlbnNlRW50cmllc0NvbGxlY3QuZGVsZXRlRW50cmllcygpLFxuICAgICAgICBleHBlbnNlRW50cmllc0NvbGxlY3Quc2F2ZUJhbGFuY2UoKSxcbiAgICAgIF0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogVXBkYXRlIGRldGFpbHMgb2YgdGhlIGdpdmVuIGFjY291bnQuXG4gICAqL1xuICB1cGRhdGVFeHBlbnNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIGNoZWNrKCdwYXltZW50X2FjY291bnRfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2V4cGVuc2VfYWNjb3VudF9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2Ftb3VudCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvRmxvYXQoKSxcbiAgICAgIGNoZWNrKCdjdXJyZW5jeV9jb2RlJykub3B0aW9uYWwoKSxcbiAgICAgIGNoZWNrKCdleGNoYW5nZV9yYXRlJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0Zsb2F0KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGV4cGVuc2VUcmFuc2FjdGlvbiA9IGF3YWl0IEV4cGVuc2UucXVlcnkoKS5maW5kQnlJZChpZCk7XG5cbiAgICAgIGlmICghZXhwZW5zZVRyYW5zYWN0aW9uKSB7XG4gICAgICAgIHJldHVybiByZXMuc3RhdHVzKDQwNCkuc2VuZCh7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnRVhQRU5TRS5UUkFOU0FDVElPTi5OT1QuRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGRldGFpbHMgb2YgdGhlIGdpdmVuIGV4cGVuc2UgaWQuXG4gICAqL1xuICBnZXRFeHBlbnNlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZXhwZW5zZVRyYW5zYWN0aW9uID0gYXdhaXQgRXhwZW5zZS5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcblxuICAgICAgaWYgKCFleHBlbnNlVHJhbnNhY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDA0KS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdFWFBFTlNFLlRSQU5TQUNUSU9OLk5PVC5GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV4cGVuc2VDRk1ldGFkYXRhUmVwbyA9IG5ldyBSZXNvdXJjZUN1c3RvbUZpZWxkUmVwb3NpdG9yeShFeHBlbnNlKTtcbiAgICAgIGF3YWl0IGV4cGVuc2VDRk1ldGFkYXRhUmVwby5sb2FkKCk7XG4gICAgICBhd2FpdCBleHBlbnNlQ0ZNZXRhZGF0YVJlcG8uZmV0Y2hDdXN0b21GaWVsZHNNZXRhZGF0YShleHBlbnNlVHJhbnNhY3Rpb24uaWQpO1xuXG4gICAgICBjb25zdCBleHBlbnNlQ3VzRmllbGRzTWV0YWRhdGEgPSBleHBlbnNlQ0ZNZXRhZGF0YVJlcG8uZ2V0TWV0YWRhdGEoZXhwZW5zZVRyYW5zYWN0aW9uLmlkKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgLi4uZXhwZW5zZVRyYW5zYWN0aW9uLFxuICAgICAgICBjdXN0b21fZmllbGRzOiBbXG4gICAgICAgICAgLi4uZXhwZW5zZUN1c0ZpZWxkc01ldGFkYXRhLnRvQXJyYXkoKSxcbiAgICAgICAgXSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IGV4cHJlc3MgZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgeyBjaGVjaywgcGFyYW0sIHZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgUmVzb3VyY2VGaWVsZCBmcm9tICdAL21vZGVscy9SZXNvdXJjZUZpZWxkJztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICdAL21vZGVscy9SZXNvdXJjZSc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJy4uL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcblxuLyoqXG4gKiBUeXBlcyBvZiB0aGUgY3VzdG9tIGZpZWxkcy5cbiAqL1xuY29uc3QgVFlQRVMgPSBbJ3RleHQnLCAnZW1haWwnLCAnbnVtYmVyJywgJ3VybCcsICdwZXJjZW50YWdlJywgJ2NoZWNrYm94JywgJ3JhZGlvJywgJ3RleHRhcmVhJ107XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3RvciBtZXRob2QuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvcmVzb3VyY2UvOnJlc291cmNlX25hbWUnLFxuICAgICAgdGhpcy5hZGROZXdGaWVsZC52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuYWRkTmV3RmllbGQuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86ZmllbGRfaWQnLFxuICAgICAgdGhpcy5lZGl0RmllbGQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmVkaXRGaWVsZC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnL3N0YXR1cy86ZmllbGRfaWQnLFxuICAgICAgdGhpcy5jaGFuZ2VTdGF0dXMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmNoYW5nZVN0YXR1cy5oYW5kbGVyKSk7XG5cbiAgICAvLyByb3V0ZXIuZ2V0KCcvOmZpZWxkX2lkJyxcbiAgICAvLyAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldEZpZWxkLmhhbmRsZXIpKTtcblxuICAgIC8vIHJvdXRlci5kZWxldGUoJy86ZmllbGRfaWQnLFxuICAgIC8vICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZGVsZXRlRmllbGQuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogQWRkcyBhIG5ldyBmaWVsZCBjb250cm9sIHRvIHRoZSBnaXZlbiByZXNvdXJjZS5cbiAgICogQHBhcmFtIHtSZXF1ZXN0fSByZXEgLVxuICAgKiBAcGFyYW0ge1Jlc3BvbnNlfSByZXMgLVxuICAgKi9cbiAgYWRkTmV3RmllbGQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgncmVzb3VyY2VfbmFtZScpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdsYWJlbCcpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdkYXRhX3R5cGUnKS5leGlzdHMoKS5pc0luKFRZUEVTKSxcbiAgICAgIGNoZWNrKCdoZWxwX3RleHQnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ2RlZmF1bHQnKS5vcHRpb25hbCgpLFxuICAgICAgY2hlY2soJ29wdGlvbnMnKS5vcHRpb25hbCgpLmlzQXJyYXkoKSxcbiAgICAgIGNoZWNrKCdvcHRpb25zLioua2V5JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdvcHRpb25zLioudmFsdWUnKS5leGlzdHMoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgcmVzb3VyY2VfbmFtZTogcmVzb3VyY2VOYW1lIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgUmVzb3VyY2UucXVlcnkoKS53aGVyZSgnbmFtZScsIHJlc291cmNlTmFtZSkuZmlyc3QoKTtcblxuICAgICAgaWYgKCFyZXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1JFU09VUkNFX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmb3JtID0geyBvcHRpb25zOiBbXSwgLi4ucmVxLmJvZHkgfTtcbiAgICAgIGNvbnN0IGNob2ljZXMgPSBmb3JtLm9wdGlvbnMubWFwKChvcHRpb24pID0+ICh7IGtleTogb3B0aW9uLmtleSwgdmFsdWU6IG9wdGlvbi52YWx1ZSB9KSk7XG5cbiAgICAgIGNvbnN0IHN0b3JlZFJlc291cmNlID0gYXdhaXQgUmVzb3VyY2VGaWVsZC5xdWVyeSgpLmluc2VydEFuZEZldGNoKHtcbiAgICAgICAgZGF0YV90eXBlOiBmb3JtLmRhdGFfdHlwZSxcbiAgICAgICAgbGFiZWxfbmFtZTogZm9ybS5sYWJlbCxcbiAgICAgICAgaGVscF90ZXh0OiBmb3JtLmhlbHBfdGV4dCxcbiAgICAgICAgZGVmYXVsdDogZm9ybS5kZWZhdWx0LFxuICAgICAgICByZXNvdXJjZV9pZDogcmVzb3VyY2UuaWQsXG4gICAgICAgIG9wdGlvbnM6IGNob2ljZXMsXG4gICAgICAgIGluZGV4OiAtMSxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHN0b3JlZFJlc291cmNlLmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEVkaXQgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gZmllbGQuXG4gICAqL1xuICBlZGl0RmllbGQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnZmllbGRfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2xhYmVsJykuZXhpc3RzKCkuZXNjYXBlKCkudHJpbSgpLFxuICAgICAgY2hlY2soJ2RhdGFfdHlwZScpLmV4aXN0cygpLmlzSW4oVFlQRVMpLFxuICAgICAgY2hlY2soJ2hlbHBfdGV4dCcpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnZGVmYXVsdCcpLm9wdGlvbmFsKCksXG4gICAgICBjaGVjaygnb3B0aW9ucycpLm9wdGlvbmFsKCkuaXNBcnJheSgpLFxuICAgICAgY2hlY2soJ29wdGlvbnMuKi5rZXknKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ29wdGlvbnMuKi52YWx1ZScpLmV4aXN0cygpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBmaWVsZF9pZDogZmllbGRJZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWVsZCA9IGF3YWl0IFJlc291cmNlRmllbGQucXVlcnkoKS5maW5kQnlJZChmaWVsZElkKTtcblxuICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ0ZJRUxEX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICAvLyBTZXRzIHRoZSBkZWZhdWx0IHZhbHVlIG9mIG9wdGlvbmFsIGZpZWxkcy5cbiAgICAgIGNvbnN0IGZvcm0gPSB7IG9wdGlvbnM6IFtdLCAuLi5yZXEuYm9keSB9O1xuICAgICAgY29uc3QgY2hvaWNlcyA9IGZvcm0ub3B0aW9ucy5tYXAoKG9wdGlvbikgPT4gKHsga2V5OiBvcHRpb24ua2V5LCB2YWx1ZTogb3B0aW9uLnZhbHVlIH0pKTtcblxuICAgICAgYXdhaXQgUmVzb3VyY2VGaWVsZC5xdWVyeSgpLmZpbmRCeUlkKGZpZWxkLmlkKS51cGRhdGUoe1xuICAgICAgICBkYXRhX3R5cGU6IGZvcm0uZGF0YV90eXBlLFxuICAgICAgICBsYWJlbF9uYW1lOiBmb3JtLmxhYmVsLFxuICAgICAgICBoZWxwX3RleHQ6IGZvcm0uaGVscF90ZXh0LFxuICAgICAgICBkZWZhdWx0OiBmb3JtLmRlZmF1bHQsXG4gICAgICAgIG9wdGlvbnM6IGNob2ljZXMsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBmaWVsZC5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgZmllbGRzIGxpc3Qgb2YgdGhlIGdpdmVuIHJlc291cmNlLlxuICAgKiBAcGFyYW0ge1JlcXVlc3R9IHJlcSAtXG4gICAqIEBwYXJhbSB7UmVzcG9uc2V9IHJlcyAtXG4gICAqL1xuICBmaWVsZHNMaXN0OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ3Jlc291cmNlX25hbWUnKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgcmVzb3VyY2VfbmFtZTogcmVzb3VyY2VOYW1lIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgcmVzb3VyY2UgPSBhd2FpdCBSZXNvdXJjZS5xdWVyeSgpLndoZXJlKCduYW1lJywgcmVzb3VyY2VOYW1lKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXJlc291cmNlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUkVTT1VSQ0VfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpZWxkcyA9IGF3YWl0IFJlc291cmNlRmllbGQud2hlcmUoJ3Jlc291cmNlX2lkJywgcmVzb3VyY2UuaWQpLmZldGNoQWxsKCk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGZpZWxkczogZmllbGRzLnRvSlNPTigpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIENoYW5nZSBzdGF0dXMgb2YgdGhlIGdpdmVuIGZpZWxkLlxuICAgKi9cbiAgY2hhbmdlU3RhdHVzOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2ZpZWxkX2lkJykudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdhY3RpdmUnKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgZmllbGRfaWQ6IGZpZWxkSWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBmaWVsZCA9IGF3YWl0IFJlc291cmNlRmllbGQucXVlcnkoKS5maW5kQnlJZChmaWVsZElkKTtcblxuICAgICAgaWYgKCFmaWVsZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ05PVF9GT1VORF9GSUVMRCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgYWN0aXZlIH0gPSByZXEuYm9keTtcbiAgICAgIGF3YWl0IFJlc291cmNlRmllbGQucXVlcnkoKS5maW5kQnlJZChmaWVsZC5pZCkucGF0Y2goeyBhY3RpdmUgfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBmaWVsZC5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBkZXRhaWxzIG9mIHRoZSBnaXZlbiBmaWVsZC5cbiAgICovXG4gIGdldEZpZWxkOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2ZpZWxkX2lkJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgZmllbGRfaWQ6IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgZmllbGQgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLndoZXJlKCdpZCcsIGlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWZpZWxkKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBmaWVsZDogZmllbGQudG9KU09OKCksXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGdpdmVuIGZpZWxkLlxuICAgKi9cbiAgZGVsZXRlRmllbGQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnZmllbGRfaWQnKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBmaWVsZF9pZDogaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBmaWVsZCA9IGF3YWl0IFJlc291cmNlRmllbGQud2hlcmUoJ2lkJywgaWQpLmZldGNoKCk7XG5cbiAgICAgIGlmICghZmllbGQpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICBpZiAoZmllbGQuYXR0cmlidXRlcy5wcmVkZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdQUkVERUZJTkVEX0ZJRUxEJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGZpZWxkLmRlc3Ryb3koKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IGZpZWxkLmdldCgnaWQnKSB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgcXVlcnksIHZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBwaWNrIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBBY2NvdW50VHJhbnNhY3Rpb24gZnJvbSAnQC9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uJztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEFjY291bnRUeXBlIGZyb20gJ0AvbW9kZWxzL0FjY291bnRUeXBlJztcbmltcG9ydCBBY2NvdW50IGZyb20gJ0AvbW9kZWxzL0FjY291bnQnO1xuaW1wb3J0IEpvdXJuYWxQb3N0ZXIgZnJvbSAnQC9zZXJ2aWNlcy9BY2NvdW50aW5nL0pvdXJuYWxQb3N0ZXInO1xuaW1wb3J0IHsgZGF0ZVJhbmdlQ29sbGVjdGlvbiB9IGZyb20gJ0AvdXRpbHMnO1xuXG5jb25zdCBmb3JtYXROdW1iZXJDbG9zdXJlID0gKGZpbHRlcikgPT4gKGJhbGFuY2UpID0+IHtcbiAgbGV0IGZvcm1hdHRlZEJhbGFuY2UgPSBwYXJzZUZsb2F0KGJhbGFuY2UpO1xuXG4gIGlmIChmaWx0ZXIubm9fY2VudHMpIHtcbiAgICBmb3JtYXR0ZWRCYWxhbmNlID0gcGFyc2VJbnQoZm9ybWF0dGVkQmFsYW5jZSwgMTApO1xuICB9XG4gIGlmIChmaWx0ZXIuZGl2aWRlXzEwMDApIHtcbiAgICBmb3JtYXR0ZWRCYWxhbmNlIC89IDEwMDA7XG4gIH1cbiAgcmV0dXJuIGZvcm1hdHRlZEJhbGFuY2U7XG59O1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICByb3V0ZXIudXNlKGp3dEF1dGgpO1xuXG4gICAgcm91dGVyLmdldCgnL2xlZGdlcicsXG4gICAgICB0aGlzLmxlZGdlci52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubGVkZ2VyLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy9nZW5lcmFsX2xlZGdlcicsXG4gICAgICB0aGlzLmdlbmVyYWxMZWRnZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdlbmVyYWxMZWRnZXIuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnL2JhbGFuY2Vfc2hlZXQnLFxuICAgICAgdGhpcy5iYWxhbmNlU2hlZXQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmJhbGFuY2VTaGVldC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvdHJpYWxfYmFsYW5jZV9zaGVldCcsXG4gICAgICB0aGlzLnRyaWFsQmFsYW5jZVNoZWV0LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy50cmlhbEJhbGFuY2VTaGVldC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvcHJvZml0X2xvc3Nfc2hlZXQnLFxuICAgICAgdGhpcy5wcm9maXRMb3NzU2hlZXQudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnByb2ZpdExvc3NTaGVldC5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvY2FzaF9mbG93X3N0YXRlbWVudCcsXG4gICAgICB0aGlzLmNhc2hGbG93U3RhdGVtZW50LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5jYXNoRmxvd1N0YXRlbWVudC5oYW5kbGVyKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgbGVkZ2VyIHJlcG9ydCBvZiB0aGUgZ2l2ZW4gYWNjb3VudC5cbiAgICovXG4gIGxlZGdlcjoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdmcm9tX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ3RvX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ3RyYW5zYWN0aW9uX3R5cGVzJykub3B0aW9uYWwoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgcXVlcnkoJ2FjY291bnRfaWRzJykub3B0aW9uYWwoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgcXVlcnkoJ2FjY291bnRfaWRzLionKS5vcHRpb25hbCgpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBxdWVyeSgnZnJvbV9yYW5nZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCd0b19yYW5nZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0Lm5vX2NlbnRzJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0LmRpdmlkZV8xMDAwJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGZyb21fcmFuZ2U6IG51bGwsXG4gICAgICAgIHRvX3JhbmdlOiBudWxsLFxuICAgICAgICBhY2NvdW50X2lkczogW10sXG4gICAgICAgIHRyYW5zYWN0aW9uX3R5cGVzOiBbXSxcbiAgICAgICAgbnVtYmVyX2Zvcm1hdDoge1xuICAgICAgICAgIG5vX2NlbnRzOiBmYWxzZSxcbiAgICAgICAgICBkaXZpZGVfMTAwMDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG4gICAgICBjb25zdCBhY2NvdW50c0pvdXJuYWxFbnRyaWVzID0gYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLm1vZGlmeSgnZmlsdGVyRGF0ZVJhbmdlJywgZmlsdGVyLmZyb21fZGF0ZSwgZmlsdGVyLnRvX2RhdGUpXG4gICAgICAgIC5tb2RpZnkoJ2ZpbHRlckFjY291bnRzJywgZmlsdGVyLmFjY291bnRfaWRzKVxuICAgICAgICAubW9kaWZ5KCdmaWx0ZXJUcmFuc2FjdGlvblR5cGVzJywgZmlsdGVyLnRyYW5zYWN0aW9uX3R5cGVzKVxuICAgICAgICAubW9kaWZ5KCdmaWx0ZXJBbW91bnRSYW5nZScsIGZpbHRlci5mcm9tX3JhbmdlLCBmaWx0ZXIudG9fcmFuZ2UpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCdhY2NvdW50Jyk7XG5cbiAgICAgIGNvbnN0IGZvcm1hdE51bWJlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBtZXRhOiB7IC4uLmZpbHRlciB9LFxuICAgICAgICBpdGVtczogYWNjb3VudHNKb3VybmFsRW50cmllcy5tYXAoKGVudHJ5KSA9PiAoe1xuICAgICAgICAgIC4uLmVudHJ5LFxuICAgICAgICAgIGNyZWRpdDogZm9ybWF0TnVtYmVyKGVudHJ5LmNyZWRpdCksXG4gICAgICAgICAgZGViaXQ6IGZvcm1hdE51bWJlcihlbnRyeS5kZWJpdCksXG4gICAgICAgIH0pKSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHRoZSBnZW5lcmFsIGxlZGdlciBmaW5hbmNpYWwgc3RhdGVtZW50LlxuICAgKi9cbiAgZ2VuZXJhbExlZGdlcjoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdmcm9tX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ3RvX2RhdGUnKS5vcHRpb25hbCgpLmlzSVNPODYwMSgpLFxuICAgICAgcXVlcnkoJ2Jhc2lzJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0Lm5vX2NlbnRzJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0LmRpdmlkZV8xMDAwJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdub25lX3plcm8nKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgZnJvbV9kYXRlOiBtb21lbnQoKS5zdGFydE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIHRvX2RhdGU6IG1vbWVudCgpLmVuZE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIG51bWJlcl9mb3JtYXQ6IHtcbiAgICAgICAgICBub19jZW50czogZmFsc2UsXG4gICAgICAgICAgZGl2aWRlXzEwMDA6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBub25lX3plcm86IGZhbHNlLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KClcbiAgICAgICAgLm9yZGVyQnkoJ2luZGV4JywgJ0RFU0MnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHJhbnNhY3Rpb25zJylcbiAgICAgICAgLm1vZGlmeUdyYXBoKCd0cmFuc2FjdGlvbnMnLCAoYnVpbGRlcikgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJEYXRlUmFuZ2UnLCBmaWx0ZXIuZnJvbV9kYXRlLCBmaWx0ZXIudG9fZGF0ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBvcGVuaW5nQmFsYW5jZVRyYW5zYWN0aW9ucyA9IGF3YWl0IEFjY291bnRUcmFuc2FjdGlvbi5xdWVyeSgpXG4gICAgICAgIC5tb2RpZnkoJ2ZpbHRlckRhdGVSYW5nZScsIG51bGwsIGZpbHRlci5mcm9tX2RhdGUpXG4gICAgICAgIC5tb2RpZnkoJ3N1bWF0aW9uQ3JlZGl0RGViaXQnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnYWNjb3VudC50eXBlJyk7XG5cbiAgICAgIGNvbnN0IGNsb3NpbmdCYWxhbmNlVHJhbnNhY3Rpb25zID0gYXdhaXQgQWNjb3VudFRyYW5zYWN0aW9uLnF1ZXJ5KClcbiAgICAgICAgLm1vZGlmeSgnZmlsdGVyRGF0ZVJhbmdlJywgbnVsbCwgZmlsdGVyLnRvX2RhdGUpXG4gICAgICAgIC5tb2RpZnkoJ3N1bWF0aW9uQ3JlZGl0RGViaXQnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnYWNjb3VudC50eXBlJyk7XG5cbiAgICAgIGNvbnN0IG9wZWluZ0JhbGFuY2VDb2xsZWN0aW9uID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGNvbnN0IGNsb3NpbmdCYWxhbmNlQ29sbGVjdGlvbiA9IG5ldyBKb3VybmFsUG9zdGVyKCk7XG5cbiAgICAgIG9wZWluZ0JhbGFuY2VDb2xsZWN0aW9uLmxvYWRFbnRyaWVzKG9wZW5pbmdCYWxhbmNlVHJhbnNhY3Rpb25zKTtcbiAgICAgIGNsb3NpbmdCYWxhbmNlQ29sbGVjdGlvbi5sb2FkRW50cmllcyhjbG9zaW5nQmFsYW5jZVRyYW5zYWN0aW9ucyk7XG5cbiAgICAgIC8vIFRyYW5zYWN0aW9uIGFtb3VudCBmb3JtYXR0ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHF1ZXJ5LlxuICAgICAgY29uc3QgZm9ybWF0TnVtYmVyID0gZm9ybWF0TnVtYmVyQ2xvc3VyZShmaWx0ZXIubnVtYmVyX2Zvcm1hdCk7XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gW1xuICAgICAgICAuLi5hY2NvdW50c1xuICAgICAgICAgIC5maWx0ZXIoKGFjY291bnQpID0+IChcbiAgICAgICAgICAgIGFjY291bnQudHJhbnNhY3Rpb25zLmxlbmd0aCA+IDAgfHwgIWZpbHRlci5ub25lX3plcm9cbiAgICAgICAgICApKVxuICAgICAgICAgIC5tYXAoKGFjY291bnQpID0+ICh7XG4gICAgICAgICAgICAuLi5waWNrKGFjY291bnQsIFsnaWQnLCAnbmFtZScsICdjb2RlJywgJ2luZGV4J10pLFxuICAgICAgICAgICAgdHJhbnNhY3Rpb25zOiBbXG4gICAgICAgICAgICAgIC4uLmFjY291bnQudHJhbnNhY3Rpb25zLm1hcCgodHJhbnNhY3Rpb24pID0+ICh7XG4gICAgICAgICAgICAgICAgLi4udHJhbnNhY3Rpb24sXG4gICAgICAgICAgICAgICAgY3JlZGl0OiBmb3JtYXROdW1iZXIodHJhbnNhY3Rpb24uY3JlZGl0KSxcbiAgICAgICAgICAgICAgICBkZWJpdDogZm9ybWF0TnVtYmVyKHRyYW5zYWN0aW9uLmRlYml0KSxcbiAgICAgICAgICAgICAgfSkpLFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIG9wZW5pbmc6IHtcbiAgICAgICAgICAgICAgZGF0ZTogZmlsdGVyLmZyb21fZGF0ZSxcbiAgICAgICAgICAgICAgYmFsYW5jZTogb3BlaW5nQmFsYW5jZUNvbGxlY3Rpb24uZ2V0Q2xvc2luZ0JhbGFuY2UoYWNjb3VudC5pZCksXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY2xvc2luZzoge1xuICAgICAgICAgICAgICBkYXRlOiBmaWx0ZXIudG9fZGF0ZSxcbiAgICAgICAgICAgICAgYmFsYW5jZTogY2xvc2luZ0JhbGFuY2VDb2xsZWN0aW9uLmdldENsb3NpbmdCYWxhbmNlKGFjY291bnQuaWQpLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSksXG4gICAgICBdO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgbWV0YTogeyAuLi5maWx0ZXIgfSxcbiAgICAgICAgYWNjb3VudHM6IGl0ZW1zLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGJhbGFuY2Ugc2hlZXQuXG4gICAqL1xuICBiYWxhbmNlU2hlZXQ6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBxdWVyeSgnYWNjb3VudGluZ19tZXRob2QnKS5vcHRpb25hbCgpLmlzSW4oWydjYXNoJywgJ2FjY3VyYWwnXSksXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdkaXNwbGF5X2NvbHVtbnNfYnknKS5vcHRpb25hbCgpLmlzSW4oWyd0b3RhbCcsICd5ZWFyJywgJ21vbnRoJywgJ3dlZWsnLCAnZGF5JywgJ3F1YXJ0ZXInXSksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5ub19jZW50cycpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbnVtYmVyX2Zvcm1hdC5kaXZpZGVfMTAwMCcpLm9wdGlvbmFsKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgICBxdWVyeSgnbm9uZV96ZXJvJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKS50b0Jvb2xlYW4oKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGRpc3BsYXlfY29sdW1uc19ieTogJ3RvdGFsJyxcbiAgICAgICAgZnJvbV9kYXRlOiBtb21lbnQoKS5zdGFydE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIHRvX2RhdGU6IG1vbWVudCgpLmVuZE9mKCd5ZWFyJykuZm9ybWF0KCdZWVlZLU1NLUREJyksXG4gICAgICAgIG51bWJlcl9mb3JtYXQ6IHtcbiAgICAgICAgICBub19jZW50czogZmFsc2UsXG4gICAgICAgICAgZGl2aWRlXzEwMDA6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBub25lX3plcm86IGZhbHNlLFxuICAgICAgICBiYXNpczogJ2Nhc2gnLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBiYWxhbmNlU2hlZXRUeXBlcyA9IGF3YWl0IEFjY291bnRUeXBlLnF1ZXJ5KCkud2hlcmUoJ2JhbGFuY2Vfc2hlZXQnLCB0cnVlKTtcblxuICAgICAgLy8gRmV0Y2ggYWxsIGJhbGFuY2Ugc2hlZXQgYWNjb3VudHMuXG4gICAgICBjb25zdCBhY2NvdW50cyA9IGF3YWl0IEFjY291bnQucXVlcnkoKVxuICAgICAgICAud2hlcmVJbignYWNjb3VudF90eXBlX2lkJywgYmFsYW5jZVNoZWV0VHlwZXMubWFwKChhKSA9PiBhLmlkKSlcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3R5cGUnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHJhbnNhY3Rpb25zJylcbiAgICAgICAgLm1vZGlmeUdyYXBoKCd0cmFuc2FjdGlvbnMnLCAoYnVpbGRlcikgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdmaWx0ZXJEYXRlUmFuZ2UnLCBudWxsLCBmaWx0ZXIudG9fZGF0ZSk7XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBqb3VybmFsRW50cmllc0NvbGxlY3RlZCA9IEFjY291bnQuY29sbGVjdEpvdXJuYWxFbnRyaWVzKGFjY291bnRzKTtcbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmxvYWRFbnRyaWVzKGpvdXJuYWxFbnRyaWVzQ29sbGVjdGVkKTtcblxuICAgICAgLy8gQWNjb3VudCBiYWxhbmNlIGZvcm1tYXR0ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHF1ZXJ5LlxuICAgICAgY29uc3QgYmFsYW5jZUZvcm1hdHRlciA9IGZvcm1hdE51bWJlckNsb3N1cmUoZmlsdGVyLm51bWJlcl9mb3JtYXQpO1xuICAgICAgY29uc3QgZmlsdGVyRGF0ZVR5cGUgPSBmaWx0ZXIuZGlzcGxheV9jb2x1bW5zX2J5ID09PSAndG90YWwnXG4gICAgICAgID8gJ2RheScgOiBmaWx0ZXIuZGlzcGxheV9jb2x1bW5zX2J5O1xuXG4gICAgICAvLyBHZXRzIHRoZSBkYXRlIHJhbmdlIHNldCBmcm9tIHN0YXJ0IHRvIGVuZCBkYXRlLlxuICAgICAgY29uc3QgZGF0ZVJhbmdlU2V0ID0gZGF0ZVJhbmdlQ29sbGVjdGlvbihcbiAgICAgICAgZmlsdGVyLmZyb21fZGF0ZSxcbiAgICAgICAgZmlsdGVyLnRvX2RhdGUsXG4gICAgICAgIGZpbHRlckRhdGVUeXBlLFxuICAgICAgKTtcblxuICAgICAgLy8gUmV0cmlldmUgdGhlIGFzc2V0IGJhbGFuY2Ugc2hlZXQuXG4gICAgICBjb25zdCBhc3NldHMgPSBhY2NvdW50c1xuICAgICAgICAuZmlsdGVyKChhY2NvdW50KSA9PiAoXG4gICAgICAgICAgYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2RlYml0J1xuICAgICAgICAgICAgJiYgKGFjY291bnQudHJhbnNhY3Rpb25zLmxlbmd0aCA+IDAgfHwgIWZpbHRlci5ub25lX3plcm8pXG4gICAgICAgICkpXG4gICAgICAgIC5tYXAoKGFjY291bnQpID0+IHtcbiAgICAgICAgICAvLyBDYWxjdWxhdGVzIHRoZSBjbG9zaW5nIGJhbGFuY2UgdG8gdGhlIGdpdmVuIGRhdGUuXG4gICAgICAgICAgY29uc3QgY2xvc2luZ0JhbGFuY2UgPSBqb3VybmFsRW50cmllcy5nZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50LmlkLCBmaWx0ZXIudG9fZGF0ZSk7XG4gICAgICAgICAgY29uc3QgdHlwZSA9IGZpbHRlci5kaXNwbGF5X2NvbHVtbnNfYnk7XG5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4ucGljayhhY2NvdW50LCBbJ2lkJywgJ2luZGV4JywgJ25hbWUnLCAnY29kZSddKSxcbiAgICAgICAgICAgIC4uLih0eXBlICE9PSAndG90YWwnKSA/IHtcbiAgICAgICAgICAgICAgcGVyaW9kc19iYWxhbmNlOiBkYXRlUmFuZ2VTZXQubWFwKChkYXRlKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgYmFsYW5jZSA9IGpvdXJuYWxFbnRyaWVzLmdldENsb3NpbmdCYWxhbmNlKGFjY291bnQuaWQsIGRhdGUsIGZpbHRlckRhdGVUeXBlKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgICBkYXRlLFxuICAgICAgICAgICAgICAgICAgZm9ybWF0dGVkX2Ftb3VudDogYmFsYW5jZUZvcm1hdHRlcihiYWxhbmNlKSxcbiAgICAgICAgICAgICAgICAgIGFtb3VudDogYmFsYW5jZSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0gOiB7fSxcbiAgICAgICAgICAgIGJhbGFuY2U6IHtcbiAgICAgICAgICAgICAgZm9ybWF0dGVkX2Ftb3VudDogYmFsYW5jZUZvcm1hdHRlcihjbG9zaW5nQmFsYW5jZSksXG4gICAgICAgICAgICAgIGFtb3VudDogY2xvc2luZ0JhbGFuY2UsXG4gICAgICAgICAgICAgIGRhdGU6IGZpbHRlci50b19kYXRlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgLy8gUmV0cmlldmUgbGlhYmlsaXRpZXMgYW5kIGVxdWl0eSBiYWxhbmNlIHNoZWV0LlxuICAgICAgY29uc3QgbGlhYmlsaXRpZXNFcXVpdHkgPSBhY2NvdW50c1xuICAgICAgICAuZmlsdGVyKChhY2NvdW50KSA9PiAoXG4gICAgICAgICAgYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2NyZWRpdCdcbiAgICAgICAgICAgICYmIChhY2NvdW50LnRyYW5zYWN0aW9ucy5sZW5ndGggPiAwIHx8ICFmaWx0ZXIubm9uZV96ZXJvKVxuICAgICAgICApKVxuICAgICAgICAubWFwKChhY2NvdW50KSA9PiB7XG4gICAgICAgICAgLy8gQ2FsY3VsYXRlcyB0aGUgY2xvc2luZyBiYWxhbmNlIHRvIHRoZSBnaXZlbiBkYXRlLlxuICAgICAgICAgIGNvbnN0IGNsb3NpbmdCYWxhbmNlID0gam91cm5hbEVudHJpZXMuZ2V0Q2xvc2luZ0JhbGFuY2UoYWNjb3VudC5pZCwgZmlsdGVyLnRvX2RhdGUpO1xuICAgICAgICAgIGNvbnN0IHR5cGUgPSBmaWx0ZXIuZGlzcGxheV9jb2x1bW5zX2J5O1xuXG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnBpY2soYWNjb3VudCwgWydpZCcsICdpbmRleCcsICduYW1lJywgJ2NvZGUnXSksXG4gICAgICAgICAgICAuLi4odHlwZSAhPT0gJ3RvdGFsJykgPyB7XG4gICAgICAgICAgICAgIHBlcmlvZHNfYmFsYW5jZTogZGF0ZVJhbmdlU2V0Lm1hcCgoZGF0ZSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhbGFuY2UgPSBqb3VybmFsRW50cmllcy5nZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50LmlkLCBkYXRlLCBmaWx0ZXJEYXRlVHlwZSk7XG5cbiAgICAgICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgICAgZGF0ZSxcbiAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZF9hbW91bnQ6IGJhbGFuY2VGb3JtYXR0ZXIoYmFsYW5jZSksXG4gICAgICAgICAgICAgICAgICBhbW91bnQ6IGJhbGFuY2UsXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9IDoge30sXG4gICAgICAgICAgICBiYWxhbmNlOiB7XG4gICAgICAgICAgICAgIGZvcm1hdHRlZEFtb3VudDogYmFsYW5jZUZvcm1hdHRlcihjbG9zaW5nQmFsYW5jZSksXG4gICAgICAgICAgICAgIGFtb3VudDogY2xvc2luZ0JhbGFuY2UsXG4gICAgICAgICAgICAgIGRhdGU6IGZpbHRlci50b19kYXRlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgcXVlcnk6IHsgLi4uZmlsdGVyIH0sXG4gICAgICAgIGNvbHVtbnM6IHsgLi4uZGF0ZVJhbmdlU2V0IH0sXG4gICAgICAgIGJhbGFuY2Vfc2hlZXQ6IHtcbiAgICAgICAgICBhc3NldHM6IHtcbiAgICAgICAgICAgIHRpdGxlOiAnQXNzZXRzJyxcbiAgICAgICAgICAgIGFjY291bnRzOiBbLi4uYXNzZXRzXSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGxpYWJpbGl0aWVzX2VxdWl0eToge1xuICAgICAgICAgICAgdGl0bGU6ICdMaWFiaWxpdGllcyAmIEVxdWl0eScsXG4gICAgICAgICAgICBhY2NvdW50czogWy4uLmxpYWJpbGl0aWVzRXF1aXR5XSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIHRyaWFsIGJhbGFuY2Ugc2hlZXQuXG4gICAqL1xuICB0cmlhbEJhbGFuY2VTaGVldDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0Lm5vX2NlbnRzJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0LjEwMDBfZGl2aWRlJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnbm9uZV96ZXJvJykub3B0aW9uYWwoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGZyb21fZGF0ZTogbW9tZW50KCkuc3RhcnRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICB0b19kYXRlOiBtb21lbnQoKS5lbmRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICBudW1iZXJfZm9ybWF0OiB7XG4gICAgICAgICAgbm9fY2VudHM6IGZhbHNlLFxuICAgICAgICAgIGRpdmlkZV8xMDAwOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgYmFzaXM6ICdhY2N1cmFsJyxcbiAgICAgICAgbm9uZV96ZXJvOiBmYWxzZSxcbiAgICAgICAgLi4ucmVxLnF1ZXJ5LFxuICAgICAgfTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KClcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3R5cGUnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgndHJhbnNhY3Rpb25zJylcbiAgICAgICAgLm1vZGlmeUdyYXBoKCd0cmFuc2FjdGlvbnMnLCAoYnVpbGRlcikgPT4ge1xuICAgICAgICAgIGJ1aWxkZXIubW9kaWZ5KCdzdW1hdGlvbkNyZWRpdERlYml0Jyk7XG4gICAgICAgICAgYnVpbGRlci5tb2RpZnkoJ2ZpbHRlckRhdGVSYW5nZScsIGZpbHRlci5mcm9tX2RhdGUsIGZpbHRlci50b19kYXRlKTtcbiAgICAgICAgfSk7XG5cbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzQ29sbGVjdCA9IEFjY291bnQuY29sbGVjdEpvdXJuYWxFbnRyaWVzKGFjY291bnRzKTtcbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmxvYWRFbnRyaWVzKGpvdXJuYWxFbnRyaWVzQ29sbGVjdCk7XG5cbiAgICAgIC8vIEFjY291bnQgYmFsYW5jZSBmb3JtbWF0dGVyIGJhc2VkIG9uIHRoZSBnaXZlbiBxdWVyeS5cbiAgICAgIGNvbnN0IGJhbGFuY2VGb3JtYXR0ZXIgPSBmb3JtYXROdW1iZXJDbG9zdXJlKGZpbHRlci5udW1iZXJfZm9ybWF0KTtcblxuICAgICAgY29uc3QgaXRlbXMgPSBhY2NvdW50c1xuICAgICAgICAuZmlsdGVyKChhY2NvdW50KSA9PiAoXG4gICAgICAgICAgYWNjb3VudC50cmFuc2FjdGlvbnMubGVuZ3RoID4gMCB8fCAhZmlsdGVyLm5vbmVfemVyb1xuICAgICAgICApKVxuICAgICAgICAubWFwKChhY2NvdW50KSA9PiB7XG4gICAgICAgICAgY29uc3QgdHJpYWwgPSBqb3VybmFsRW50cmllcy5nZXRUcmlhbEJhbGFuY2UoYWNjb3VudC5pZCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGFjY291bnRfaWQ6IGFjY291bnQuaWQsXG4gICAgICAgICAgICBjb2RlOiBhY2NvdW50LmNvZGUsXG4gICAgICAgICAgICBhY2NvdW50Tm9ybWFsOiBhY2NvdW50LnR5cGUubm9ybWFsLFxuICAgICAgICAgICAgY3JlZGl0OiBiYWxhbmNlRm9ybWF0dGVyKHRyaWFsLmNyZWRpdCksXG4gICAgICAgICAgICBkZWJpdDogYmFsYW5jZUZvcm1hdHRlcih0cmlhbC5kZWJpdCksXG4gICAgICAgICAgICBiYWxhbmNlOiBiYWxhbmNlRm9ybWF0dGVyKHRyaWFsLmJhbGFuY2UpLFxuICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgcXVlcnk6IHsgLi4uZmlsdGVyIH0sXG4gICAgICAgIGl0ZW1zOiBbLi4uaXRlbXNdLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgcHJvZml0L2xvc3MgZmluYW5jaWFsIHN0YXRlbWVudC5cbiAgICovXG4gIHByb2ZpdExvc3NTaGVldDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnZnJvbV9kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCd0b19kYXRlJykub3B0aW9uYWwoKS5pc0lTTzg2MDEoKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0Lm5vX2NlbnRzJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdudW1iZXJfZm9ybWF0LmRpdmlkZV8xMDAwJykub3B0aW9uYWwoKS5pc0Jvb2xlYW4oKSxcbiAgICAgIHF1ZXJ5KCdiYXNpcycpLm9wdGlvbmFsKCksXG4gICAgICBxdWVyeSgnbm9uZV96ZXJvJykub3B0aW9uYWwoKSxcbiAgICAgIHF1ZXJ5KCdkaXNwbGF5X2NvbHVtbnNfYnknKS5vcHRpb25hbCgpLmlzSW4oWyd5ZWFyJywgJ21vbnRoJywgJ3dlZWsnLCAnZGF5JywgJ3F1YXJ0ZXInXSksXG4gICAgICBxdWVyeSgnYWNjb3VudHMnKS5vcHRpb25hbCgpLmlzQXJyYXkoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCBmaWx0ZXIgPSB7XG4gICAgICAgIGZyb21fZGF0ZTogbW9tZW50KCkuc3RhcnRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICB0b19kYXRlOiBtb21lbnQoKS5lbmRPZigneWVhcicpLmZvcm1hdCgnWVlZWS1NTS1ERCcpLFxuICAgICAgICBudW1iZXJfZm9ybWF0OiB7XG4gICAgICAgICAgbm9fY2VudHM6IGZhbHNlLFxuICAgICAgICAgIGRpdmlkZV8xMDAwOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgYmFzaXM6ICdhY2N1cmFsJyxcbiAgICAgICAgbm9uZV96ZXJvOiBmYWxzZSxcbiAgICAgICAgZGlzcGxheV9jb2x1bW5zX2J5OiAnbW9udGgnLFxuICAgICAgICAuLi5yZXEucXVlcnksXG4gICAgICB9O1xuICAgICAgY29uc3QgaW5jb21lU3RhdGVtZW50VHlwZXMgPSBhd2FpdCBBY2NvdW50VHlwZS5xdWVyeSgpLndoZXJlKCdpbmNvbWVfc2hlZXQnLCB0cnVlKTtcblxuICAgICAgY29uc3QgYWNjb3VudHMgPSBhd2FpdCBBY2NvdW50LnF1ZXJ5KClcbiAgICAgICAgLndoZXJlSW4oJ2FjY291bnRfdHlwZV9pZCcsIGluY29tZVN0YXRlbWVudFR5cGVzLm1hcCgodCkgPT4gdC5pZCkpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCd0eXBlJylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3RyYW5zYWN0aW9ucycpO1xuXG4gICAgICBjb25zdCBmaWx0ZXJlZEFjY291bnRzID0gYWNjb3VudHMuZmlsdGVyKChhY2NvdW50KSA9PiB7XG4gICAgICAgIHJldHVybiBhY2NvdW50LnRyYW5zYWN0aW9ucy5sZW5ndGggPiAwIHx8ICFmaWx0ZXIubm9uZV96ZXJvO1xuICAgICAgfSk7XG4gICAgICBjb25zdCBqb3VybmFsRW50cmllc0NvbGxlY3RlZCA9IEFjY291bnQuY29sbGVjdEpvdXJuYWxFbnRyaWVzKGFjY291bnRzKTtcbiAgICAgIGNvbnN0IGpvdXJuYWxFbnRyaWVzID0gbmV3IEpvdXJuYWxQb3N0ZXIoKTtcbiAgICAgIGpvdXJuYWxFbnRyaWVzLmxvYWRFbnRyaWVzKGpvdXJuYWxFbnRyaWVzQ29sbGVjdGVkKTtcblxuICAgICAgLy8gQWNjb3VudCBiYWxhbmNlIGZvcm1tYXR0ZXIgYmFzZWQgb24gdGhlIGdpdmVuIHF1ZXJ5LlxuICAgICAgY29uc3QgbnVtYmVyRm9ybWF0dGVyID0gZm9ybWF0TnVtYmVyQ2xvc3VyZShmaWx0ZXIubnVtYmVyX2Zvcm1hdCk7XG5cbiAgICAgIC8vIEdldHMgdGhlIGRhdGUgcmFuZ2Ugc2V0IGZyb20gc3RhcnQgdG8gZW5kIGRhdGUuXG4gICAgICBjb25zdCBkYXRlUmFuZ2VTZXQgPSBkYXRlUmFuZ2VDb2xsZWN0aW9uKFxuICAgICAgICBmaWx0ZXIuZnJvbV9kYXRlLFxuICAgICAgICBmaWx0ZXIudG9fZGF0ZSxcbiAgICAgICAgZmlsdGVyLmRpc3BsYXlfY29sdW1uc19ieSxcbiAgICAgICk7XG4gICAgICBjb25zdCBhY2NvdW50c0luY29tZSA9IGZpbHRlcmVkQWNjb3VudHNcbiAgICAgICAgLmZpbHRlcigoYWNjb3VudCkgPT4gYWNjb3VudC50eXBlLm5vcm1hbCA9PT0gJ2NyZWRpdCcpXG4gICAgICAgIC5tYXAoKGFjY291bnQpID0+ICh7XG4gICAgICAgICAgLi4ucGljayhhY2NvdW50LCBbJ2lkJywgJ2luZGV4JywgJ25hbWUnLCAnY29kZSddKSxcbiAgICAgICAgICBkYXRlczogZGF0ZVJhbmdlU2V0Lm1hcCgoZGF0ZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdHlwZSA9IGZpbHRlci5kaXNwbGF5X2NvbHVtbnNfYnk7XG4gICAgICAgICAgICBjb25zdCBhbW91bnQgPSBqb3VybmFsRW50cmllcy5nZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50LmlkLCBkYXRlLCB0eXBlKTtcblxuICAgICAgICAgICAgcmV0dXJuIHsgZGF0ZSwgcmF3QW1vdW50OiBhbW91bnQsIGFtb3VudDogbnVtYmVyRm9ybWF0dGVyKGFtb3VudCkgfTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgfSkpO1xuXG4gICAgICBjb25zdCBhY2NvdW50c0V4cGVuc2VzID0gZmlsdGVyZWRBY2NvdW50c1xuICAgICAgICAuZmlsdGVyKChhY2NvdW50KSA9PiBhY2NvdW50LnR5cGUubm9ybWFsID09PSAnZGViaXQnKVxuICAgICAgICAubWFwKChhY2NvdW50KSA9PiAoe1xuICAgICAgICAgIC4uLnBpY2soYWNjb3VudCwgWydpZCcsICdpbmRleCcsICduYW1lJywgJ2NvZGUnXSksXG4gICAgICAgICAgZGF0ZXM6IGRhdGVSYW5nZVNldC5tYXAoKGRhdGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBmaWx0ZXIuZGlzcGxheV9jb2x1bW5zX2J5O1xuICAgICAgICAgICAgY29uc3QgYW1vdW50ID0gam91cm5hbEVudHJpZXMuZ2V0Q2xvc2luZ0JhbGFuY2UoYWNjb3VudC5pZCwgZGF0ZSwgdHlwZSk7XG5cbiAgICAgICAgICAgIHJldHVybiB7IGRhdGUsIHJhd0Ftb3VudDogYW1vdW50LCBhbW91bnQ6IG51bWJlckZvcm1hdHRlcihhbW91bnQpIH07XG4gICAgICAgICAgfSksXG4gICAgICAgIH0pKTtcblxuICAgICAgLy8gQ2FsY3VsYXRlcyB0aGUgdG90YWwgaW5jb21lIG9mIGluY29tZSBhY2NvdW50cy5cbiAgICAgIGNvbnN0IHRvdGFsQWNjb3VudHNJbmNvbWUgPSBkYXRlUmFuZ2VTZXQucmVkdWNlKChhY2MsIGRhdGUsIGluZGV4KSA9PiB7XG4gICAgICAgIGxldCBhbW91bnQgPSAwO1xuICAgICAgICBhY2NvdW50c0luY29tZS5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG4gICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBhY2NvdW50LmRhdGVzW2luZGV4XTtcbiAgICAgICAgICBhbW91bnQgKz0gY3VycmVudERhdGUucmF3QW1vdW50IHx8IDA7XG4gICAgICAgIH0pO1xuICAgICAgICBhY2NbZGF0ZV0gPSB7IGRhdGUsIHJhd0Ftb3VudDogYW1vdW50LCBhbW91bnQ6IG51bWJlckZvcm1hdHRlcihhbW91bnQpIH07XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIC8vIENhbGN1bGF0ZXMgdGhlIHRvdGFsIGV4cGVuc2VzIG9mIGV4cGVuc2VzIGFjY291bnRzLlxuICAgICAgY29uc3QgdG90YWxBY2NvdW50c0V4cGVuc2VzID0gZGF0ZVJhbmdlU2V0LnJlZHVjZSgoYWNjLCBkYXRlLCBpbmRleCkgPT4ge1xuICAgICAgICBsZXQgYW1vdW50ID0gMDtcbiAgICAgICAgYWNjb3VudHNFeHBlbnNlcy5mb3JFYWNoKChhY2NvdW50KSA9PiB7XG4gICAgICAgICAgY29uc3QgY3VycmVudERhdGUgPSBhY2NvdW50LmRhdGVzW2luZGV4XTtcbiAgICAgICAgICBhbW91bnQgKz0gY3VycmVudERhdGUucmF3QW1vdW50IHx8IDA7XG4gICAgICAgIH0pO1xuICAgICAgICBhY2NbZGF0ZV0gPSB7IGRhdGUsIHJhd0Ftb3VudDogYW1vdW50LCBhbW91bnQ6IG51bWJlckZvcm1hdHRlcihhbW91bnQpIH07XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIC8vIFRvdGFsIGluY29tZShkYXRlKSAtIFRvdGFsIGV4cGVuc2VzKGRhdGUpID0gTmV0IGluY29tZShkYXRlKVxuICAgICAgY29uc3QgbmV0SW5jb21lID0gZGF0ZVJhbmdlU2V0Lm1hcCgoZGF0ZSkgPT4ge1xuICAgICAgICBjb25zdCB0b3RhbEluY29tZSA9IHRvdGFsQWNjb3VudHNJbmNvbWVbZGF0ZV07XG4gICAgICAgIGNvbnN0IHRvdGFsRXhwZW5zZXMgPSB0b3RhbEFjY291bnRzRXhwZW5zZXNbZGF0ZV07XG5cbiAgICAgICAgbGV0IGFtb3VudCA9IHRvdGFsSW5jb21lLnJhd0Ftb3VudCB8fCAwO1xuICAgICAgICBhbW91bnQgLT0gdG90YWxFeHBlbnNlcy5yYXdBbW91bnQgfHwgMDtcbiAgICAgICAgcmV0dXJuIHsgZGF0ZSwgcmF3QW1vdW50OiBhbW91bnQsIGFtb3VudDogbnVtYmVyRm9ybWF0dGVyKGFtb3VudCkgfTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBtZXRhOiB7IC4uLmZpbHRlciB9LFxuICAgICAgICBpbmNvbWU6IHtcbiAgICAgICAgICBlbnRyeV9ub3JtYWw6ICdjcmVkaXQnLFxuICAgICAgICAgIGFjY291bnRzOiBhY2NvdW50c0luY29tZSxcbiAgICAgICAgfSxcbiAgICAgICAgZXhwZW5zZXM6IHtcbiAgICAgICAgICBlbnRyeV9ub3JtYWw6ICdkZWJpdCcsXG4gICAgICAgICAgYWNjb3VudHM6IGFjY291bnRzRXhwZW5zZXMsXG4gICAgICAgIH0sXG4gICAgICAgIHRvdGFsX2luY29tZTogT2JqZWN0LnZhbHVlcyh0b3RhbEFjY291bnRzSW5jb21lKSxcbiAgICAgICAgdG90YWxfZXhwZW5zZXM6IE9iamVjdC52YWx1ZXModG90YWxBY2NvdW50c0V4cGVuc2VzKSxcbiAgICAgICAgdG90YWxfbmV0X2luY29tZTogbmV0SW5jb21lLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcblxuICBjYXNoRmxvd1N0YXRlbWVudDoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdkYXRlX2Zyb20nKS5vcHRpb25hbCgpLFxuICAgICAgcXVlcnkoJ2RhdGVfdG8nKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoe1xuICAgICAgICBtZXRhOiB7fSxcbiAgICAgICAgb3BlcmF0aW5nOiBbXSxcbiAgICAgICAgZmluYW5jaW5nOiBbXSxcbiAgICAgICAgaW52ZXN0aW5nOiBbXSxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG59XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGNoZWNrLCBwYXJhbSwgdmFsaWRhdGlvblJlc3VsdCB9IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnLi4vbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IEl0ZW1DYXRlZ29yeSBmcm9tICdAL21vZGVscy9JdGVtQ2F0ZWdvcnknO1xuaW1wb3J0IEF1dGhvcml6YXRpb24gZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXV0aG9yaXphdGlvbic7XG5pbXBvcnQgSldUQXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICAvKipcbiAgICogUm91dGVyIGNvbnN0cnVjdG9yIG1ldGhvZC5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuICAgIGNvbnN0IHBlcm1pdCA9IEF1dGhvcml6YXRpb24oJ2l0ZW1zX2NhdGVnb3JpZXMnKTtcblxuICAgIHJvdXRlci51c2UoSldUQXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICBwZXJtaXQoJ2NyZWF0ZScsICdlZGl0JyksXG4gICAgICB0aGlzLmVkaXRDYXRlZ29yeS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdENhdGVnb3J5LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHBlcm1pdCgnY3JlYXRlJyksXG4gICAgICB0aGlzLm5ld0NhdGVnb3J5LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdDYXRlZ29yeS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOmlkJyxcbiAgICAgIHBlcm1pdCgnY3JlYXRlJywgJ2VkaXQnLCAnZGVsZXRlJyksXG4gICAgICB0aGlzLmRlbGV0ZUl0ZW0udmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZUl0ZW0uaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLzppZCcsXG4gICAgICBwZXJtaXQoJ3ZpZXcnKSxcbiAgICAgIHRoaXMuZ2V0Q2F0ZWdvcnkudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldENhdGVnb3J5LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgcGVybWl0KCd2aWV3JyksXG4gICAgICB0aGlzLmdldExpc3QudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmdldExpc3QudmFsaWRhdGlvbikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBpdGVtIGNhdGVnb3J5LlxuICAgKi9cbiAgbmV3Q2F0ZWdvcnk6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cyh7IGNoZWNrRmFsc3k6IHRydWUgfSkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ3BhcmVudF9jYXRlZ29yeV9pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBuYW1lLCBwYXJlbnRfY2F0ZWdvcnlfaWQ6IHBhcmVudENhdGVnb3J5SWQsIGRlc2NyaXB0aW9uIH0gPSByZXEuYm9keTtcblxuICAgICAgaWYgKHBhcmVudENhdGVnb3J5SWQpIHtcbiAgICAgICAgY29uc3QgZm91bmRQYXJlbnRDYXRlZ29yeSA9IGF3YWl0IEl0ZW1DYXRlZ29yeS53aGVyZSgnaWQnLCBwYXJlbnRDYXRlZ29yeUlkKS5mZXRjaCgpO1xuXG4gICAgICAgIGlmICghZm91bmRQYXJlbnRDYXRlZ29yeSkge1xuICAgICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgnVGhlIHBhcmVudCBjYXRlZ29yeSBJRCBpcyBub3QgZm91bmQuJywge1xuICAgICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUEFSRU5UX0NBVEVHT1JZX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgY2F0ZWdvcnkgPSBhd2FpdCBJdGVtQ2F0ZWdvcnkuZm9yZ2Uoe1xuICAgICAgICBsYWJlbDogbmFtZSxcbiAgICAgICAgcGFyZW50X2NhdGVnb3J5X2lkOiBwYXJlbnRDYXRlZ29yeUlkLFxuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgIH0pO1xuXG4gICAgICBhd2FpdCBjYXRlZ29yeS5zYXZlKCk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogY2F0ZWdvcnkuZ2V0KCdpZCcpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEVkaXQgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gY2F0ZWdvcnkgaXRlbS5cbiAgICovXG4gIGVkaXRDYXRlZ29yeToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdpZCcpLnRvSW50KCksXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cyh7IGNoZWNrRmFsc3k6IHRydWUgfSkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ3BhcmVudF9jYXRlZ29yeV9pZCcpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZhbGlkYXRpb25FcnJvcnMgPSB2YWxpZGF0aW9uUmVzdWx0KHJlcSk7XG5cbiAgICAgIGlmICghdmFsaWRhdGlvbkVycm9ycy5pc0VtcHR5KCkpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZERhdGEobnVsbCwge1xuICAgICAgICAgIGNvZGU6ICd2YWxpZGF0aW9uX2Vycm9yJywgLi4udmFsaWRhdGlvbkVycm9ycyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCB7IG5hbWUsIHBhcmVudF9jYXRlZ29yeV9pZDogcGFyZW50Q2F0ZWdvcnlJZCwgZGVzY3JpcHRpb24gfSA9IHJlcS5ib2R5O1xuICAgICAgY29uc3QgaXRlbUNhdGVnb3J5ID0gYXdhaXQgSXRlbUNhdGVnb3J5LndoZXJlKCdpZCcsIGlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWl0ZW1DYXRlZ29yeSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIGlmIChwYXJlbnRDYXRlZ29yeUlkICYmIHBhcmVudENhdGVnb3J5SWQgIT09IGl0ZW1DYXRlZ29yeS5hdHRyaWJ1dGVzLnBhcmVudF9jYXRlZ29yeV9pZCkge1xuICAgICAgICBjb25zdCBmb3VuZFBhcmVudENhdGVnb3J5ID0gYXdhaXQgSXRlbUNhdGVnb3J5LndoZXJlKCdpZCcsIHBhcmVudENhdGVnb3J5SWQpLmZldGNoKCk7XG5cbiAgICAgICAgaWYgKCFmb3VuZFBhcmVudENhdGVnb3J5KSB7XG4gICAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCdUaGUgcGFyZW50IGNhdGVnb3J5IElEIGlzIG5vdCBmb3VuZC4nLCB7XG4gICAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdQQVJFTlRfQ0FURUdPUllfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCBpdGVtQ2F0ZWdvcnkuc2F2ZSh7XG4gICAgICAgIGxhYmVsOiBuYW1lLFxuICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgcGFyZW50X2NhdGVnb3J5X2lkOiBwYXJlbnRDYXRlZ29yeUlkLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBpdGVtQ2F0ZWdvcnkuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlIGl0ZW0gY2F0ZWdvcnkuXG4gICAqL1xuICBkZWxldGVJdGVtOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCBpdGVtQ2F0ZWdvcnkgPSBhd2FpdCBJdGVtQ2F0ZWdvcnkud2hlcmUoJ2lkJywgaWQpLmZldGNoKCk7XG5cbiAgICAgIGlmICghaXRlbUNhdGVnb3J5KSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgYXdhaXQgaXRlbUNhdGVnb3J5LmRlc3Ryb3koKTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCgpO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHRoZSBsaXN0IG9mIGl0ZW1zLlxuICAgKi9cbiAgZ2V0TGlzdDoge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgSXRlbUNhdGVnb3J5LmZldGNoKCk7XG5cbiAgICAgIGlmICghaXRlbXMpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpdGVtczogaXRlbXMudG9KU09OKCkgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgZGV0YWlscyBvZiB0aGUgZ2l2ZW4gY2F0ZWdvcnkuXG4gICAqL1xuICBnZXRDYXRlZ29yeToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdjYXRlZ29yeV9pZCcpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGNhdGVnb3J5X2lkOiBjYXRlZ29yeUlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgaXRlbSA9IGF3YWl0IEl0ZW1DYXRlZ29yeS53aGVyZSgnaWQnLCBjYXRlZ29yeUlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIWl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdDQVRFR09SWV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBjYXRlZ29yeTogaXRlbS50b0pTT04oKSB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsImltcG9ydCBleHByZXNzIGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgY2hlY2ssIHZhbGlkYXRpb25SZXN1bHQgfSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgeyBkaWZmZXJlbmNlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBhc3luY01pZGRsZXdhcmUgZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvYXN5bmNNaWRkbGV3YXJlJztcbmltcG9ydCBqd3RBdXRoIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2p3dEF1dGgnO1xuaW1wb3J0IEl0ZW0gZnJvbSAnQC9tb2RlbHMvSXRlbSc7XG5pbXBvcnQgQWNjb3VudCBmcm9tICdAL21vZGVscy9BY2NvdW50JztcbmltcG9ydCBJdGVtQ2F0ZWdvcnkgZnJvbSAnQC9tb2RlbHMvSXRlbUNhdGVnb3J5JztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICdAL21vZGVscy9SZXNvdXJjZSc7XG5pbXBvcnQgUmVzb3VyY2VGaWVsZCBmcm9tICdAL21vZGVscy9SZXNvdXJjZUZpZWxkJztcbmltcG9ydCBBdXRob3JpemF0aW9uIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2F1dGhvcml6YXRpb24nO1xuXG5leHBvcnQgZGVmYXVsdCB7XG5cbiAgcm91dGVyKCkge1xuICAgIGNvbnN0IHJvdXRlciA9IGV4cHJlc3MuUm91dGVyKCk7XG4gICAgY29uc3QgcGVybWl0ID0gQXV0aG9yaXphdGlvbignaXRlbXMnKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICB0aGlzLmVkaXRJdGVtLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5lZGl0SXRlbS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICAvLyBwZXJtaXQoJ2NyZWF0ZScpLFxuICAgICAgdGhpcy5uZXdJdGVtLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5uZXdJdGVtLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5kZWxldGUoJy86aWQnLFxuICAgICAgdGhpcy5kZWxldGVJdGVtLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVJdGVtLmhhbmRsZXIpKTtcblxuICAgIC8vIHJvdXRlci5nZXQoJy86aWQnLFxuICAgIC8vICAgdGhpcy5nZXRDYXRlZ29yeS52YWxpZGF0aW9uLFxuICAgIC8vICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0Q2F0ZWdvcnkuaGFuZGxlcikpO1xuXG4gICAgLy8gcm91dGVyLmdldCgnLycsXG4gICAgLy8gICB0aGlzLmNhdGVnb3JpZXNMaXN0LnZhbGlkYXRpb24sXG4gICAgLy8gICBhc3luY01pZGRsZXdhcmUodGhpcy5jYXRlZ29yaWVzTGlzdC52YWxpZGF0aW9uKSk7XG5cbiAgICByZXR1cm4gcm91dGVyO1xuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGl0ZW0uXG4gICAqL1xuICBuZXdJdGVtOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCd0eXBlJykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLmlzSW4oWydzZXJ2aWNlJywgJ3Byb2R1Y3QnXSksXG4gICAgICBjaGVjaygnY29zdF9wcmljZScpLmV4aXN0cygpLmlzTnVtZXJpYygpLFxuICAgICAgY2hlY2soJ3NlbGxfcHJpY2UnKS5leGlzdHMoKS5pc051bWVyaWMoKSxcbiAgICAgIGNoZWNrKCdjb3N0X2FjY291bnRfaWQnKS5leGlzdHMoKS5pc0ludCgpLnRvSW50KCksXG4gICAgICBjaGVjaygnc2VsbF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNJbnQoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2NhdGVnb3J5X2lkJykub3B0aW9uYWwoKS5pc0ludCgpLnRvSW50KCksXG5cbiAgICAgIGNoZWNrKCdjdXN0b21fZmllbGRzJykub3B0aW9uYWwoKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgICAgY2hlY2soJ2N1c3RvbV9maWVsZHMuKi5rZXknKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2N1c3RvbV9maWVsZHMuKi52YWx1ZScpLmV4aXN0cygpLFxuXG4gICAgICBjaGVjaygnbm90ZScpLm9wdGlvbmFsKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZm9ybSA9IHtcbiAgICAgICAgY3VzdG9tX2ZpZWxkczogW10sXG4gICAgICAgIC4uLnJlcS5ib2R5LFxuICAgICAgfTtcbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuXG4gICAgICBjb25zdCBjb3N0QWNjb3VudFByb21pc2UgPSBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5jb3N0X2FjY291bnRfaWQpO1xuICAgICAgY29uc3Qgc2VsbEFjY291bnRQcm9taXNlID0gQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGZvcm0uc2VsbF9hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IGl0ZW1DYXRlZ29yeVByb21pc2UgPSAoZm9ybS5jYXRlZ29yeV9pZClcbiAgICAgICAgPyBJdGVtQ2F0ZWdvcnkucXVlcnkoKS5maW5kQnlJZChmb3JtLmNhdGVnb3J5X2lkKSA6IG51bGw7XG5cbiAgICAgIC8vIFZhbGlkYXRlIHRoZSBjdXN0b20gZmllbGRzIGtleSBhbmQgdmFsdWUgdHlwZS5cbiAgICAgIGlmIChmb3JtLmN1c3RvbV9maWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCBjdXN0b21GaWVsZHNLZXlzID0gZm9ybS5jdXN0b21fZmllbGRzLm1hcCgoZmllbGQpID0+IGZpZWxkLmtleSk7XG5cbiAgICAgICAgLy8gR2V0IHJlc291cmNlIGlkIHRoYW4gZ2V0IGFsbCByZXNvdXJjZSBmaWVsZHMuXG4gICAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgUmVzb3VyY2Uud2hlcmUoJ25hbWUnLCAnaXRlbXMnKS5mZXRjaCgpO1xuICAgICAgICBjb25zdCBmaWVsZHMgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLnF1ZXJ5KChxdWVyeSkgPT4ge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdyZXNvdXJjZV9pZCcsIHJlc291cmNlLmlkKTtcbiAgICAgICAgICBxdWVyeS53aGVyZUluKCdrZXknLCBjdXN0b21GaWVsZHNLZXlzKTtcbiAgICAgICAgfSkuZmV0Y2hBbGwoKTtcblxuICAgICAgICBjb25zdCBzdG9yZWRGaWVsZHNLZXkgPSBmaWVsZHMubWFwKChmKSA9PiBmLmF0dHJpYnV0ZXMua2V5KTtcblxuICAgICAgICAvLyBHZXQgYWxsIG5vdCBkZWZpbmVkIHJlc291cmNlIGZpZWxkcy5cbiAgICAgICAgY29uc3Qgbm90Rm91bmRGaWVsZHMgPSBkaWZmZXJlbmNlKGN1c3RvbUZpZWxkc0tleXMsIHN0b3JlZEZpZWxkc0tleSk7XG5cbiAgICAgICAgaWYgKG5vdEZvdW5kRmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdGSUVMRF9LRVlfTk9UX0ZPVU5EJywgY29kZTogMTUwLCBmaWVsZHM6IG5vdEZvdW5kRmllbGRzIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjb25zdCBbY29zdEFjY291bnQsIHNlbGxBY2NvdW50LCBpdGVtQ2F0ZWdvcnldID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgICBjb3N0QWNjb3VudFByb21pc2UsIHNlbGxBY2NvdW50UHJvbWlzZSwgaXRlbUNhdGVnb3J5UHJvbWlzZSxcbiAgICAgIF0pO1xuICAgICAgaWYgKCFjb3N0QWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdDT1NUX0FDQ09VTlRfTk9UX0ZPVU5EJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFzZWxsQWNjb3VudCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdTRUxMX0FDQ09VTlRfTk9UX0ZPVU5EJywgY29kZTogMTIwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKCFpdGVtQ2F0ZWdvcnkgJiYgZm9ybS5jYXRlZ29yeV9pZCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdJVEVNX0NBVEVHT1JZX05PVF9GT1VORCcsIGNvZGU6IDE0MCB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgaXRlbSA9IGF3YWl0IEl0ZW0ucXVlcnkoKS5pbnNlcnRBbmRGZXRjaCh7XG4gICAgICAgIG5hbWU6IGZvcm0ubmFtZSxcbiAgICAgICAgdHlwZTogZm9ybS50eXBlLFxuICAgICAgICBjb3N0X3ByaWNlOiBmb3JtLmNvc3RfcHJpY2UsXG4gICAgICAgIHNlbGxfcHJpY2U6IGZvcm0uc2VsbF9wcmljZSxcbiAgICAgICAgc2VsbF9hY2NvdW50X2lkOiBmb3JtLnNlbGxfYWNjb3VudF9pZCxcbiAgICAgICAgY29zdF9hY2NvdW50X2lkOiBmb3JtLmNvc3RfYWNjb3VudF9pZCxcbiAgICAgICAgY3VycmVuY3lfY29kZTogZm9ybS5jdXJyZW5jeV9jb2RlLFxuICAgICAgICBub3RlOiBmb3JtLm5vdGUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IGlkOiBpdGVtLmlkIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEVkaXQgdGhlIGdpdmVuIGl0ZW0uXG4gICAqL1xuICBlZGl0SXRlbToge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCduYW1lJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygndHlwZScpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKS5pc0luKFsncHJvZHVjdCcsICdzZXJ2aWNlJ10pLFxuICAgICAgY2hlY2soJ2Nvc3RfcHJpY2UnKS5leGlzdHMoKS5pc051bWVyaWMoKSxcbiAgICAgIGNoZWNrKCdzZWxsX3ByaWNlJykuZXhpc3RzKCkuaXNOdW1lcmljKCksXG4gICAgICBjaGVjaygnY29zdF9hY2NvdW50X2lkJykuZXhpc3RzKCkuaXNJbnQoKSxcbiAgICAgIGNoZWNrKCdzZWxsX2FjY291bnRfaWQnKS5leGlzdHMoKS5pc0ludCgpLFxuICAgICAgY2hlY2soJ2NhdGVnb3J5X2lkJykub3B0aW9uYWwoKS5pc0ludCgpLFxuICAgICAgY2hlY2soJ25vdGUnKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGZvcm0gPSB7XG4gICAgICAgIGN1c3RvbV9maWVsZHM6IFtdLFxuICAgICAgICAuLi5yZXEuYm9keSxcbiAgICAgIH07XG4gICAgICBjb25zdCBpdGVtID0gYXdhaXQgSXRlbS5xdWVyeSgpLmZpbmRCeUlkKGlkKTtcbiAgICAgIFxuICAgICAgaWYgKCFpdGVtKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7IGVycm9yczogW1xuICAgICAgICAgIHsgdHlwZTogJ0lURU0uTk9ULkZPVU5EJywgY29kZTogMTAwIH0sXG4gICAgICAgIF19KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGVycm9yUmVhc29ucyA9IFtdO1xuXG4gICAgICBjb25zdCBjb3N0QWNjb3VudFByb21pc2UgPSBBY2NvdW50LnF1ZXJ5KCkuZmluZEJ5SWQoZm9ybS5jb3N0X2FjY291bnRfaWQpO1xuICAgICAgY29uc3Qgc2VsbEFjY291bnRQcm9taXNlID0gQWNjb3VudC5xdWVyeSgpLmZpbmRCeUlkKGZvcm0uc2VsbF9hY2NvdW50X2lkKTtcbiAgICAgIGNvbnN0IGl0ZW1DYXRlZ29yeVByb21pc2UgPSAoZm9ybS5jYXRlZ29yeV9pZClcbiAgICAgICAgPyBJdGVtQ2F0ZWdvcnkucXVlcnkoKS5maW5kQnlJZChmb3JtLmNhdGVnb3J5X2lkKSA6IG51bGw7XG5cbiAgICAgIGNvbnN0IFtjb3N0QWNjb3VudCwgc2VsbEFjY291bnQsIGl0ZW1DYXRlZ29yeV0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIGNvc3RBY2NvdW50UHJvbWlzZSwgc2VsbEFjY291bnRQcm9taXNlLCBpdGVtQ2F0ZWdvcnlQcm9taXNlLFxuICAgICAgXSk7XG4gICAgICBpZiAoIWNvc3RBY2NvdW50KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0NPU1RfQUNDT1VOVF9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIXNlbGxBY2NvdW50KSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1NFTExfQUNDT1VOVF9OT1RfRk9VTkQnLCBjb2RlOiAxMjAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoIWl0ZW1DYXRlZ29yeSAmJiBmb3JtLmNhdGVnb3J5X2lkKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ0lURU1fQ0FURUdPUllfTk9UX0ZPVU5EJywgY29kZTogMTQwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVwZGF0ZWRJdGVtID0gYXdhaXQgSXRlbS5xdWVyeSgpLmZpbmRCeUlkKGlkKS5wYXRjaCh7XG4gICAgICAgIG5hbWU6IGZvcm0ubmFtZSxcbiAgICAgICAgdHlwZTogZm9ybS50eXBlLFxuICAgICAgICBjb3N0X3ByaWNlOiBmb3JtLmNvc3RfcHJpY2UsXG4gICAgICAgIHNlbGxfcHJpY2U6IGZvcm0uc2VsbF9wcmljZSxcbiAgICAgICAgY3VycmVuY3lfY29kZTogZm9ybS5jdXJyZW5jeV9jb2RlLFxuICAgICAgICBzZWxsX2FjY291bnRfaWQ6IGZvcm0uc2VsbF9hY2NvdW50X2lkLFxuICAgICAgICBjb3N0X2FjY291bnRfaWQ6IGZvcm0uY29zdF9hY2NvdW50X2lkLFxuICAgICAgICBjYXRlZ29yeV9pZDogZm9ybS5jYXRlZ29yeV9pZCxcbiAgICAgICAgbm90ZTogZm9ybS5ub3RlLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogdXBkYXRlZEl0ZW0uaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlbiBpdGVtIGZyb20gdGhlIHN0b3JhZ2UuXG4gICAqL1xuICBkZWxldGVJdGVtOiB7XG4gICAgdmFsaWRhdGlvbjogW10sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IGl0ZW0gPSBhd2FpdCBJdGVtLnF1ZXJ5KCkuZmluZEJ5SWQoaWQpO1xuXG4gICAgICBpZiAoIWl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdJVEVNX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIERlbGV0ZSB0aGUgZnVja2luZyB0aGUgZ2l2ZW4gaXRlbSBpZC5cbiAgICAgIGF3YWl0IEl0ZW0ucXVlcnkoKS5maW5kQnlJZChpdGVtLmlkKS5kZWxldGUoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogUmV0cml2ZSB0aGUgbGlzdCBpdGVtcyB3aXRoIHBhZ2luYXRpb24gbWV0YS5cbiAgICovXG4gIGxpc3RJdGVtczoge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IGZpbHRlciA9IHtcbiAgICAgICAgbmFtZTogJycsXG4gICAgICAgIGRlc2NyaXB0aW9uOiAnJyxcbiAgICAgICAgU0tVOiAnJyxcbiAgICAgICAgYWNjb3VudF9pZDogbnVsbCxcbiAgICAgICAgcGFnZV9zaXplOiAxMCxcbiAgICAgICAgcGFnZTogMSxcbiAgICAgICAgc3RhcnRfZGF0ZTogbnVsbCxcbiAgICAgICAgZW5kX2RhdGU6IG51bGwsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGl0ZW1zID0gYXdhaXQgSXRlbS5xdWVyeSgocXVlcnkpID0+IHtcbiAgICAgICAgaWYgKGZpbHRlci5kZXNjcmlwdGlvbikge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdkZXNjcmlwdGlvbicsICdsaWtlJywgYCUke2ZpbHRlci5kZXNjcmlwdGlvbn0lYCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5kZXNjcmlwdGlvbikge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdTS1UnLCBmaWx0ZXIuU0tZKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLm5hbWUpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnbmFtZScsIGZpbHRlci5uYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLnN0YXJ0X2RhdGUpIHtcbiAgICAgICAgICBjb25zdCBzdGFydERhdGVGb3JtYXR0ZWQgPSBtb21lbnQoZmlsdGVyLnN0YXJ0X2RhdGUpLmZvcm1hdCgnWVlZWS1NTS1ERCBISDptbTpTUycpO1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdjcmVhdGVkX2F0JywgJz49Jywgc3RhcnREYXRlRm9ybWF0dGVkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZmlsdGVyLmVuZF9kYXRlKSB7XG4gICAgICAgICAgY29uc3QgZW5kRGF0ZUZvcm1hdHRlZCA9IG1vbWVudChmaWx0ZXIuZW5kX2RhdGUpLmZvcm1hdCgnWVlZWS1NTS1ERCBISDptbTpTUycpO1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdjcmVhdGVkX2F0JywgJzw9JywgZW5kRGF0ZUZvcm1hdHRlZCk7XG4gICAgICAgIH1cbiAgICAgIH0pLmZldGNoUGFnZSh7XG4gICAgICAgIHBhZ2Vfc2l6ZTogZmlsdGVyLnBhZ2Vfc2l6ZSxcbiAgICAgICAgcGFnZTogZmlsdGVyLnBhZ2UsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgaXRlbXM6IGl0ZW1zLnRvSlNPTigpLFxuICAgICAgICBwYWdpbmF0aW9uOiBpdGVtcy5wYWdpbmF0aW9uLFxuICAgICAgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGJvZHksIHF1ZXJ5LCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IE9wdGlvbiBmcm9tICdAL21vZGVscy9PcHRpb24nO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHRoaXMuc2F2ZU9wdGlvbnMudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLnNhdmVPcHRpb25zLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgdGhpcy5nZXRPcHRpb25zLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRTZXR0aW5ncykpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogU2F2ZXMgdGhlIGdpdmVuIG9wdGlvbnMgdG8gdGhlIHN0b3JhZ2UuXG4gICAqL1xuICBzYXZlT3B0aW9uczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGJvZHkoJ29wdGlvbnMnKS5pc0FycmF5KCksXG4gICAgICBib2R5KCdvcHRpb25zLioua2V5JykuZXhpc3RzKCksXG4gICAgICBib2R5KCdvcHRpb25zLioudmFsdWUnKS5leGlzdHMoKSxcbiAgICAgIGJvZHkoJ29wdGlvbnMuKi5ncm91cCcpLmV4aXN0cygpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ1ZBTElEQVRJT05fRVJST1InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCBvcHRpb25zQ29sbGVjdGlvbnMgPSBhd2FpdCBPcHRpb24ucXVlcnkoKTtcblxuICAgICAgZm9ybS5vcHRpb25zLmZvckVhY2goKG9wdGlvbikgPT4ge1xuICAgICAgICBvcHRpb25zQ29sbGVjdGlvbnMuc2V0TWV0YShvcHRpb24ua2V5LCBvcHRpb24udmFsdWUsIG9wdGlvbi5ncm91cCk7XG4gICAgICB9KTtcbiAgICAgIGF3YWl0IG9wdGlvbnNDb2xsZWN0aW9ucy5zYXZlTWV0YSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgYXBwbGljYXRpb24gb3B0aW9ucyBmcm9tIHRoZSBzdG9yYWdlLlxuICAgKi9cbiAgZ2V0T3B0aW9uczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHF1ZXJ5KCdrZXknKS5vcHRpb25hbCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ1ZBTElEQVRJT05fRVJST1InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG9wdGlvbnMgPSBhd2FpdCBPcHRpb24ucXVlcnkoKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kcyh7IG9wdGlvbnMgfSk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7XG4gIHBhcmFtLFxuICBxdWVyeSxcbiAgdmFsaWRhdGlvblJlc3VsdCxcbn0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IGp3dEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci51c2Uoand0QXV0aCk7XG5cbiAgICByb3V0ZXIuZ2V0KCcvOnJlc291cmNlX3NsdWcvY29sdW1ucycsXG4gICAgICB0aGlzLnJlc291cmNlQ29sdW1ucy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMucmVzb3VyY2VDb2x1bW5zLmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy86cmVzb3VyY2Vfc2x1Zy9maWVsZHMnLFxuICAgICAgdGhpcy5yZXNvdXJjZUZpZWxkcy52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMucmVzb3VyY2VGaWVsZHMuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogUmV0cmlldmUgcmVzb3VyY2UgY29sdW1ucyBvZiB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAqL1xuICByZXNvdXJjZUNvbHVtbnM6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgncmVzb3VyY2Vfc2x1ZycpLnRyaW0oKS5lc2NhcGUoKS5leGlzdHMoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgcmVzb3VyY2Vfc2x1ZzogcmVzb3VyY2VTbHVnIH0gPSByZXEucGFyYW1zO1xuXG4gICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCduYW1lJywgcmVzb3VyY2VTbHVnKVxuICAgICAgICAud2l0aEdyYXBoRmV0Y2hlZCgnZmllbGRzJylcbiAgICAgICAgLmZpcnN0KCk7XG5cbiAgICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoNDAwKS5zZW5kKHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdSRVNPVVJDRS5TTFVHLk5PVC5GT1VORCcsIGNvZGU6IDIwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXNvdXJjZUZpZWxkcyA9IHJlc291cmNlLmZpZWxkc1xuICAgICAgICAuZmlsdGVyKChmaWVsZCkgPT4gZmllbGQuY29sdW1uYWJsZSlcbiAgICAgICAgLm1hcCgoZmllbGQpID0+ICh7XG4gICAgICAgICAgaWQ6IGZpZWxkLmlkLFxuICAgICAgICAgIGxhYmVsOiBmaWVsZC5sYWJlbE5hbWUsXG4gICAgICAgICAga2V5OiBmaWVsZC5rZXksXG4gICAgICAgIH0pKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHtcbiAgICAgICAgcmVzb3VyY2VfY29sdW1uczogcmVzb3VyY2VGaWVsZHMsXG4gICAgICAgIHJlc291cmNlX3NsdWc6IHJlc291cmNlU2x1ZyxcbiAgICAgIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHJlc291cmNlIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAqL1xuICByZXNvdXJjZUZpZWxkczoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCdyZXNvdXJjZV9zbHVnJykudHJpbSgpLmVzY2FwZSgpLmV4aXN0cygpLFxuICAgICAgcXVlcnkoJ3ByZWRlZmluZWQnKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgICAgcXVlcnkoJ2J1aWx0aW4nKS5vcHRpb25hbCgpLmlzQm9vbGVhbigpLnRvQm9vbGVhbigpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyByZXNvdXJjZV9zbHVnOiByZXNvdXJjZVNsdWcgfSA9IHJlcS5wYXJhbXM7XG5cbiAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgUmVzb3VyY2UucXVlcnkoKVxuICAgICAgICAud2hlcmUoJ25hbWUnLCByZXNvdXJjZVNsdWcpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCdmaWVsZHMnKVxuICAgICAgICAuZmlyc3QoKTtcblxuICAgICAgaWYgKCFyZXNvdXJjZSkge1xuICAgICAgICByZXR1cm4gcmVzLnN0YXR1cyg0MDApLnNlbmQoe1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1JFU09VUkNFLlNMVUcuTk9ULkZPVU5EJywgY29kZTogMjAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7XG4gICAgICAgIHJlc291cmNlX2ZpZWxkczogcmVzb3VyY2UuZmllbGRzLFxuICAgICAgICByZXNvdXJjZV9zbHVnOiByZXNvdXJjZVNsdWcsXG4gICAgICB9KTtcbiAgICB9LFxuICB9LFxufTtcbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGNoZWNrLCB2YWxpZGF0aW9uUmVzdWx0IH0gZnJvbSAnZXhwcmVzcy12YWxpZGF0b3InO1xuaW1wb3J0IHsgZGlmZmVyZW5jZSB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgUm9sZSBmcm9tICdAL21vZGVscy9Sb2xlJztcbmltcG9ydCBQZXJtaXNzaW9uIGZyb20gJ0AvbW9kZWxzL1Blcm1pc3Npb24nO1xuaW1wb3J0IFJlc291cmNlIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlJztcbmltcG9ydCBrbmV4IGZyb20gJ0AvZGF0YWJhc2Uva25leCc7XG5cbmNvbnN0IEFjY2Vzc0NvbnRyb2xsU2NoZW1hID0gW1xuICB7XG4gICAgcmVzb3VyY2U6ICdpdGVtcycsXG4gICAgbGFiZWw6ICdwcm9kdWN0c19zZXJ2aWNlcycsXG4gICAgcGVybWlzc2lvbnM6IFsnY3JlYXRlJywgJ2VkaXQnLCAnZGVsZXRlJywgJ3ZpZXcnXSxcbiAgICBmdWxsQWNjZXNzOiB0cnVlLFxuICAgIG93bkNvbnRyb2w6IHRydWUsXG4gIH0sXG5dO1xuXG5jb25zdCBnZXRSZXNvdXJjZVNjaGVtYSA9IChyZXNvdXJjZSkgPT4gQWNjZXNzQ29udHJvbGxTY2hlbWFcbiAgLmZpbmQoKHNjaGVtYSkgPT4gc2NoZW1hLnJlc291cmNlID09PSByZXNvdXJjZSk7XG5cbmNvbnN0IGdldFJlc291cmNlUGVybWlzc2lvbnMgPSAocmVzb3VyY2UpID0+IHtcbiAgY29uc3QgZm91bmRSZXNvdXJjZSA9IGdldFJlc291cmNlU2NoZW1hKHJlc291cmNlKTtcbiAgcmV0dXJuIGZvdW5kUmVzb3VyY2UgPyBmb3VuZFJlc291cmNlLnBlcm1pc3Npb25zIDogW107XG59O1xuXG5jb25zdCBmaW5kTm90Rm91bmRSZXNvdXJjZXMgPSAocmVzb3VyY2VzU2x1Z3MpID0+IHtcbiAgY29uc3Qgc2NoZW1hUmVzb3VyY2VzU2x1Z3MgPSBBY2Nlc3NDb250cm9sbFNjaGVtYS5tYXAoKHMpID0+IHMucmVzb3VyY2UpO1xuICByZXR1cm4gZGlmZmVyZW5jZShyZXNvdXJjZXNTbHVncywgc2NoZW1hUmVzb3VyY2VzU2x1Z3MpO1xufTtcblxuY29uc3QgZmluZE5vdEZvdW5kUGVybWlzc2lvbnMgPSAocGVybWlzc2lvbnMsIHJlc291cmNlU2x1ZykgPT4ge1xuICBjb25zdCBzY2hlbWFQZXJtaXNzaW9ucyA9IGdldFJlc291cmNlUGVybWlzc2lvbnMocmVzb3VyY2VTbHVnKTtcbiAgcmV0dXJuIGRpZmZlcmVuY2UocGVybWlzc2lvbnMsIHNjaGVtYVBlcm1pc3Npb25zKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3RvciBtZXRob2QuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIHRoaXMubmV3Um9sZS52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMubmV3Um9sZS5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLzppZCcsXG4gICAgICB0aGlzLmVkaXRSb2xlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5lZGl0Um9sZS5oYW5kbGVyLmJpbmQodGhpcykpKTtcblxuICAgIHJvdXRlci5kZWxldGUoJy86aWQnLFxuICAgICAgdGhpcy5kZWxldGVSb2xlLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVSb2xlLmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgcm9sZS5cbiAgICovXG4gIG5ld1JvbGU6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdkZXNjcmlwdGlvbicpLm9wdGlvbmFsKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ3Blcm1pc3Npb25zJykuaXNBcnJheSh7IG1pbjogMCB9KSxcbiAgICAgIGNoZWNrKCdwZXJtaXNzaW9ucy4qLnJlc291cmNlX3NsdWcnKS5leGlzdHMoKS53aGl0ZWxpc3QoJ15bYS16MC05XSsoPzotW2EtejAtOV0rKSokJyksXG4gICAgICBjaGVjaygncGVybWlzc2lvbnMuKi5wZXJtaXNzaW9ucycpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBuYW1lLCBkZXNjcmlwdGlvbiwgcGVybWlzc2lvbnMgfSA9IHJlcS5ib2R5O1xuXG4gICAgICBjb25zdCByZXNvdXJjZXNTbHVncyA9IHBlcm1pc3Npb25zLm1hcCgocGVybSkgPT4gcGVybS5yZXNvdXJjZV9zbHVnKTtcbiAgICAgIGNvbnN0IHBlcm1pc3Npb25zU2x1Z3MgPSBbXTtcbiAgICAgIGNvbnN0IHJlc291cmNlc05vdEZvdW5kID0gZmluZE5vdEZvdW5kUmVzb3VyY2VzKHJlc291cmNlc1NsdWdzKTtcblxuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBub3RGb3VuZFBlcm1pc3Npb25zID0gW107XG5cbiAgICAgIGlmIChyZXNvdXJjZXNOb3RGb3VuZC5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnUkVTT1VSQ0VfU0xVR19OT1RfRk9VTkQnLCBjb2RlOiAxMDAsIHJlc291cmNlczogcmVzb3VyY2VzTm90Rm91bmQsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcGVybWlzc2lvbnMuZm9yRWFjaCgocGVybSkgPT4ge1xuICAgICAgICBjb25zdCBhYmlsaXRpZXMgPSBwZXJtLnBlcm1pc3Npb25zLm1hcCgoYWJpbGl0eSkgPT4gYWJpbGl0eSk7XG5cbiAgICAgICAgLy8gR2V0cyB0aGUgbm90IGZvdW5kIHBlcm1pc3Npb25zIGluIHRoZSBzY2hlbWEuXG4gICAgICAgIGNvbnN0IG5vdEZvdW5kQWJpbGl0aWVzID0gZmluZE5vdEZvdW5kUGVybWlzc2lvbnMoYWJpbGl0aWVzLCBwZXJtLnJlc291cmNlX3NsdWcpO1xuICAgICAgICBcbiAgICAgICAgaWYgKG5vdEZvdW5kQWJpbGl0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBub3RGb3VuZFBlcm1pc3Npb25zLnB1c2goe1xuICAgICAgICAgICAgcmVzb3VyY2Vfc2x1ZzogcGVybS5yZXNvdXJjZV9zbHVnLFxuICAgICAgICAgICAgcGVybWlzc2lvbnM6IG5vdEZvdW5kQWJpbGl0aWVzLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHBlcm1zID0gcGVybS5wZXJtaXNzaW9ucyB8fCBbXTtcbiAgICAgICAgICBwZXJtcy5mb3JFYWNoKChwZXJtaXNzaW9uKSA9PiB7XG4gICAgICAgICAgICBpZiAocGVybXMuaW5kZXhPZihwZXJtaXNzaW9uKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgcGVybWlzc2lvbnNTbHVncy5wdXNoKHBlcm1pc3Npb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGlmIChub3RGb3VuZFBlcm1pc3Npb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goe1xuICAgICAgICAgIHR5cGU6ICdQRVJNSVNTSU9OU19TTFVHX05PVF9GT1VORCcsXG4gICAgICAgICAgY29kZTogMjAwLFxuICAgICAgICAgIHBlcm1pc3Npb25zOiBub3RGb3VuZFBlcm1pc3Npb25zLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmIChlcnJvclJlYXNvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7IGVycm9yczogZXJyb3JSZWFzb25zIH0pO1xuICAgICAgfVxuICAgICAgLy8gUGVybWlzc2lvbnMuXG4gICAgICBjb25zdCBbcmVzb3VyY2VzQ29sbGVjdGlvbiwgcGVybXNDb2xsZWN0aW9uXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgUmVzb3VyY2UucXVlcnkoKHF1ZXJ5KSA9PiB7IHF1ZXJ5LndoZXJlSW4oJ25hbWUnLCByZXNvdXJjZXNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICAgIFBlcm1pc3Npb24ucXVlcnkoKHF1ZXJ5KSA9PiB7IHF1ZXJ5LndoZXJlSW4oJ25hbWUnLCBwZXJtaXNzaW9uc1NsdWdzKTsgfSkuZmV0Y2hBbGwoKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBub3RTdG9yZWRSZXNvdXJjZXMgPSBkaWZmZXJlbmNlKFxuICAgICAgICByZXNvdXJjZXNTbHVncywgcmVzb3VyY2VzQ29sbGVjdGlvbi5tYXAoKHMpID0+IHMubmFtZSksXG4gICAgICApO1xuICAgICAgY29uc3Qgbm90U3RvcmVkUGVybWlzc2lvbnMgPSBkaWZmZXJlbmNlKFxuICAgICAgICBwZXJtaXNzaW9uc1NsdWdzLCBwZXJtc0NvbGxlY3Rpb24ubWFwKChwZXJtKSA9PiBwZXJtLnNsdWcpLFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW5zZXJ0VGhyZWFkID0gW107XG5cbiAgICAgIGlmIChub3RTdG9yZWRSZXNvdXJjZXMubGVuZ3RoID4gMCkge1xuICAgICAgICBpbnNlcnRUaHJlYWQucHVzaChrbmV4KCdyZXNvdXJjZXMnKS5pbnNlcnQoW1xuICAgICAgICAgIC4uLm5vdFN0b3JlZFJlc291cmNlcy5tYXAoKHJlc291cmNlKSA9PiAoeyBuYW1lOiByZXNvdXJjZSB9KSksXG4gICAgICAgIF0pKTtcbiAgICAgIH1cbiAgICAgIGlmIChub3RTdG9yZWRQZXJtaXNzaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGluc2VydFRocmVhZC5wdXNoKGtuZXgoJ3Blcm1pc3Npb25zJykuaW5zZXJ0KFtcbiAgICAgICAgICAuLi5ub3RTdG9yZWRQZXJtaXNzaW9ucy5tYXAoKHBlcm1pc3Npb24pID0+ICh7IG5hbWU6IHBlcm1pc3Npb24gfSkpLFxuICAgICAgICBdKSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKGluc2VydFRocmVhZCk7XG5cbiAgICAgIGNvbnN0IFtzdG9yZWRQZXJtaXNzaW9ucywgc3RvcmVkUmVzb3VyY2VzXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgUGVybWlzc2lvbi5xdWVyeSgocSkgPT4geyBxLndoZXJlSW4oJ25hbWUnLCBwZXJtaXNzaW9uc1NsdWdzKTsgfSkuZmV0Y2hBbGwoKSxcbiAgICAgICAgUmVzb3VyY2UucXVlcnkoKHEpID0+IHsgcS53aGVyZUluKCduYW1lJywgcmVzb3VyY2VzU2x1Z3MpOyB9KS5mZXRjaEFsbCgpLFxuICAgICAgXSk7XG5cbiAgICAgIGNvbnN0IHN0b3JlZFJlc291cmNlc1NldCA9IG5ldyBNYXAoc3RvcmVkUmVzb3VyY2VzLm1hcCgocmVzb3VyY2UpID0+IFtcbiAgICAgICAgcmVzb3VyY2UuYXR0cmlidXRlcy5uYW1lLCByZXNvdXJjZS5hdHRyaWJ1dGVzLmlkLFxuICAgICAgXSkpO1xuICAgICAgY29uc3Qgc3RvcmVkUGVybWlzc2lvbnNTZXQgPSBuZXcgTWFwKHN0b3JlZFBlcm1pc3Npb25zLm1hcCgocGVybSkgPT4gW1xuICAgICAgICBwZXJtLmF0dHJpYnV0ZXMubmFtZSwgcGVybS5hdHRyaWJ1dGVzLmlkLFxuICAgICAgXSkpO1xuICAgICAgY29uc3Qgcm9sZSA9IFJvbGUuZm9yZ2UoeyBuYW1lLCBkZXNjcmlwdGlvbiB9KTtcblxuICAgICAgYXdhaXQgcm9sZS5zYXZlKCk7XG5cbiAgICAgIGNvbnN0IHJvbGVIYXNQZXJtcyA9IHBlcm1pc3Npb25zLm1hcCgocmVzb3VyY2UpID0+IHJlc291cmNlLnBlcm1pc3Npb25zLm1hcCgocGVybSkgPT4gKHtcbiAgICAgICAgcm9sZV9pZDogcm9sZS5pZCxcbiAgICAgICAgcmVzb3VyY2VfaWQ6IHN0b3JlZFJlc291cmNlc1NldC5nZXQocmVzb3VyY2UucmVzb3VyY2Vfc2x1ZyksXG4gICAgICAgIHBlcm1pc3Npb25faWQ6IHN0b3JlZFBlcm1pc3Npb25zU2V0LmdldChwZXJtKSxcbiAgICAgIH0pKSk7XG5cbiAgICAgIGlmIChyb2xlSGFzUGVybXMubGVuZ3RoID4gMCkge1xuICAgICAgICBhd2FpdCBrbmV4KCdyb2xlX2hhc19wZXJtaXNzaW9ucycpLmluc2VydChyb2xlSGFzUGVybXNbMF0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHJvbGUuZ2V0KCdpZCcpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIEVkaXQgdGhlIGdpdmUgcm9sZS5cbiAgICovXG4gIGVkaXRSb2xlOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ25hbWUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBjaGVjaygnZGVzY3JpcHRpb24nKS5vcHRpb25hbCgpLnRyaW0oKS5lc2NhcGUoKSxcbiAgICAgIGNoZWNrKCdwZXJtaXNzaW9ucycpLmlzQXJyYXkoeyBtaW46IDAgfSksXG4gICAgICBjaGVjaygncGVybWlzc2lvbnMuKi5yZXNvdXJjZV9zbHVnJykuZXhpc3RzKCkud2hpdGVsaXN0KCdeW2EtejAtOV0rKD86LVthLXowLTldKykqJCcpLFxuICAgICAgY2hlY2soJ3Blcm1pc3Npb25zLioucGVybWlzc2lvbnMnKS5pc0FycmF5KHsgbWluOiAxIH0pLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgeyBpZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHJvbGUgPSBhd2FpdCBSb2xlLndoZXJlKCdpZCcsIGlkKS5mZXRjaCgpO1xuXG4gICAgICBpZiAoIXJvbGUpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdST0xFX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHsgcGVybWlzc2lvbnMgfSA9IHJlcS5ib2R5O1xuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBwZXJtaXNzaW9uc1NsdWdzID0gW107XG4gICAgICBjb25zdCBub3RGb3VuZFBlcm1pc3Npb25zID0gW107XG5cbiAgICAgIGNvbnN0IHJlc291cmNlc1NsdWdzID0gcGVybWlzc2lvbnMubWFwKChwZXJtKSA9PiBwZXJtLnJlc291cmNlX3NsdWcpO1xuICAgICAgY29uc3QgcmVzb3VyY2VzTm90Rm91bmQgPSBmaW5kTm90Rm91bmRSZXNvdXJjZXMocmVzb3VyY2VzU2x1Z3MpO1xuXG4gICAgICBpZiAocmVzb3VyY2VzTm90Rm91bmQubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7XG4gICAgICAgICAgdHlwZTogJ1JFU09VUkNFX1NMVUdfTk9UX0ZPVU5EJyxcbiAgICAgICAgICBjb2RlOiAxMDAsXG4gICAgICAgICAgcmVzb3VyY2VzOiByZXNvdXJjZXNOb3RGb3VuZCxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHBlcm1pc3Npb25zLmZvckVhY2goKHBlcm0pID0+IHtcbiAgICAgICAgY29uc3QgYWJpbGl0aWVzID0gcGVybS5wZXJtaXNzaW9ucy5tYXAoKGFiaWxpdHkpID0+IGFiaWxpdHkpO1xuICAgICAgICAvLyBHZXRzIHRoZSBub3QgZm91bmQgcGVybWlzc2lvbnMgaW4gdGhlIHNjaGVtYS5cbiAgICAgICAgY29uc3Qgbm90Rm91bmRBYmlsaXRpZXMgPSBmaW5kTm90Rm91bmRQZXJtaXNzaW9ucyhhYmlsaXRpZXMsIHBlcm0ucmVzb3VyY2Vfc2x1Zyk7XG5cbiAgICAgICAgaWYgKG5vdEZvdW5kQWJpbGl0aWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBub3RGb3VuZFBlcm1pc3Npb25zLnB1c2goe1xuICAgICAgICAgICAgcmVzb3VyY2Vfc2x1ZzogcGVybS5yZXNvdXJjZV9zbHVnLCBwZXJtaXNzaW9uczogbm90Rm91bmRBYmlsaXRpZXMsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgcGVybXMgPSBwZXJtLnBlcm1pc3Npb25zIHx8IFtdO1xuICAgICAgICAgIHBlcm1zLmZvckVhY2goKHBlcm1pc3Npb24pID0+IHtcbiAgICAgICAgICAgIGlmIChwZXJtcy5pbmRleE9mKHBlcm1pc3Npb24pICE9PSAtMSkge1xuICAgICAgICAgICAgICBwZXJtaXNzaW9uc1NsdWdzLnB1c2gocGVybWlzc2lvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm90Rm91bmRQZXJtaXNzaW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHtcbiAgICAgICAgICB0eXBlOiAnUEVSTUlTU0lPTlNfU0xVR19OT1RfRk9VTkQnLFxuICAgICAgICAgIGNvZGU6IDIwMCxcbiAgICAgICAgICBwZXJtaXNzaW9uczogbm90Rm91bmRQZXJtaXNzaW9ucyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAoZXJyb3JSZWFzb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLmJhZFJlcXVlc3QobnVsbCwgeyBlcnJvcnM6IGVycm9yUmVhc29ucyB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gUGVybWlzc2lvbnMuXG4gICAgICBjb25zdCBbcmVzb3VyY2VzQ29sbGVjdGlvbiwgcGVybXNDb2xsZWN0aW9uXSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgUmVzb3VyY2UucXVlcnkoKHF1ZXJ5KSA9PiB7IHF1ZXJ5LndoZXJlSW4oJ25hbWUnLCByZXNvdXJjZXNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICAgIFBlcm1pc3Npb24ucXVlcnkoKHF1ZXJ5KSA9PiB7IHF1ZXJ5LndoZXJlSW4oJ25hbWUnLCBwZXJtaXNzaW9uc1NsdWdzKTsgfSkuZmV0Y2hBbGwoKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBub3RTdG9yZWRSZXNvdXJjZXMgPSBkaWZmZXJlbmNlKFxuICAgICAgICByZXNvdXJjZXNTbHVncywgcmVzb3VyY2VzQ29sbGVjdGlvbi5tYXAoKHMpID0+IHMubmFtZSksXG4gICAgICApO1xuICAgICAgY29uc3Qgbm90U3RvcmVkUGVybWlzc2lvbnMgPSBkaWZmZXJlbmNlKFxuICAgICAgICBwZXJtaXNzaW9uc1NsdWdzLCBwZXJtc0NvbGxlY3Rpb24ubWFwKChwZXJtKSA9PiBwZXJtLnNsdWcpLFxuICAgICAgKTtcbiAgICAgIGNvbnN0IGluc2VydFRocmVhZCA9IFtdO1xuXG4gICAgICBpZiAobm90U3RvcmVkUmVzb3VyY2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgaW5zZXJ0VGhyZWFkLnB1c2goa25leCgncmVzb3VyY2VzJykuaW5zZXJ0KFtcbiAgICAgICAgICAuLi5ub3RTdG9yZWRSZXNvdXJjZXMubWFwKChyZXNvdXJjZSkgPT4gKHsgbmFtZTogcmVzb3VyY2UgfSkpLFxuICAgICAgICBdKSk7XG4gICAgICB9XG4gICAgICBpZiAobm90U3RvcmVkUGVybWlzc2lvbnMubGVuZ3RoID4gMCkge1xuICAgICAgICBpbnNlcnRUaHJlYWQucHVzaChrbmV4KCdwZXJtaXNzaW9ucycpLmluc2VydChbXG4gICAgICAgICAgLi4ubm90U3RvcmVkUGVybWlzc2lvbnMubWFwKChwZXJtaXNzaW9uKSA9PiAoeyBuYW1lOiBwZXJtaXNzaW9uIH0pKSxcbiAgICAgICAgXSkpO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChpbnNlcnRUaHJlYWQpO1xuXG4gICAgICBjb25zdCBbc3RvcmVkUGVybWlzc2lvbnMsIHN0b3JlZFJlc291cmNlc10gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgIFBlcm1pc3Npb24ucXVlcnkoKHEpID0+IHsgcS53aGVyZUluKCduYW1lJywgcGVybWlzc2lvbnNTbHVncyk7IH0pLmZldGNoQWxsKCksXG4gICAgICAgIFJlc291cmNlLnF1ZXJ5KChxKSA9PiB7IHEud2hlcmVJbignbmFtZScsIHJlc291cmNlc1NsdWdzKTsgfSkuZmV0Y2hBbGwoKSxcbiAgICAgIF0pO1xuXG4gICAgICBjb25zdCBzdG9yZWRSZXNvdXJjZXNTZXQgPSBuZXcgTWFwKHN0b3JlZFJlc291cmNlcy5tYXAoKHJlc291cmNlKSA9PiBbXG4gICAgICAgIHJlc291cmNlLmF0dHJpYnV0ZXMubmFtZSwgcmVzb3VyY2UuYXR0cmlidXRlcy5pZCxcbiAgICAgIF0pKTtcbiAgICAgIGNvbnN0IHN0b3JlZFBlcm1pc3Npb25zU2V0ID0gbmV3IE1hcChzdG9yZWRQZXJtaXNzaW9ucy5tYXAoKHBlcm0pID0+IFtcbiAgICAgICAgcGVybS5hdHRyaWJ1dGVzLm5hbWUsIHBlcm0uYXR0cmlidXRlcy5pZCxcbiAgICAgIF0pKTtcblxuICAgICAgYXdhaXQgcm9sZS5zYXZlKCk7XG5cblxuICAgICAgY29uc3Qgc2F2ZWRSb2xlSGFzUGVybXMgPSBhd2FpdCBrbmV4KCdyb2xlX2hhc19wZXJtaXNzaW9ucycpLndoZXJlKHtcbiAgICAgICAgcm9sZV9pZDogcm9sZS5pZCxcbiAgICAgIH0pO1xuXG4gICAgICBjb25zb2xlLmxvZyhzYXZlZFJvbGVIYXNQZXJtcyk7XG5cbiAgICAgIC8vIGNvbnN0IHJvbGVIYXNQZXJtcyA9IHBlcm1pc3Npb25zLm1hcCgocmVzb3VyY2UpID0+IHJlc291cmNlLnBlcm1pc3Npb25zLm1hcCgocGVybSkgPT4gKHtcbiAgICAgIC8vICAgcm9sZV9pZDogcm9sZS5pZCxcbiAgICAgIC8vICAgcmVzb3VyY2VfaWQ6IHN0b3JlZFJlc291cmNlc1NldC5nZXQocmVzb3VyY2UucmVzb3VyY2Vfc2x1ZyksXG4gICAgICAvLyAgIHBlcm1pc3Npb25faWQ6IHN0b3JlZFBlcm1pc3Npb25zU2V0LmdldChwZXJtKSxcbiAgICAgIC8vIH0pKSk7XG5cbiAgICAgIC8vIGlmIChyb2xlSGFzUGVybXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gICBhd2FpdCBrbmV4KCdyb2xlX2hhc19wZXJtaXNzaW9ucycpLmluc2VydChyb2xlSGFzUGVybXNbMF0pO1xuICAgICAgLy8gfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHJvbGUuZ2V0KCdpZCcpIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgZGVsZXRlUm9sZToge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCByb2xlID0gYXdhaXQgUm9sZS53aGVyZSgnaWQnLCBpZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCFyb2xlKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZCgpO1xuICAgICAgfVxuICAgICAgaWYgKHJvbGUuYXR0cmlidXRlcy5wcmVkZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdST0xFX1BSRURFRklORUQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBrbmV4KCdyb2xlX2hhc19wZXJtaXNzaW9ucycpXG4gICAgICAgIC53aGVyZSgncm9sZV9pZCcsIHJvbGUuaWQpLmRlbGV0ZSh7IHJlcXVpcmU6IGZhbHNlIH0pO1xuXG4gICAgICBhd2FpdCByb2xlLmRlc3Ryb3koKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcblxuICBnZXRSb2xlOiB7XG4gICAgdmFsaWRhdGlvbjogW10sXG4gICAgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcbn07XG4iLCJpbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7XG4gIGNoZWNrLFxuICBxdWVyeSxcbiAgcGFyYW0sXG4gIHZhbGlkYXRpb25SZXN1bHQsXG59IGZyb20gJ2V4cHJlc3MtdmFsaWRhdG9yJztcbmltcG9ydCBVc2VyIGZyb20gJ0AvbW9kZWxzL1VzZXInO1xuaW1wb3J0IGFzeW5jTWlkZGxld2FyZSBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hc3luY01pZGRsZXdhcmUnO1xuaW1wb3J0IGp3dEF1dGggZnJvbSAnQC9odHRwL21pZGRsZXdhcmUvand0QXV0aCc7XG5pbXBvcnQgQXV0aG9yaXphdGlvbiBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9hdXRob3JpemF0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQge1xuXG4gIC8qKlxuICAgKiBSb3V0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICByb3V0ZXIoKSB7XG4gICAgY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTtcbiAgICAvLyBjb25zdCBwZXJtaXQgPSBBdXRob3JpemF0aW9uKCd1c2VycycpO1xuXG4gICAgcm91dGVyLnVzZShqd3RBdXRoKTtcblxuICAgIHJvdXRlci5wb3N0KCcvJyxcbiAgICAgIC8vIHBlcm1pdCgnY3JlYXRlJyksXG4gICAgICB0aGlzLm5ld1VzZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLm5ld1VzZXIuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86aWQnLFxuICAgICAgLy8gcGVybWl0KCdjcmVhdGUnLCAnZWRpdCcpLFxuICAgICAgdGhpcy5lZGl0VXNlci52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZWRpdFVzZXIuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLycsXG4gICAgICAvLyBwZXJtaXQoJ3ZpZXcnKSxcbiAgICAgIHRoaXMubGlzdFVzZXJzLnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5saXN0VXNlcnMuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLmdldCgnLzppZCcsXG4gICAgICAvLyBwZXJtaXQoJ3ZpZXcnKSxcbiAgICAgIHRoaXMuZ2V0VXNlci52YWxpZGF0aW9uLFxuICAgICAgYXN5bmNNaWRkbGV3YXJlKHRoaXMuZ2V0VXNlci5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOmlkJyxcbiAgICAgIC8vIHBlcm1pdCgnY3JlYXRlJywgJ2VkaXQnLCAnZGVsZXRlJyksXG4gICAgICB0aGlzLmRlbGV0ZVVzZXIudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmRlbGV0ZVVzZXIuaGFuZGxlcikpO1xuXG4gICAgcmV0dXJuIHJvdXRlcjtcbiAgfSxcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyB1c2VyLlxuICAgKi9cbiAgbmV3VXNlcjoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIGNoZWNrKCdmaXJzdF9uYW1lJykudHJpbSgpLmVzY2FwZSgpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ2xhc3RfbmFtZScpLnRyaW0oKS5lc2NhcGUoKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdlbWFpbCcpLmV4aXN0cygpLmlzRW1haWwoKSxcbiAgICAgIGNoZWNrKCdwaG9uZV9udW1iZXInKS5vcHRpb25hbCgpLmlzTW9iaWxlUGhvbmUoKSxcbiAgICAgIGNoZWNrKCdwYXNzd29yZCcpLmlzTGVuZ3RoKHsgbWluOiA0IH0pLmV4aXN0cygpLmN1c3RvbSgodmFsdWUsIHsgcmVxIH0pID0+IHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSByZXEuYm9keS5jb25maXJtX3Bhc3N3b3JkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFzc3dvcmRzIGRvbid0IG1hdGNoXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBjaGVjaygnc3RhdHVzJykuZXhpc3RzKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGlvblJlc3VsdChyZXEpO1xuXG4gICAgICBpZiAoIXZhbGlkYXRpb25FcnJvcnMuaXNFbXB0eSgpKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWREYXRhKG51bGwsIHtcbiAgICAgICAgICBjb2RlOiAndmFsaWRhdGlvbl9lcnJvcicsIC4uLnZhbGlkYXRpb25FcnJvcnMsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgeyBlbWFpbCwgcGhvbmVfbnVtYmVyOiBwaG9uZU51bWJlciB9ID0gcmVxLmJvZHk7XG5cbiAgICAgIGNvbnN0IGZvdW5kVXNlcnMgPSBhd2FpdCBVc2VyLnF1ZXJ5KClcbiAgICAgICAgLndoZXJlKCdlbWFpbCcsIGVtYWlsKVxuICAgICAgICAub3JXaGVyZSgncGhvbmVfbnVtYmVyJywgcGhvbmVOdW1iZXIpO1xuXG4gICAgICBjb25zdCBmb3VuZFVzZXJFbWFpbCA9IGZvdW5kVXNlcnMuZmluZCgodSkgPT4gdS5lbWFpbCA9PT0gZW1haWwpO1xuICAgICAgY29uc3QgZm91bmRVc2VyUGhvbmUgPSBmb3VuZFVzZXJzLmZpbmQoKHUpID0+IHUucGhvbmVOdW1iZXIgPT09IHBob25lTnVtYmVyKTtcblxuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG5cbiAgICAgIGlmIChmb3VuZFVzZXJFbWFpbCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdFTUFJTF9BTFJFQURZX0VYSVNUJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGZvdW5kVXNlclBob25lKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1BIT05FX05VTUJFUl9BTFJFQURZX0VYSVNUJywgY29kZTogMTIwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBVc2VyLnF1ZXJ5KCkuaW5zZXJ0KHtcbiAgICAgICAgZmlyc3RfbmFtZTogcmVxLmJvZHkuZmlyc3RfbmFtZSxcbiAgICAgICAgbGFzdF9uYW1lOiByZXEuYm9keS5sYXN0X25hbWUsXG4gICAgICAgIGVtYWlsOiByZXEuYm9keS5lbWFpbCxcbiAgICAgICAgcGhvbmVfbnVtYmVyOiByZXEuYm9keS5waG9uZV9udW1iZXIsXG4gICAgICAgIGFjdGl2ZTogcmVxLmJvZHkuc3RhdHVzLFxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IHVzZXIgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRWRpdCBkZXRhaWxzIG9mIHRoZSBnaXZlbiB1c2VyLlxuICAgKi9cbiAgZWRpdFVzZXI6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgnaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgICAgY2hlY2soJ2ZpcnN0X25hbWUnKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdsYXN0X25hbWUnKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdlbWFpbCcpLmV4aXN0cygpLmlzRW1haWwoKSxcbiAgICAgIGNoZWNrKCdwaG9uZV9udW1iZXInKS5vcHRpb25hbCgpLmlzTW9iaWxlUGhvbmUoKSxcbiAgICAgIGNoZWNrKCdwYXNzd29yZCcpLmlzTGVuZ3RoKHsgbWluOiA0IH0pLmV4aXN0cygpLmN1c3RvbSgodmFsdWUsIHsgcmVxIH0pID0+IHtcbiAgICAgICAgaWYgKHZhbHVlICE9PSByZXEuYm9keS5jb25maXJtX3Bhc3N3b3JkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiUGFzc3dvcmRzIGRvbid0IG1hdGNoXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfSksXG4gICAgICBjaGVjaygnc3RhdHVzJykuZXhpc3RzKCkuaXNCb29sZWFuKCkudG9Cb29sZWFuKCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IGlkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBVc2VyLnF1ZXJ5KCkud2hlcmUoJ2lkJywgaWQpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghdXNlcikge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQoKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHsgZW1haWwsIHBob25lX251bWJlcjogcGhvbmVOdW1iZXIgfSA9IHJlcS5ib2R5O1xuXG4gICAgICBjb25zdCBmb3VuZFVzZXJzID0gYXdhaXQgVXNlci5xdWVyeSgpXG4gICAgICAgIC53aGVyZU5vdCgnaWQnLCBpZClcbiAgICAgICAgLmFuZFdoZXJlKChxKSA9PiB7XG4gICAgICAgICAgcS53aGVyZSgnZW1haWwnLCBlbWFpbCk7XG4gICAgICAgICAgcS5vcldoZXJlKCdwaG9uZV9udW1iZXInLCBwaG9uZU51bWJlcik7XG4gICAgICAgIH0pO1xuXG4gICAgICBjb25zdCBmb3VuZFVzZXJFbWFpbCA9IGZvdW5kVXNlcnMuZmluZCgodSkgPT4gdS5lbWFpbCA9PT0gZW1haWwpO1xuICAgICAgY29uc3QgZm91bmRVc2VyUGhvbmUgPSBmb3VuZFVzZXJzLmZpbmQoKHUpID0+IHUucGhvbmVOdW1iZXIgPT09IHBob25lTnVtYmVyKTtcblxuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG5cbiAgICAgIGlmIChmb3VuZFVzZXJFbWFpbCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdFTUFJTF9BTFJFQURZX0VYSVNUJywgY29kZTogMTAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGZvdW5kVXNlclBob25lKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1BIT05FX05VTUJFUl9BTFJFQURZX0VYSVNUJywgY29kZTogMTIwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IFVzZXIucXVlcnkoKS53aGVyZSgnaWQnLCBpZCkudXBkYXRlKHtcbiAgICAgICAgZmlyc3RfbmFtZTogcmVxLmJvZHkuZmlyc3RfbmFtZSxcbiAgICAgICAgbGFzdF9uYW1lOiByZXEuYm9keS5sYXN0X25hbWUsXG4gICAgICAgIGVtYWlsOiByZXEuYm9keS5lbWFpbCxcbiAgICAgICAgcGhvbmVfbnVtYmVyOiByZXEuYm9keS5waG9uZV9udW1iZXIsXG4gICAgICAgIGFjdGl2ZTogcmVxLmJvZHkuc3RhdHVzLFxuICAgICAgfSk7XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBTb2Z0IGRlbGV0aW5nIHRoZSBnaXZlbiB1c2VyLlxuICAgKi9cbiAgZGVsZXRlVXNlcjoge1xuICAgIHZhbGlkYXRpb246IFtdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci5xdWVyeSgpLndoZXJlKCdpZCcsIGlkKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdVU0VSX05PVF9GT1VORCcsIGNvZGU6IDEwMCB9XSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBhd2FpdCBVc2VyLnF1ZXJ5KCkud2hlcmUoJ2lkJywgaWQpLmRlbGV0ZSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoKTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB1c2VyIGRldGFpbHMgb2YgdGhlIGdpdmVuIHVzZXIgaWQuXG4gICAqL1xuICBnZXRVc2VyOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgaWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB1c2VyID0gYXdhaXQgVXNlci5xdWVyeSgpLndoZXJlKCdpZCcsIGlkKS5maXJzdCgpO1xuXG4gICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB1c2VyIH0pO1xuICAgIH0sXG4gIH0sXG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHRoZSBsaXN0IG9mIHVzZXJzLlxuICAgKi9cbiAgbGlzdFVzZXJzOiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcXVlcnkoJ3BhZ2Vfc2l6ZScpLm9wdGlvbmFsKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIHF1ZXJ5KCdwYWdlJykub3B0aW9uYWwoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgZmlsdGVyID0ge1xuICAgICAgICBmaXJzdF9uYW1lOiAnJyxcbiAgICAgICAgbGFzdF9uYW1lOiAnJyxcbiAgICAgICAgZW1haWw6ICcnLFxuICAgICAgICBwaG9uZV9udW1iZXI6ICcnLFxuXG4gICAgICAgIHBhZ2Vfc2l6ZTogMTAsXG4gICAgICAgIHBhZ2U6IDEsXG4gICAgICAgIC4uLnJlcS5xdWVyeSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IHVzZXJzID0gYXdhaXQgVXNlci5xdWVyeSgpXG4gICAgICAgIC5wYWdlKGZpbHRlci5wYWdlIC0gMSwgZmlsdGVyLnBhZ2Vfc2l6ZSk7XG5cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IHVzZXJzIH0pO1xuICAgIH0sXG4gIH0sXG59O1xuIiwiaW1wb3J0IHsgZGlmZmVyZW5jZSwgcGljayB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgZXhwcmVzcyBmcm9tICdleHByZXNzJztcbmltcG9ydCB7XG4gIGNoZWNrLFxuICBxdWVyeSxcbiAgcGFyYW0sXG4gIG9uZU9mLFxuICB2YWxpZGF0aW9uUmVzdWx0LFxufSBmcm9tICdleHByZXNzLXZhbGlkYXRvcic7XG5pbXBvcnQgYXN5bmNNaWRkbGV3YXJlIGZyb20gJ0AvaHR0cC9taWRkbGV3YXJlL2FzeW5jTWlkZGxld2FyZSc7XG5pbXBvcnQgand0QXV0aCBmcm9tICdAL2h0dHAvbWlkZGxld2FyZS9qd3RBdXRoJztcbmltcG9ydCBSZXNvdXJjZSBmcm9tICdAL21vZGVscy9SZXNvdXJjZSc7XG5pbXBvcnQgVmlldyBmcm9tICdAL21vZGVscy9WaWV3JztcbmltcG9ydCBWaWV3Um9sZSBmcm9tICdAL21vZGVscy9WaWV3Um9sZSc7XG5pbXBvcnQgVmlld0NvbHVtbiBmcm9tICdAL21vZGVscy9WaWV3Q29sdW1uJztcbmltcG9ydCB7XG4gIHZhbGlkYXRlVmlld0xvZ2ljRXhwcmVzc2lvbixcbn0gZnJvbSAnQC9saWIvVmlld1JvbGVzQnVpbGRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgcmVzb3VyY2U6ICdpdGVtcycsXG5cbiAgLyoqXG4gICAqIFJvdXRlciBjb25zdHJ1Y3Rvci5cbiAgICovXG4gIHJvdXRlcigpIHtcbiAgICBjb25zdCByb3V0ZXIgPSBleHByZXNzLlJvdXRlcigpO1xuXG4gICAgcm91dGVyLnVzZShqd3RBdXRoKTtcblxuICAgIHJvdXRlci5nZXQoJy8nLFxuICAgICAgdGhpcy5saXN0Vmlld3MudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmxpc3RWaWV3cy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIucG9zdCgnLycsXG4gICAgICB0aGlzLmNyZWF0ZVZpZXcudmFsaWRhdGlvbixcbiAgICAgIGFzeW5jTWlkZGxld2FyZSh0aGlzLmNyZWF0ZVZpZXcuaGFuZGxlcikpO1xuXG4gICAgcm91dGVyLnBvc3QoJy86dmlld19pZCcsXG4gICAgICB0aGlzLmVkaXRWaWV3LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5lZGl0Vmlldy5oYW5kbGVyKSk7XG5cbiAgICByb3V0ZXIuZGVsZXRlKCcvOnZpZXdfaWQnLFxuICAgICAgdGhpcy5kZWxldGVWaWV3LnZhbGlkYXRpb24sXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5kZWxldGVWaWV3LmhhbmRsZXIpKTtcblxuICAgIHJvdXRlci5nZXQoJy86dmlld19pZCcsXG4gICAgICBhc3luY01pZGRsZXdhcmUodGhpcy5nZXRWaWV3LmhhbmRsZXIpKTtcblxuICAgIHJldHVybiByb3V0ZXI7XG4gIH0sXG5cbiAgLyoqXG4gICAqIExpc3QgYWxsIHZpZXdzIHRoYXQgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiByZXNvdXJjZS5cbiAgICovXG4gIGxpc3RWaWV3czoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIG9uZU9mKFtcbiAgICAgICAgcXVlcnkoJ3Jlc291cmNlX25hbWUnKS5leGlzdHMoKS50cmltKCkuZXNjYXBlKCksXG4gICAgICBdLCBbXG4gICAgICAgIHF1ZXJ5KCdyZXNvdXJjZV9pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBdKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IGZpbHRlciA9IHsgLi4ucmVxLnF1ZXJ5IH07XG5cbiAgICAgIGNvbnN0IHJlc291cmNlID0gYXdhaXQgUmVzb3VyY2UucXVlcnkoKS5vbkJ1aWxkKChidWlsZGVyKSA9PiB7XG4gICAgICAgIGlmIChmaWx0ZXIucmVzb3VyY2VfaWQpIHtcbiAgICAgICAgICBidWlsZGVyLndoZXJlKCdpZCcsIGZpbHRlci5yZXNvdXJjZV9pZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGZpbHRlci5yZXNvdXJjZV9uYW1lKSB7XG4gICAgICAgICAgYnVpbGRlci53aGVyZSgnbmFtZScsIGZpbHRlci5yZXNvdXJjZV9uYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBidWlsZGVyLmZpcnN0KCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3Qgdmlld3MgPSBhd2FpdCBWaWV3LnF1ZXJ5KCkud2hlcmUoJ3Jlc291cmNlX2lkJywgcmVzb3VyY2UuaWQpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyB2aWV3cyB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB2aWV3IGRldGFpbHMgb2YgdGhlIGdpdmVuIHZpZXcgaWQuXG4gICAqL1xuICBnZXRWaWV3OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgcGFyYW0oJ3ZpZXdfaWQnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgeyB2aWV3X2lkOiB2aWV3SWQgfSA9IHJlcS5wYXJhbXM7XG4gICAgICBjb25zdCB2aWV3ID0gYXdhaXQgVmlldy5xdWVyeSgpXG4gICAgICAgIC53aGVyZSgnaWQnLCB2aWV3SWQpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCdyZXNvdXJjZScpXG4gICAgICAgIC53aXRoR3JhcGhGZXRjaGVkKCdjb2x1bW5zJylcbiAgICAgICAgLndpdGhHcmFwaEZldGNoZWQoJ3JvbGVzLmZpZWxkJylcbiAgICAgICAgLmZpcnN0KCk7XG5cbiAgICAgIGlmICghdmlldykge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20ubm90Rm91bmQobnVsbCwge1xuICAgICAgICAgIGVycm9yczogW3sgdHlwZTogJ1ZJRVdfTk9UX0ZPVU5EJywgY29kZTogMTAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybiByZXMuc3RhdHVzKDIwMCkuc2VuZCh7IHZpZXc6IHZpZXcudG9KU09OKCkgfSk7XG4gICAgfSxcbiAgfSxcblxuICAvKipcbiAgICogRGVsZXRlIHRoZSBnaXZlbiB2aWV3IG9mIHRoZSByZXNvdXJjZS5cbiAgICovXG4gIGRlbGV0ZVZpZXc6IHtcbiAgICB2YWxpZGF0aW9uOiBbXG4gICAgICBwYXJhbSgndmlld19pZCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgXSxcbiAgICBhc3luYyBoYW5kbGVyKHJlcSwgcmVzKSB7XG4gICAgICBjb25zdCB7IHZpZXdfaWQ6IHZpZXdJZCB9ID0gcmVxLnBhcmFtcztcbiAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBWaWV3LnF1ZXJ5KCkuZmluZEJ5SWQodmlld0lkKTtcblxuICAgICAgaWYgKCF2aWV3KSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnVklFV19OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHZpZXcucHJlZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkUmVxdWVzdChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUFJFREVGSU5FRF9WSUVXJywgY29kZTogMjAwIH1dLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgICAgdmlldy4kcmVsYXRlZFF1ZXJ5KCdyb2xlcycpLmRlbGV0ZSgpLFxuICAgICAgICB2aWV3LiRyZWxhdGVkUXVlcnkoJ2NvbHVtbnMnKS5kZWxldGUoKSxcbiAgICAgIF0pO1xuICAgICAgYXdhaXQgVmlldy5xdWVyeSgpLndoZXJlKCdpZCcsIHZpZXcuaWQpLmRlbGV0ZSgpO1xuXG4gICAgICByZXR1cm4gcmVzLnN0YXR1cygyMDApLnNlbmQoeyBpZDogdmlldy5pZCB9KTtcbiAgICB9LFxuICB9LFxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHZpZXcuXG4gICAqL1xuICBjcmVhdGVWaWV3OiB7XG4gICAgdmFsaWRhdGlvbjogW1xuICAgICAgY2hlY2soJ3Jlc291cmNlX25hbWUnKS5leGlzdHMoKS5lc2NhcGUoKS50cmltKCksXG4gICAgICBjaGVjaygnbmFtZScpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdsb2dpY19leHByZXNzaW9uJykuZXhpc3RzKCkudHJpbSgpLmVzY2FwZSgpLFxuICAgICAgY2hlY2soJ3JvbGVzJykuaXNBcnJheSh7IG1pbjogMSB9KSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLmZpZWxkX2tleScpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLmNvbXBhcmF0b3InKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLnZhbHVlJykuZXhpc3RzKCksXG4gICAgICBjaGVjaygncm9sZXMuKi5pbmRleCcpLmV4aXN0cygpLmlzTnVtZXJpYygpLnRvSW50KCksXG4gICAgICBjaGVjaygnY29sdW1ucycpLmV4aXN0cygpLmlzQXJyYXkoeyBtaW46IDEgfSksXG4gICAgICBjaGVjaygnY29sdW1ucy4qLmtleScpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdjb2x1bW5zLiouaW5kZXgnKS5leGlzdHMoKS5pc051bWVyaWMoKS50b0ludCgpLFxuICAgIF0sXG4gICAgYXN5bmMgaGFuZGxlcihyZXEsIHJlcykge1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZvcm0gPSB7IC4uLnJlcS5ib2R5IH07XG4gICAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KCkud2hlcmUoJ25hbWUnLCBmb3JtLnJlc291cmNlX25hbWUpLmZpcnN0KCk7XG5cbiAgICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgICAgcmV0dXJuIHJlcy5ib29tLm5vdEZvdW5kKG51bGwsIHtcbiAgICAgICAgICBlcnJvcnM6IFt7IHR5cGU6ICdSRVNPVVJDRV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgY29uc3QgZXJyb3JSZWFzb25zID0gW107XG4gICAgICBjb25zdCBmaWVsZHNTbHVncyA9IGZvcm0ucm9sZXMubWFwKChyb2xlKSA9PiByb2xlLmZpZWxkX2tleSk7XG5cbiAgICAgIGNvbnN0IHJlc291cmNlRmllbGRzID0gYXdhaXQgcmVzb3VyY2UuJHJlbGF0ZWRRdWVyeSgnZmllbGRzJyk7XG4gICAgICBjb25zdCByZXNvdXJjZUZpZWxkc0tleXMgPSByZXNvdXJjZUZpZWxkcy5tYXAoKGYpID0+IGYua2V5KTtcbiAgICAgIGNvbnN0IHJlc291cmNlRmllbGRzS2V5c01hcCA9IG5ldyBNYXAocmVzb3VyY2VGaWVsZHMubWFwKChmaWVsZCkgPT4gW2ZpZWxkLmtleSwgZmllbGRdKSk7XG4gICAgICBjb25zdCBjb2x1bW5zS2V5cyA9IGZvcm0uY29sdW1ucy5tYXAoKGMpID0+IGMua2V5KTtcblxuICAgICAgLy8gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc3RvcmVkIHJlc291cmNlIGZpZWxkcyBhbmQgc3VibWl0IGZpZWxkcyBrZXlzLlxuICAgICAgY29uc3Qgbm90Rm91bmRGaWVsZHMgPSBkaWZmZXJlbmNlKGZpZWxkc1NsdWdzLCByZXNvdXJjZUZpZWxkc0tleXMpO1xuXG4gICAgICBpZiAobm90Rm91bmRGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICBlcnJvclJlYXNvbnMucHVzaCh7IHR5cGU6ICdSRVNPVVJDRV9GSUVMRFNfTk9UX0VYSVNUJywgY29kZTogMTAwLCBmaWVsZHM6IG5vdEZvdW5kRmllbGRzIH0pO1xuICAgICAgfVxuICAgICAgLy8gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgc3RvcmVkIHJlc291cmNlIGZpZWxkcyBhbmQgdGhlIHN1Ym1pdCBjb2x1bW5zIGtleXMuXG4gICAgICBjb25zdCBub3RGb3VuZENvbHVtbnMgPSBkaWZmZXJlbmNlKGNvbHVtbnNLZXlzLCByZXNvdXJjZUZpZWxkc0tleXMpO1xuXG4gICAgICBpZiAobm90Rm91bmRDb2x1bW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZXJyb3JSZWFzb25zLnB1c2goeyB0eXBlOiAnQ09MVU1OU19OT1RfRVhJU1QnLCBjb2RlOiAyMDAsIGNvbHVtbnM6IG5vdEZvdW5kQ29sdW1ucyB9KTtcbiAgICAgIH1cbiAgICAgIC8vIFZhbGlkYXRlcyB0aGUgdmlldyBjb25kaXRpb25hbCBsb2dpYyBleHByZXNzaW9uLlxuICAgICAgaWYgKCF2YWxpZGF0ZVZpZXdMb2dpY0V4cHJlc3Npb24oZm9ybS5sb2dpY19leHByZXNzaW9uLCBmb3JtLnJvbGVzLm1hcCgocikgPT4gci5pbmRleCkpKSB7XG4gICAgICAgIGVycm9yUmVhc29ucy5wdXNoKHsgdHlwZTogJ1ZJRVcuUk9MRVMuTE9HSUMuRVhQUkVTU0lPTi5JTlZBTElEJywgY29kZTogNDAwIH0pO1xuICAgICAgfVxuICAgICAgaWYgKGVycm9yUmVhc29ucy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5iYWRSZXF1ZXN0KG51bGwsIHsgZXJyb3JzOiBlcnJvclJlYXNvbnMgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNhdmUgdmlldyBkZXRhaWxzLlxuICAgICAgY29uc3QgdmlldyA9IGF3YWl0IFZpZXcucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICBuYW1lOiBmb3JtLm5hbWUsXG4gICAgICAgIHByZWRlZmluZWQ6IGZhbHNlLFxuICAgICAgICByZXNvdXJjZV9pZDogcmVzb3VyY2UuaWQsXG4gICAgICAgIHJvbGVzX2xvZ2ljX2V4cHJlc3Npb246IGZvcm0ubG9naWNfZXhwcmVzc2lvbixcbiAgICAgIH0pO1xuICAgICAgLy8gU2F2ZSB2aWV3IHJvbGVzIGFzeW5jIG9wZXJhdGlvbnMuXG4gICAgICBjb25zdCBzYXZlVmlld1JvbGVzT3BlcnMgPSBbXTtcblxuICAgICAgZm9ybS5yb2xlcy5mb3JFYWNoKChyb2xlKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkTW9kZWwgPSByZXNvdXJjZUZpZWxkc0tleXNNYXAuZ2V0KHJvbGUuZmllbGRfa2V5KTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IHNhdmVWaWV3Um9sZU9wZXIgPSBWaWV3Um9sZS5xdWVyeSgpLmluc2VydCh7XG4gICAgICAgICAgLi4ucGljayhyb2xlLCBbJ2NvbXBhcmF0b3InLCAndmFsdWUnLCAnaW5kZXgnXSksXG4gICAgICAgICAgZmllbGRfaWQ6IGZpZWxkTW9kZWwuaWQsXG4gICAgICAgICAgdmlld19pZDogdmlldy5pZCxcbiAgICAgICAgfSk7XG4gICAgICAgIHNhdmVWaWV3Um9sZXNPcGVycy5wdXNoKHNhdmVWaWV3Um9sZU9wZXIpO1xuICAgICAgfSk7XG5cbiAgICAgIGZvcm0uY29sdW1ucy5mb3JFYWNoKChjb2x1bW4pID0+IHtcbiAgICAgICAgY29uc3QgZmllbGRNb2RlbCA9IHJlc291cmNlRmllbGRzS2V5c01hcC5nZXQoY29sdW1uLmtleSk7XG5cbiAgICAgICAgY29uc3Qgc2F2ZVZpZXdDb2x1bW5PcGVyID0gVmlld0NvbHVtbi5xdWVyeSgpLmluc2VydCh7XG4gICAgICAgICAgZmllbGRfaWQ6IGZpZWxkTW9kZWwuaWQsXG4gICAgICAgICAgdmlld19pZDogdmlldy5pZCxcbiAgICAgICAgICBpbmRleDogY29sdW1uLmluZGV4LFxuICAgICAgICB9KTtcbiAgICAgICAgc2F2ZVZpZXdSb2xlc09wZXJzLnB1c2goc2F2ZVZpZXdDb2x1bW5PcGVyKTtcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoc2F2ZVZpZXdSb2xlc09wZXJzKTtcblxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKHsgaWQ6IHZpZXcuaWQgfSk7XG4gICAgfSxcbiAgfSxcblxuICBlZGl0Vmlldzoge1xuICAgIHZhbGlkYXRpb246IFtcbiAgICAgIHBhcmFtKCd2aWV3X2lkJykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICAgIGNoZWNrKCdsYWJlbCcpLmV4aXN0cygpLmVzY2FwZSgpLnRyaW0oKSxcbiAgICAgIGNoZWNrKCdjb2x1bW5zJykuaXNBcnJheSh7IG1pbjogMyB9KSxcbiAgICAgIGNoZWNrKCdyb2xlcycpLmlzQXJyYXkoKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLmZpZWxkJykuZXhpc3RzKCkuZXNjYXBlKCkudHJpbSgpLFxuICAgICAgY2hlY2soJ3JvbGVzLiouY29tcGFyYXRvcicpLmV4aXN0cygpLFxuICAgICAgY2hlY2soJ3JvbGVzLioudmFsdWUnKS5leGlzdHMoKSxcbiAgICAgIGNoZWNrKCdyb2xlcy4qLmluZGV4JykuZXhpc3RzKCkuaXNOdW1lcmljKCkudG9JbnQoKSxcbiAgICBdLFxuICAgIGFzeW5jIGhhbmRsZXIocmVxLCByZXMpIHtcbiAgICAgIGNvbnN0IHsgdmlld19pZDogdmlld0lkIH0gPSByZXEucGFyYW1zO1xuICAgICAgY29uc3QgdmFsaWRhdGlvbkVycm9ycyA9IHZhbGlkYXRpb25SZXN1bHQocmVxKTtcblxuICAgICAgaWYgKCF2YWxpZGF0aW9uRXJyb3JzLmlzRW1wdHkoKSkge1xuICAgICAgICByZXR1cm4gcmVzLmJvb20uYmFkRGF0YShudWxsLCB7XG4gICAgICAgICAgY29kZTogJ3ZhbGlkYXRpb25fZXJyb3InLCAuLi52YWxpZGF0aW9uRXJyb3JzLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHZpZXcgPSBhd2FpdCBWaWV3LndoZXJlKCdpZCcsIHZpZXdJZCkuZmV0Y2goKTtcblxuICAgICAgaWYgKCF2aWV3KSB7XG4gICAgICAgIHJldHVybiByZXMuYm9vbS5ub3RGb3VuZChudWxsLCB7XG4gICAgICAgICAgZXJyb3JzOiBbeyB0eXBlOiAnUk9MRV9OT1RfRk9VTkQnLCBjb2RlOiAxMDAgfV0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHJlcy5zdGF0dXMoMjAwKS5zZW5kKCk7XG4gICAgfSxcbiAgfSxcbn07XG4iLCIvLyBpbXBvcnQgT0F1dGgyIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9PQXV0aDInO1xuaW1wb3J0IEF1dGhlbnRpY2F0aW9uIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9BdXRoZW50aWNhdGlvbic7XG5pbXBvcnQgVXNlcnMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1VzZXJzJztcbmltcG9ydCBSb2xlcyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvUm9sZXMnO1xuaW1wb3J0IEl0ZW1zIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9JdGVtcyc7XG5pbXBvcnQgSXRlbUNhdGVnb3JpZXMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0l0ZW1DYXRlZ29yaWVzJztcbmltcG9ydCBBY2NvdW50cyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudHMnO1xuaW1wb3J0IEFjY291bnRUeXBlcyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudFR5cGVzJztcbmltcG9ydCBBY2NvdW50T3BlbmluZ0JhbGFuY2UgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0FjY291bnRPcGVuaW5nQmFsYW5jZSc7XG5pbXBvcnQgVmlld3MgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1ZpZXdzJztcbmltcG9ydCBDdXN0b21GaWVsZHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0ZpZWxkcyc7XG5pbXBvcnQgQWNjb3VudGluZyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQWNjb3VudGluZyc7XG5pbXBvcnQgRmluYW5jaWFsU3RhdGVtZW50cyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvRmluYW5jaWFsU3RhdGVtZW50cyc7XG5pbXBvcnQgRXhwZW5zZXMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0V4cGVuc2VzJztcbmltcG9ydCBPcHRpb25zIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9PcHRpb25zJztcbmltcG9ydCBCdWRnZXQgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL0J1ZGdldCc7XG5pbXBvcnQgQnVkZ2V0UmVwb3J0cyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQnVkZ2V0UmVwb3J0cyc7XG5pbXBvcnQgQ3VycmVuY2llcyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQ3VycmVuY2llcyc7XG5pbXBvcnQgQ3VzdG9tZXJzIGZyb20gJ0AvaHR0cC9jb250cm9sbGVycy9DdXN0b21lcnMnO1xuaW1wb3J0IFN1cHBsaWVycyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvU3VwcGxpZXJzJztcbmltcG9ydCBCaWxscyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvQmlsbHMnO1xuaW1wb3J0IEN1cnJlbmN5QWRqdXN0bWVudCBmcm9tICcuL2NvbnRyb2xsZXJzL0N1cnJlbmN5QWRqdXN0bWVudCc7XG5pbXBvcnQgUmVzb3VyY2VzIGZyb20gJy4vY29udHJvbGxlcnMvUmVzb3VyY2VzJztcbi8vIGltcG9ydCBTYWxlc1JlcG9ydHMgZnJvbSAnQC9odHRwL2NvbnRyb2xsZXJzL1NhbGVzUmVwb3J0cyc7XG4vLyBpbXBvcnQgUHVyY2hhc2VzUmVwb3J0cyBmcm9tICdAL2h0dHAvY29udHJvbGxlcnMvUHVyY2hhc2VzUmVwb3J0cyc7XG5cbmV4cG9ydCBkZWZhdWx0IChhcHApID0+IHtcbiAgLy8gYXBwLnVzZSgnL2FwaS9vYXV0aDInLCBPQXV0aDIucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2F1dGgnLCBBdXRoZW50aWNhdGlvbi5yb3V0ZXIoKSk7XG4gIGFwcC51c2UoJy9hcGkvY3VycmVuY2llcycsIEN1cnJlbmNpZXMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL3VzZXJzJywgVXNlcnMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL3JvbGVzJywgUm9sZXMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2FjY291bnRzJywgQWNjb3VudHMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2FjY291bnRfdHlwZXMnLCBBY2NvdW50VHlwZXMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2FjY291bnRpbmcnLCBBY2NvdW50aW5nLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9hY2NvdW50c19vcGVuaW5nX2JhbGFuY2VzJywgQWNjb3VudE9wZW5pbmdCYWxhbmNlLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS92aWV3cycsIFZpZXdzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9maWVsZHMnLCBDdXN0b21GaWVsZHMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2l0ZW1zJywgSXRlbXMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL2l0ZW1fY2F0ZWdvcmllcycsIEl0ZW1DYXRlZ29yaWVzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9leHBlbnNlcycsIEV4cGVuc2VzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9maW5hbmNpYWxfc3RhdGVtZW50cycsIEZpbmFuY2lhbFN0YXRlbWVudHMucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL29wdGlvbnMnLCBPcHRpb25zLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9idWRnZXRfcmVwb3J0cycsIEJ1ZGdldFJlcG9ydHMucm91dGVyKCkpO1xuICAvLyBhcHAudXNlKCcvYXBpL2N1c3RvbWVycycsIEN1c3RvbWVycy5yb3V0ZXIoKSk7XG4gIC8vIGFwcC51c2UoJy9hcGkvc3VwcGxpZXJzJywgU3VwcGxpZXJzLnJvdXRlcigpKTtcbiAgLy8gYXBwLnVzZSgnL2FwaS9iaWxscycsIEJpbGxzLnJvdXRlcigpKTtcbiAgYXBwLnVzZSgnL2FwaS9idWRnZXQnLCBCdWRnZXQucm91dGVyKCkpO1xuICBhcHAudXNlKCcvYXBpL3Jlc291cmNlcycsIFJlc291cmNlcy5yb3V0ZXIoKSk7XG4gIC8vIGFwcC51c2UoJy9hcGkvY3VycmVuY3lfYWRqdXN0bWVudCcsIEN1cnJlbmN5QWRqdXN0bWVudC5yb3V0ZXIoKSk7XG4gIC8vIGFwcC51c2UoJy9hcGkvcmVwb3J0cy9zYWxlcycsIFNhbGVzUmVwb3J0cy5yb3V0ZXIoKSk7XG4gIC8vIGFwcC51c2UoJy9hcGkvcmVwb3J0cy9wdXJjaGFzZXMnLCBQdXJjaGFzZXNSZXBvcnRzLnJvdXRlcigpKTtcbn07XG4iLCJjb25zdCBhc3luY01pZGRsZXdhcmUgPSAoZm4pID0+IChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICBQcm9taXNlLnJlc29sdmUoZm4ocmVxLCByZXMsIG5leHQpKVxuICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgIG5leHQoZXJyb3IpO1xuICAgIH0pO1xufTtcblxuZXhwb3J0IGRlZmF1bHQgYXN5bmNNaWRkbGV3YXJlO1xuIiwiLyogZXNsaW50LWRpc2FibGUgY29uc2lzdGVudC1yZXR1cm4gKi9cbmNvbnN0IGF1dGhvcml6YXRpb24gPSAocmVzb3VyY2VOYW1lKSA9PiAoLi4ucGVybWlzc2lvbnMpID0+IChyZXEsIHJlcywgbmV4dCkgPT4ge1xuICBjb25zdCB7IHVzZXIgfSA9IHJlcTtcbiAgY29uc3Qgb25FcnJvciA9ICgpID0+IHtcbiAgICByZXMuYm9vbS51bmF1dGhvcml6ZWQoKTtcbiAgfTtcbiAgdXNlci5oYXNQZXJtaXNzaW9ucyhyZXNvdXJjZU5hbWUsIHBlcm1pc3Npb25zKVxuICAgIC50aGVuKChhdXRob3JpemVkKSA9PiB7XG4gICAgICBpZiAoIWF1dGhvcml6ZWQpIHtcbiAgICAgICAgcmV0dXJuIG9uRXJyb3IoKTtcbiAgICAgIH1cbiAgICAgIG5leHQoKTtcbiAgICB9KS5jYXRjaChvbkVycm9yKTtcbn07XG5cbmV4cG9ydCBkZWZhdWx0IGF1dGhvcml6YXRpb247XG4iLCIvKiBlc2xpbnQtZGlzYWJsZSBjb25zaXN0ZW50LXJldHVybiAqL1xuaW1wb3J0IGp3dCBmcm9tICdqc29ud2VidG9rZW4nO1xuaW1wb3J0IFVzZXIgZnJvbSAnQC9tb2RlbHMvVXNlcic7XG4vLyBpbXBvcnQgQXV0aCBmcm9tICdAL21vZGVscy9BdXRoJztcblxuY29uc3QgYXV0aE1pZGRsZXdhcmUgPSAocmVxLCByZXMsIG5leHQpID0+IHtcbiAgY29uc3QgeyBKV1RfU0VDUkVUX0tFWSB9ID0gcHJvY2Vzcy5lbnY7XG4gIGNvbnN0IHRva2VuID0gcmVxLmhlYWRlcnNbJ3gtYWNjZXNzLXRva2VuJ10gfHwgcmVxLnF1ZXJ5LnRva2VuO1xuXG4gIGNvbnN0IG9uRXJyb3IgPSAoKSA9PiB7XG4gICAgLy8gQXV0aC5sb2dnZWRPdXQoKTtcbiAgICByZXMuc3RhdHVzKDQwMSkuc2VuZCh7XG4gICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgIG1lc3NhZ2U6ICd1bmF1dGhvcml6ZWQnLFxuICAgIH0pO1xuICB9O1xuXG4gIGlmICghdG9rZW4pIHtcbiAgICByZXR1cm4gb25FcnJvcigpO1xuICB9XG5cbiAgY29uc3QgdmVyaWZ5ID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGp3dC52ZXJpZnkodG9rZW4sIEpXVF9TRUNSRVRfS0VZLCBhc3luYyAoZXJyb3IsIGRlY29kZWQpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVuZGVyc2NvcmUtZGFuZ2xlXG4gICAgICAgIHJlcS51c2VyID0gYXdhaXQgVXNlci5xdWVyeSgpLmZpbmRCeUlkKGRlY29kZWQuX2lkKTtcbiAgICAgICAgLy8gQXV0aC5zZXRBdXRoZW50aWNhdGVkVXNlcihyZXEudXNlcik7XG5cbiAgICAgICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgICAgIHJldHVybiBvbkVycm9yKCk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzb2x2ZShkZWNvZGVkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgdmVyaWZ5LnRoZW4oKCkgPT4geyBuZXh0KCk7IH0pLmNhdGNoKG9uRXJyb3IpO1xufTtcbmV4cG9ydCBkZWZhdWx0IGF1dGhNaWRkbGV3YXJlO1xuIiwiXG5jb25zdCBPcGVyYXRpb25UeXBlID0ge1xuICBMT0dJQzogJ0xPR0lDJyxcbiAgU1RSSU5HOiAnU1RSSU5HJyxcbiAgQ09NUEFSSVNPTjogJ0NPTVBBUklTT04nLFxuICBNQVRIOiAnTUFUSCcsXG59O1xuXG5leHBvcnQgY2xhc3MgTGV4ZXIge1xuICAvLyBvcGVyYXRpb24gdGFibGVcbiAgc3RhdGljIGdldCBvcHRhYmxlKCkge1xuICAgIHJldHVybiB7XG4gICAgICAnPSc6IE9wZXJhdGlvblR5cGUuTE9HSUMsXG4gICAgICAnJic6IE9wZXJhdGlvblR5cGUuTE9HSUMsXG4gICAgICAnfCc6IE9wZXJhdGlvblR5cGUuTE9HSUMsXG4gICAgICAnPyc6IE9wZXJhdGlvblR5cGUuTE9HSUMsXG4gICAgICAnOic6IE9wZXJhdGlvblR5cGUuTE9HSUMsXG5cbiAgICAgICdcXCcnOiBPcGVyYXRpb25UeXBlLlNUUklORyxcbiAgICAgICdcIic6IE9wZXJhdGlvblR5cGUuU1RSSU5HLFxuXG4gICAgICAnISc6IE9wZXJhdGlvblR5cGUuQ09NUEFSSVNPTixcbiAgICAgICc+JzogT3BlcmF0aW9uVHlwZS5DT01QQVJJU09OLFxuICAgICAgJzwnOiBPcGVyYXRpb25UeXBlLkNPTVBBUklTT04sXG5cbiAgICAgICcoJzogT3BlcmF0aW9uVHlwZS5NQVRILFxuICAgICAgJyknOiBPcGVyYXRpb25UeXBlLk1BVEgsXG4gICAgICAnKyc6IE9wZXJhdGlvblR5cGUuTUFUSCxcbiAgICAgICctJzogT3BlcmF0aW9uVHlwZS5NQVRILFxuICAgICAgJyonOiBPcGVyYXRpb25UeXBlLk1BVEgsXG4gICAgICAnLyc6IE9wZXJhdGlvblR5cGUuTUFUSCxcbiAgICAgICclJzogT3BlcmF0aW9uVHlwZS5NQVRILFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29uc3RydWN0b3JcbiAgICogQHBhcmFtIHsqfSBleHByZXNzaW9uIC1cbiAgICovXG4gIGNvbnN0cnVjdG9yKGV4cHJlc3Npb24pIHtcbiAgICB0aGlzLmN1cnJlbnRJbmRleCA9IDA7XG4gICAgdGhpcy5pbnB1dCA9IGV4cHJlc3Npb247XG4gICAgdGhpcy50b2tlbkxpc3QgPSBbXTtcbiAgfVxuXG4gIGdldFRva2VucygpIHtcbiAgICBsZXQgdG9rO1xuICAgIGRvIHtcbiAgICAgIC8vIHJlYWQgY3VycmVudCB0b2tlbiwgc28gc3RlcCBzaG91bGQgYmUgLTFcbiAgICAgIHRvayA9IHRoaXMucGlja05leHQoLTEpO1xuICAgICAgY29uc3QgcG9zID0gdGhpcy5jdXJyZW50SW5kZXg7XG4gICAgICBzd2l0Y2ggKExleGVyLm9wdGFibGVbdG9rXSkge1xuICAgICAgICBjYXNlIE9wZXJhdGlvblR5cGUuTE9HSUM6XG4gICAgICAgICAgLy8gPT0gJiYgfHwgPT09XG4gICAgICAgICAgdGhpcy5yZWFkTG9naWNPcHQodG9rKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9wZXJhdGlvblR5cGUuU1RSSU5HOlxuICAgICAgICAgIHRoaXMucmVhZFN0cmluZyh0b2spO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgT3BlcmF0aW9uVHlwZS5DT01QQVJJU09OOlxuICAgICAgICAgIHRoaXMucmVhZENvbXBhcmUodG9rKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9wZXJhdGlvblR5cGUuTUFUSDpcbiAgICAgICAgICB0aGlzLnJlY2VpdmVUb2tlbigpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhpcy5yZWFkVmFsdWUodG9rKTtcbiAgICAgIH1cblxuICAgICAgLy8gaWYgdGhlIHBvcyBub3QgY2hhbmdlZCwgdGhpcyBsb29wIHdpbGwgZ28gaW50byBhIGluZmluaXRlIGxvb3AsIGV2ZXJ5IHN0ZXAgb2Ygd2hpbGUgbG9vcCxcbiAgICAgIC8vIHdlIG11c3QgbW92ZSB0aGUgcG9zIGZvcndhcmRcbiAgICAgIC8vIHNvIGhlcmUgd2Ugc2hvdWxkIHRocm93IGVycm9yLCBmb3IgZXhhbXBsZSBgMSAmIDJgXG4gICAgICBpZiAocG9zID09PSB0aGlzLmN1cnJlbnRJbmRleCAmJiB0b2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoYHVua29udyB0b2tlbiAke3Rva30gZnJvbSBpbnB1dCBzdHJpbmcgJHt0aGlzLmlucHV0fWApO1xuICAgICAgICBlcnIubmFtZSA9ICdVbmtub3dUb2tlbic7XG4gICAgICAgIHRocm93IGVycjtcbiAgICAgIH1cbiAgICB9IHdoaWxlICh0b2sgIT09IHVuZGVmaW5lZClcblxuICAgIHJldHVybiB0aGlzLnRva2VuTGlzdDtcbiAgfVxuXG4gIC8qKlxuICAgKiByZWFkIG5leHQgdG9rZW4sIHRoZSBpbmRleCBwYXJhbSBjYW4gc2V0IG5leHQgc3RlcCwgZGVmYXVsdCBnbyBmb3dhcmQgMSBzdGVwXG4gICAqXG4gICAqIEBwYXJhbSBpbmRleCBuZXh0IHBvc3Rpb25cbiAgICovXG4gIHBpY2tOZXh0KGluZGV4ID0gMCkge1xuICAgIHJldHVybiB0aGlzLmlucHV0W2luZGV4ICsgdGhpcy5jdXJyZW50SW5kZXggKyAxXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9yZSB0b2tlbiBpbnRvIHJlc3VsdCB0b2tlbkxpc3QsIGFuZCBtb3ZlIHRoZSBwb3MgaW5kZXhcbiAgICpcbiAgICogQHBhcmFtIGluZGV4XG4gICAqL1xuICByZWNlaXZlVG9rZW4oaW5kZXggPSAxKSB7XG4gICAgY29uc3QgdG9rID0gdGhpcy5pbnB1dC5zbGljZSh0aGlzLmN1cnJlbnRJbmRleCwgdGhpcy5jdXJyZW50SW5kZXggKyBpbmRleCkudHJpbSgpO1xuICAgIC8vIHNraXAgZW1wdHkgc3RyaW5nXG4gICAgaWYgKHRvaykge1xuICAgICAgdGhpcy50b2tlbkxpc3QucHVzaCh0b2spO1xuICAgIH1cblxuICAgIHRoaXMuY3VycmVudEluZGV4ICs9IGluZGV4O1xuICB9XG5cbiAgLy8gJyBvciBcIlxuICByZWFkU3RyaW5nKHRvaykge1xuICAgIGxldCBuZXh0O1xuICAgIGxldCBpbmRleCA9IDA7XG4gICAgZG8ge1xuICAgICAgbmV4dCA9IHRoaXMucGlja05leHQoaW5kZXgpO1xuICAgICAgaW5kZXggKz0gMTtcbiAgICB9IHdoaWxlIChuZXh0ICE9PSB0b2sgJiYgbmV4dCAhPT0gdW5kZWZpbmVkKTtcbiAgICB0aGlzLnJlY2VpdmVUb2tlbihpbmRleCArIDEpO1xuICB9XG5cbiAgLy8gPiBvciA8IG9yID49IG9yIDw9IG9yICE9PVxuICAvLyB0b2sgaW4gKD4sIDwsICEpXG4gIHJlYWRDb21wYXJlKHRvaykge1xuICAgIGlmICh0aGlzLnBpY2tOZXh0KCkgIT09ICc9Jykge1xuICAgICAgdGhpcy5yZWNlaXZlVG9rZW4oMSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vICE9PVxuICAgIGlmICh0b2sgPT09ICchJyAmJiB0aGlzLnBpY2tOZXh0KDEpID09PSAnPScpIHtcbiAgICAgIHRoaXMucmVjZWl2ZVRva2VuKDMpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlY2VpdmVUb2tlbigyKTtcbiAgfVxuXG4gIC8vID09PSBvciA9PVxuICAvLyAmJiB8fFxuICByZWFkTG9naWNPcHQodG9rKSB7XG4gICAgaWYgKHRoaXMucGlja05leHQoKSA9PT0gdG9rKSB7XG4gICAgICAvLyA9PT1cbiAgICAgIGlmICh0b2sgPT09ICc9JyAmJiB0aGlzLnBpY2tOZXh0KDEpID09PSB0b2spIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVjZWl2ZVRva2VuKDMpO1xuICAgICAgfVxuICAgICAgLy8gPT0gJiYgfHxcbiAgICAgIHJldHVybiB0aGlzLnJlY2VpdmVUb2tlbigyKTtcbiAgICB9XG4gICAgLy8gaGFuZGxlIGFzICYmXG4gICAgLy8gYSA/IGIgOiBjIGlzIGVxdWFsIHRvIGEgJiYgYiB8fCBjXG4gICAgaWYgKHRvayA9PT0gJz8nIHx8IHRvayA9PT0gJzonKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWNlaXZlVG9rZW4oMSk7XG4gICAgfVxuICB9XG5cbiAgcmVhZFZhbHVlKHRvaykge1xuICAgIGlmICghdG9rKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGluZGV4ID0gMDtcbiAgICB3aGlsZSAoIUxleGVyLm9wdGFibGVbdG9rXSAmJiB0b2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdG9rID0gdGhpcy5waWNrTmV4dChpbmRleCk7XG4gICAgICBpbmRleCArPSAxO1xuICAgIH1cbiAgICB0aGlzLnJlY2VpdmVUb2tlbihpbmRleCk7XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdG9rZW4oZXhwcmVzc2lvbikge1xuICBjb25zdCBsZXhlciA9IG5ldyBMZXhlcihleHByZXNzaW9uKTtcbiAgcmV0dXJuIGxleGVyLmdldFRva2VucygpO1xufVxuIiwiZXhwb3J0IGNvbnN0IE9QRVJBVElPTiA9IHtcbiAgJyEnOiA1LFxuICAnKic6IDQsXG4gICcvJzogNCxcbiAgJyUnOiA0LFxuICAnKyc6IDMsXG4gICctJzogMyxcbiAgJz4nOiAyLFxuICAnPCc6IDIsXG4gICc+PSc6IDIsXG4gICc8PSc6IDIsXG4gICc9PT0nOiAyLFxuICAnIT09JzogMixcbiAgJz09JzogMixcbiAgJyE9JzogMixcbiAgJyYmJzogMSxcbiAgJ3x8JzogMSxcbiAgJz8nOiAxLFxuICAnOic6IDEsXG59O1xuXG4vLyBleHBvcnQgaW50ZXJmYWNlIE5vZGUge1xuLy8gICBsZWZ0OiBOb2RlIHwgc3RyaW5nIHwgbnVsbDtcbi8vICAgcmlnaHQ6IE5vZGUgfCBzdHJpbmcgfCBudWxsO1xuLy8gICBvcGVyYXRpb246IHN0cmluZztcbi8vICAgZ3JvdXBlZD86IGJvb2xlYW47XG4vLyB9O1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBQYXJzZXIge1xuXG4gIGNvbnN0cnVjdG9yKHRva2VuKSB7XG4gICAgdGhpcy5pbmRleCA9IC0xO1xuICAgIHRoaXMuYmxvY2tMZXZlbCA9IDA7XG4gICAgdGhpcy50b2tlbiA9IHRva2VuO1xuICB9XG5cbiAgLyoqXG4gICAqIFxuICAgKiBAcmV0dXJuIHtOb2RlIHwgc3RyaW5nfSA9LSBcbiAgICovXG4gIHBhcnNlKCkge1xuICAgIGxldCB0b2s7XG4gICAgbGV0IHJvb3QgPSB7XG4gICAgICBsZWZ0OiBudWxsLFxuICAgICAgcmlnaHQ6IG51bGwsXG4gICAgICBvcGVyYXRpb246IG51bGwsXG4gICAgfTtcblxuICAgIGRvIHtcbiAgICAgIHRvayA9IHRoaXMucGFyc2VTdGF0ZW1lbnQoKTtcblxuICAgICAgaWYgKHRvayA9PT0gbnVsbCB8fCB0b2sgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgaWYgKHJvb3QubGVmdCA9PT0gbnVsbCkge1xuICAgICAgICByb290LmxlZnQgPSB0b2s7XG4gICAgICAgIHJvb3Qub3BlcmF0aW9uID0gdGhpcy5uZXh0VG9rZW4oKTtcblxuICAgICAgICBpZiAoIXJvb3Qub3BlcmF0aW9uKSB7XG4gICAgICAgICAgcmV0dXJuIHRvaztcbiAgICAgICAgfVxuXG4gICAgICAgIHJvb3QucmlnaHQgPSB0aGlzLnBhcnNlU3RhdGVtZW50KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAodHlwZW9mIHRvayAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ29wZXJhdGlvbiBtdXN0IGJlIHN0cmluZywgYnV0IGdldCAnICsgSlNPTi5zdHJpbmdpZnkodG9rKSk7XG4gICAgICAgIH1cbiAgICAgICAgcm9vdCA9IHRoaXMuYWRkTm9kZSh0b2ssIHRoaXMucGFyc2VTdGF0ZW1lbnQoKSwgcm9vdCk7XG4gICAgICB9XG4gICAgfSB3aGlsZSAodG9rKTtcblxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgbmV4dFRva2VuKCkge1xuICAgIHRoaXMuaW5kZXggKz0gMTtcbiAgICByZXR1cm4gdGhpcy50b2tlblt0aGlzLmluZGV4XTtcbiAgfVxuXG4gIHByZXZUb2tlbigpIHtcbiAgICByZXR1cm4gdGhpcy50b2tlblt0aGlzLmluZGV4IC0gMV07XG4gIH1cblxuICAvKipcbiAgICogXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gXG4gICAqIEBwYXJhbSB7Tm9kZXxTdHJpbmd8bnVsbH0gcmlnaHQgXG4gICAqIEBwYXJhbSB7Tm9kZX0gcm9vdCBcbiAgICovXG4gIGFkZE5vZGUob3BlcmF0aW9uLCByaWdodCwgcm9vdCkge1xuICAgIGxldCBwcmUgPSByb290O1xuICAgIFxuICAgIGlmICh0aGlzLmNvbXBhcmUocHJlLm9wZXJhdGlvbiwgb3BlcmF0aW9uKSA8IDAgJiYgIXByZS5ncm91cGVkKSB7XG4gICAgICBcbiAgICAgIHdoaWxlIChwcmUucmlnaHQgIT09IG51bGwgJiZcbiAgICAgICAgdHlwZW9mIHByZS5yaWdodCAhPT0gJ3N0cmluZycgJiZcbiAgICAgICAgdGhpcy5jb21wYXJlKHByZS5yaWdodC5vcGVyYXRpb24sIG9wZXJhdGlvbikgPCAwICYmICFwcmUucmlnaHQuZ3JvdXBlZCkge1xuICAgICAgICBwcmUgPSBwcmUucmlnaHQ7XG4gICAgICB9XG5cbiAgICAgIHByZS5yaWdodCA9IHtcbiAgICAgICAgb3BlcmF0aW9uLFxuICAgICAgICBsZWZ0OiBwcmUucmlnaHQsXG4gICAgICAgIHJpZ2h0LFxuICAgICAgfTtcbiAgICAgIHJldHVybiByb290O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgbGVmdDogcHJlLFxuICAgICAgcmlnaHQsXG4gICAgICBvcGVyYXRpb24sXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFxuICAgKiBAcGFyYW0ge1N0cmluZ30gYSBcbiAgICogQHBhcmFtIHtTdHJpbmd9IGIgXG4gICAqL1xuICBjb21wYXJlKGEsIGIpIHtcbiAgICBpZiAoIU9QRVJBVElPTi5oYXNPd25Qcm9wZXJ0eShhKSB8fCAhT1BFUkFUSU9OLmhhc093blByb3BlcnR5KGIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vdyBvcGVyYXRpb24gJHthfSBvciAke2J9YCk7XG4gICAgfVxuICAgIHJldHVybiBPUEVSQVRJT05bYV0gLSBPUEVSQVRJT05bYl07XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybiBzdHJpbmcgfCBOb2RlIHwgbnVsbFxuICAgKi9cbiAgcGFyc2VTdGF0ZW1lbnQoKSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLm5leHRUb2tlbigpO1xuICAgIGlmICh0b2tlbiA9PT0gJygnKSB7XG4gICAgICB0aGlzLmJsb2NrTGV2ZWwgKz0gMTtcbiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLnBhcnNlKCk7XG4gICAgICB0aGlzLmJsb2NrTGV2ZWwgLT0gMTtcblxuICAgICAgaWYgKHR5cGVvZiBub2RlICE9PSAnc3RyaW5nJykge1xuICAgICAgICBub2RlLmdyb3VwZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuXG4gICAgaWYgKHRva2VuID09PSAnKScpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmICh0b2tlbiA9PT0gJyEnKSB7XG4gICAgICByZXR1cm4geyBsZWZ0OiBudWxsLCBvcGVyYXRpb246IHRva2VuLCByaWdodDogdGhpcy5wYXJzZVN0YXRlbWVudCgpIH1cbiAgICB9XG5cbiAgICAvLyAzID4gLTEyIG9yIC0xMiArIDEwXG4gICAgaWYgKHRva2VuID09PSAnLScgJiYgKE9QRVJBVElPTlt0aGlzLnByZXZUb2tlbigpXSA+IDAgfHwgdGhpcy5wcmV2VG9rZW4oKSA9PT0gdW5kZWZpbmVkKSkge1xuICAgICAgcmV0dXJuIHsgbGVmdDogJzAnLCBvcGVyYXRpb246IHRva2VuLCByaWdodDogdGhpcy5wYXJzZVN0YXRlbWVudCgpLCBncm91cGVkOiB0cnVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9XG59XG4iLCJpbXBvcnQgeyBPUEVSQVRJT04gfSBmcm9tICcuL1BhcnNlcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFF1ZXJ5UGFyc2VyIHtcblxuICBjb25zdHJ1Y3Rvcih0cmVlLCBxdWVyaWVzKSB7XG4gICAgdGhpcy50cmVlID0gdHJlZTtcbiAgICB0aGlzLnF1ZXJpZXMgPSBxdWVyaWVzO1xuICAgIHRoaXMucXVlcnkgPSBudWxsO1xuICB9XG5cbiAgc2V0UXVlcnkocXVlcnkpIHtcbiAgICB0aGlzLnF1ZXJ5ID0gcXVlcnkuY2xvbmUoKTtcbiAgfVxuXG4gIHBhcnNlKCkge1xuICAgIHJldHVybiB0aGlzLnBhcnNlTm9kZSh0aGlzLnRyZWUpO1xuICB9XG5cbiAgcGFyc2VOb2RlKG5vZGUpIHtcbiAgICBpZiAodHlwZW9mIG5vZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICBjb25zdCBub2RlUXVlcnkgPSB0aGlzLmdldFF1ZXJ5KG5vZGUpO1xuICAgICAgcmV0dXJuIChxdWVyeSkgPT4geyBub2RlUXVlcnkocXVlcnkpOyB9O1xuICAgIH1cbiAgICBpZiAoT1BFUkFUSU9OW25vZGUub3BlcmF0aW9uXSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVua25vdyBleHByZXNzaW9uICR7bm9kZS5vcGVyYXRpb259YCk7XG4gICAgfVxuICAgIGNvbnN0IGxlZnRRdWVyeSA9IHRoaXMuZ2V0UXVlcnkobm9kZS5sZWZ0KTtcbiAgICBjb25zdCByaWdodFF1ZXJ5ID0gdGhpcy5nZXRRdWVyeShub2RlLnJpZ2h0KTtcblxuICAgIHN3aXRjaCAobm9kZS5vcGVyYXRpb24pIHtcbiAgICAgIGNhc2UgJyYmJzpcbiAgICAgIGNhc2UgJ0FORCc6XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gKG5vZGVRdWVyeSkgPT4gbm9kZVF1ZXJ5LndoZXJlKChxdWVyeSkgPT4ge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKChxKSA9PiB7IGxlZnRRdWVyeShxKTsgfSk7XG4gICAgICAgICAgcXVlcnkuYW5kV2hlcmUoKHEpID0+IHsgcmlnaHRRdWVyeShxKTsgfSk7XG4gICAgICAgIH0pO1xuICAgICAgY2FzZSAnfHwnOlxuICAgICAgY2FzZSAnT1InOlxuICAgICAgICByZXR1cm4gKG5vZGVRdWVyeSkgPT4gbm9kZVF1ZXJ5LndoZXJlKChxdWVyeSkgPT4ge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKChxKSA9PiB7IGxlZnRRdWVyeShxKTsgfSk7XG4gICAgICAgICAgcXVlcnkub3JXaGVyZSgocSkgPT4geyByaWdodFF1ZXJ5KHEpOyB9KTtcbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0UXVlcnkobm9kZSkge1xuICAgIGlmICh0eXBlb2Ygbm9kZSAhPT0gJ3N0cmluZycgJiYgbm9kZSAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VOb2RlKG5vZGUpO1xuICAgIH1cbiAgICBjb25zdCB2YWx1ZSA9IHBhcnNlRmxvYXQobm9kZSk7XG5cbiAgICBpZiAoIWlzTmFOKHZhbHVlKSkge1xuICAgICAgaWYgKHR5cGVvZiB0aGlzLnF1ZXJpZXNbbm9kZV0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgdW5rbm93IHF1ZXJ5IHVuZGVyIGluZGV4ICR7bm9kZX1gKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnF1ZXJpZXNbbm9kZV07XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59IiwiXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBNZXRhYmxlQ29sbGVjdGlvbiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubWV0YWRhdGEgPSBbXTtcbiAgICB0aGlzLktFWV9DT0xVTU4gPSAna2V5JztcbiAgICB0aGlzLlZBTFVFX0NPTFVNTiA9ICd2YWx1ZSc7XG4gICAgdGhpcy5UWVBFX0NPTFVNTiA9ICd0eXBlJztcbiAgICB0aGlzLm1vZGVsID0gbnVsbDtcbiAgICB0aGlzLmV4dHJhQ29sdW1ucyA9IFtdO1xuXG4gICAgdGhpcy5leHRyYVF1ZXJ5ID0gKHF1ZXJ5LCBtZXRhKSA9PiB7XG4gICAgICBxdWVyeS53aGVyZSgna2V5JywgbWV0YVt0aGlzLktFWV9DT0xVTU5dKTtcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldCBtb2RlbCBvZiB0aGlzIG1ldGFkYXRhIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBtb2RlbCAtXG4gICAqL1xuICBzZXRNb2RlbChtb2RlbCkge1xuICAgIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaW5kIHRoZSBnaXZlbiBtZXRhZGF0YSBrZXkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgLVxuICAgKiBAcmV0dXJuIHtvYmplY3R9IC0gTWV0YWRhdGEgb2JqZWN0LlxuICAgKi9cbiAgZmluZE1ldGEoa2V5KSB7XG4gICAgcmV0dXJuIHRoaXMuYWxsTWV0YWRhdGEoKS5maW5kKChtZXRhKSA9PiBtZXRhLmtleSA9PT0ga2V5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBhbGwgbWV0YWRhdGEuXG4gICAqL1xuICBhbGxNZXRhZGF0YSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRhZGF0YS5maWx0ZXIoKG1ldGEpID0+ICFtZXRhLm1hcmtBc0RlbGV0ZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIG1ldGFkYXRhIG9mIHRoZSBnaXZlbiBrZXkuXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBrZXkgLVxuICAgKiBAcGFyYW0ge01peGllZH0gZGVmYXVsdFZhbHVlIC1cbiAgICovXG4gIGdldE1ldGEoa2V5LCBkZWZhdWx0VmFsdWUpIHtcbiAgICBjb25zdCBtZXRhZGF0YSA9IHRoaXMuZmluZE1ldGEoa2V5KTtcbiAgICByZXR1cm4gbWV0YWRhdGEgPyBtZXRhZGF0YS52YWx1ZSA6IGRlZmF1bHRWYWx1ZSB8fCBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXJrZXMgdGhlIG1ldGFkYXRhIHRvIHNob3VsZCBiZSBkZWxldGVkLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IC1cbiAgICovXG4gIHJlbW92ZU1ldGEoa2V5KSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmZpbmRNZXRhKGtleSk7XG5cbiAgICBpZiAobWV0YWRhdGEpIHtcbiAgICAgIG1ldGFkYXRhLm1hcmtBc0RlbGV0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYWxsIG1ldGEgZGF0YSBvZiB0aGUgZ2l2ZW4gZ3JvdXAuXG4gICAqIEBwYXJhbSB7Kn0gZ3JvdXBcbiAgICovXG4gIHJlbW92ZUFsbE1ldGEoZ3JvdXAgPSAnZGVmYXVsdCcpIHtcbiAgICB0aGlzLm1ldGFkYXRhID0gdGhpcy5tZXRhZGF0YS5tYXAoKG1ldGEpID0+ICh7XG4gICAgICAuLi5tZXRhLFxuICAgICAgbWFya0FzRGVsZXRlZDogdHJ1ZSxcbiAgICB9KSk7XG4gIH1cblxuICBzZXRFeHRyYVF1ZXJ5KGNhbGxiYWNrKSB7XG4gICAgdGhpcy5leHRyYVF1ZXJ5ID0gY2FsbGJhY2s7XG4gIH1cblxuICAvKipcbiAgICogU2V0IHRoZSBtZXRhIGRhdGEgdG8gdGhlIHN0YWNrLlxuICAgKiBAcGFyYW0ge1N0cmluZ30ga2V5IC1cbiAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIC1cbiAgICovXG4gIHNldE1ldGEoa2V5LCB2YWx1ZSwgcGF5bG9hZCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGtleSkpIHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0ga2V5O1xuXG4gICAgICBtZXRhZGF0YS5mb3JFYWNoKChtZXRhKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0TWV0YShtZXRhLmtleSwgbWV0YS52YWx1ZSk7XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbWV0YWRhdGEgPSB0aGlzLmZpbmRNZXRhKGtleSk7XG5cbiAgICBpZiAobWV0YWRhdGEpIHtcbiAgICAgIG1ldGFkYXRhLnZhbHVlID0gdmFsdWU7XG4gICAgICBtZXRhZGF0YS5tYXJrQXNVcGRhdGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tZXRhZGF0YS5wdXNoKHtcbiAgICAgICAgdmFsdWUsIGtleSwgLi4ucGF5bG9hZCwgbWFya0FzSW5zZXJ0ZWQ6IHRydWUsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2F2ZWQgdGhlIG1vZGlmaWVkL2RlbGV0ZWQgYW5kIGluc2VydGVkIG1ldGFkYXRhLlxuICAgKi9cbiAgYXN5bmMgc2F2ZU1ldGEoKSB7XG4gICAgY29uc3QgaW5zZXJ0ZWQgPSB0aGlzLm1ldGFkYXRhLmZpbHRlcigobSkgPT4gKG0ubWFya0FzSW5zZXJ0ZWQgPT09IHRydWUpKTtcbiAgICBjb25zdCB1cGRhdGVkID0gdGhpcy5tZXRhZGF0YS5maWx0ZXIoKG0pID0+IChtLm1hcmtBc1VwZGF0ZWQgPT09IHRydWUpKTtcbiAgICBjb25zdCBkZWxldGVkID0gdGhpcy5tZXRhZGF0YS5maWx0ZXIoKG0pID0+IChtLm1hcmtBc0RlbGV0ZWQgPT09IHRydWUpKTtcbiAgICBjb25zdCBvcGVycyA9IFtdO1xuXG4gICAgaWYgKGRlbGV0ZWQubGVuZ3RoID4gMCkge1xuICAgICAgZGVsZXRlZC5mb3JFYWNoKChtZXRhKSA9PiB7XG4gICAgICAgIGNvbnN0IGRlbGV0ZU9wZXIgPSB0aGlzLm1vZGVsLnF1ZXJ5KCkuYmVmb3JlUnVuKChxdWVyeSwgcmVzdWx0KSA9PiB7XG4gICAgICAgICAgdGhpcy5leHRyYVF1ZXJ5KHF1ZXJ5LCBtZXRhKTtcbiAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICB9KS5kZWxldGUoKTtcbiAgICAgICAgb3BlcnMucHVzaChkZWxldGVPcGVyKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpbnNlcnRlZC5mb3JFYWNoKChtZXRhKSA9PiB7XG4gICAgICBjb25zdCBpbnNlcnRPcGVyID0gdGhpcy5tb2RlbC5xdWVyeSgpLmluc2VydCh7XG4gICAgICAgIFt0aGlzLktFWV9DT0xVTU5dOiBtZXRhLmtleSxcbiAgICAgICAgW3RoaXMuVkFMVUVfQ09MVU1OXTogbWV0YS52YWx1ZSxcbiAgICAgICAgLi4udGhpcy5leHRyYUNvbHVtbnMucmVkdWNlKChvYmosIGNvbHVtbikgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgbWV0YVtjb2x1bW5dICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgb2JqW2NvbHVtbl0gPSBtZXRhW2NvbHVtbl07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KSxcbiAgICAgIH0pO1xuICAgICAgb3BlcnMucHVzaChpbnNlcnRPcGVyKTtcbiAgICB9KTtcbiAgICB1cGRhdGVkLmZvckVhY2goKG1ldGEpID0+IHtcbiAgICAgIGNvbnN0IHVwZGF0ZU9wZXIgPSB0aGlzLm1vZGVsLnF1ZXJ5KCkub25CdWlsZCgocXVlcnkpID0+IHtcbiAgICAgICAgdGhpcy5leHRyYVF1ZXJ5KHF1ZXJ5LCBtZXRhKTtcbiAgICAgIH0pLnBhdGNoKHtcbiAgICAgICAgW3RoaXMuVkFMVUVfQ09MVU1OXTogbWV0YS52YWx1ZSxcbiAgICAgIH0pO1xuICAgICAgb3BlcnMucHVzaCh1cGRhdGVPcGVyKTtcbiAgICB9KTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChvcGVycyk7XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgdGhlIG1ldGFkYXRhIGZyb20gdGhlIHN0b3JhZ2UuXG4gICAqIEBwYXJhbSB7U3RyaW5nfEFycmF5fSBrZXkgLVxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlIC1cbiAgICovXG4gIGFzeW5jIGxvYWQoKSB7XG4gICAgY29uc3QgbWV0YWRhdGEgPSBhd2FpdCB0aGlzLnF1ZXJ5KCk7XG5cbiAgICBjb25zdCBtZXRhZGF0YUFycmF5ID0gdGhpcy5tYXBNZXRhZGF0YUNvbGxlY3Rpb24obWV0YWRhdGEpO1xuICAgIG1ldGFkYXRhQXJyYXkuZm9yRWFjaCgobWV0YSkgPT4ge1xuICAgICAgdGhpcy5tZXRhZGF0YS5wdXNoKG1ldGEpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcm1hdCB0aGUgbWV0YWRhdGEgYmVmb3JlIHNhdmluZyB0byB0aGUgZGF0YWJhc2UuXG4gICAqIEBwYXJhbSB7U3RyaW5nfE51bWJlcnxCb29sZWFufSB2YWx1ZSAtXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVR5cGUgLVxuICAgKiBAcmV0dXJuIHtTdHJpbmd8TnVtYmVyfEJvb2xlYW59IC1cbiAgICovXG4gIHN0YXRpYyBmb3JtYXRNZXRhVmFsdWUodmFsdWUsIHZhbHVlVHlwZSkge1xuICAgIGxldCBwYXJzZWRWYWx1ZTtcblxuICAgIHN3aXRjaCAodmFsdWVUeXBlKSB7XG4gICAgICBjYXNlICdudW1iZXInOlxuICAgICAgICBwYXJzZWRWYWx1ZSA9IGAke3ZhbHVlfWA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnYm9vbGVhbic6XG4gICAgICAgIHBhcnNlZFZhbHVlID0gdmFsdWUgPyAnMScgOiAnMCc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnanNvbic6XG4gICAgICAgIHBhcnNlZFZhbHVlID0gSlNPTi5zdHJpbmdpZnkocGFyc2VkVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHBhcnNlZFZhbHVlID0gdmFsdWU7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcGFyc2VkVmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogTWFwcGluZyBhbmQgcGFyc2UgbWV0YWRhdGEgdG8gY29sbGVjdGlvbiBlbnRyaWVzLlxuICAgKiBAcGFyYW0ge01ldGF9IGF0dHIgLVxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGFyc2VUeXBlIC1cbiAgICovXG4gIG1hcE1ldGFkYXRhKGF0dHIsIHBhcnNlVHlwZSA9ICdwYXJzZScpIHtcbiAgICByZXR1cm4ge1xuICAgICAga2V5OiBhdHRyW3RoaXMuS0VZX0NPTFVNTl0sXG4gICAgICB2YWx1ZTogKHBhcnNlVHlwZSA9PT0gJ3BhcnNlJylcbiAgICAgICAgPyBNZXRhYmxlQ29sbGVjdGlvbi5wYXJzZU1ldGFWYWx1ZShcbiAgICAgICAgICBhdHRyW3RoaXMuVkFMVUVfQ09MVU1OXSxcbiAgICAgICAgICB0aGlzLlRZUEVfQ09MVU1OID8gYXR0clt0aGlzLlRZUEVfQ09MVU1OXSA6IGZhbHNlLFxuICAgICAgICApXG4gICAgICAgIDogTWV0YWJsZUNvbGxlY3Rpb24uZm9ybWF0TWV0YVZhbHVlKFxuICAgICAgICAgIGF0dHJbdGhpcy5WQUxVRV9DT0xVTU5dLFxuICAgICAgICAgIHRoaXMuVFlQRV9DT0xVTU4gPyBhdHRyW3RoaXMuVFlQRV9DT0xVTU5dIDogZmFsc2UsXG4gICAgICAgICksXG4gICAgICAuLi50aGlzLmV4dHJhQ29sdW1ucy5tYXAoKGV4dHJhQ29sKSA9PiAoe1xuICAgICAgICBbZXh0cmFDb2xdOiBhdHRyW2V4dHJhQ29sXSB8fCBudWxsLFxuICAgICAgfSkpLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgdGhlIG1ldGFkYXRhIHRvIHRoZSBjb2xsZWN0aW9uLlxuICAgKiBAcGFyYW0ge0FycmF5fSBjb2xsZWN0aW9uIC1cbiAgICovXG4gIG1hcE1ldGFkYXRhVG9Db2xsZWN0aW9uKG1ldGFkYXRhLCBwYXJzZVR5cGUgPSAncGFyc2UnKSB7XG4gICAgcmV0dXJuIG1ldGFkYXRhLm1hcCgobW9kZWwpID0+IHRoaXMubWFwTWV0YWRhdGFUb0NvbGxlY3Rpb24obW9kZWwsIHBhcnNlVHlwZSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbWV0YWRhdGEgdG8gdGhlIG1ldGFibGUgY29sbGVjdGlvbi5cbiAgICogQHBhcmFtIHtBcnJheX0gbWV0YSAtXG4gICAqL1xuICBmcm9tKG1ldGEpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShtZXRhKSkge1xuICAgICAgbWV0YS5mb3JFYWNoKChtKSA9PiB7IHRoaXMuZnJvbShtKTsgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubWV0YWRhdGEucHVzaChtZXRhKTtcbiAgfVxuXG5cbiAgdG9BcnJheSgpIHtcbiAgICByZXR1cm4gdGhpcy5tZXRhZGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGF0aWMgbWV0aG9kIHRvIGxvYWQgbWV0YWRhdGEgdG8gdGhlIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXl9IG1ldGEgXG4gICAqL1xuICBzdGF0aWMgZnJvbShtZXRhKSB7XG4gICAgY29uc3QgY29sbGVjdGlvbiA9IG5ldyBNZXRhYmxlQ29sbGVjdGlvbigpO1xuICAgIGNvbGxlY3Rpb24uZnJvbShtZXRhKTtcblxuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9XG59XG4iLCJpbXBvcnQgeyBkaWZmZXJlbmNlIH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB7IExleGVyIH0gZnJvbSAnQC9saWIvTG9naWNFdmFsdWF0aW9uL0xleGVyJztcbmltcG9ydCBQYXJzZXIgZnJvbSAnQC9saWIvTG9naWNFdmFsdWF0aW9uL1BhcnNlcic7XG5pbXBvcnQgUXVlcnlQYXJzZXIgZnJvbSAnQC9saWIvTG9naWNFdmFsdWF0aW9uL1F1ZXJ5UGFyc2VyJztcbmltcG9ydCByZXNvdXJjZUZpZWxkc0tleXMgZnJvbSAnQC9kYXRhL1Jlc291cmNlRmllbGRzS2V5cyc7XG5cbi8vICBjb25zdCByb2xlID0ge1xuLy8gICBjb21wYXRvdG9yOiAnJyxcbi8vICAgdmFsdWU6ICcnLFxuLy8gICBjb2x1bW5LZXk6ICcnLFxuLy8gICBjb2x1bW5TbHVnOiAnJyxcbi8vICAgaW5kZXg6IDEsXG4vLyB9XG5cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJvbGVRdWVyeShyb2xlKSB7XG4gIGNvbnN0IGNvbHVtbk5hbWUgPSByZXNvdXJjZUZpZWxkc0tleXNbcm9sZS5jb2x1bW5LZXldO1xuXG4gIHN3aXRjaCAocm9sZS5jb21wYXJhdG9yKSB7XG4gICAgY2FzZSAnZXF1YWxzJzpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIChidWlsZGVyKSA9PiB7XG4gICAgICAgIGJ1aWxkZXIud2hlcmUoY29sdW1uTmFtZSwgcm9sZS52YWx1ZSk7XG4gICAgICB9O1xuICAgIGNhc2UgJ25vdF9lcXVhbCc6XG4gICAgY2FzZSAnbm90X2VxdWFscyc6XG4gICAgICByZXR1cm4gKGJ1aWxkZXIpID0+IHtcbiAgICAgICAgYnVpbGRlci53aGVyZU5vdChjb2x1bW5OYW1lLCByb2xlLnZhbHVlKTtcbiAgICAgIH07XG4gIH1cbn1cblxuLyoqXG4gKiBCdWlsZHMgZGF0YWJhc2UgcXVlcnkgZnJvbSBzdG9yZWQgdmlldyByb2xlcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSByb2xlcyAtXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZpZXdSb2xlc0J1aWxkZXIocm9sZXMsIGxvZ2ljRXhwcmVzc2lvbiA9ICcnKSB7XG4gIGNvbnN0IHJvbGVzSW5kZXhTZXQgPSB7fTtcblxuICByb2xlcy5mb3JFYWNoKChyb2xlKSA9PiB7XG4gICAgcm9sZXNJbmRleFNldFtyb2xlLmluZGV4XSA9IGJ1aWxkUm9sZVF1ZXJ5KHJvbGUpO1xuICB9KTtcbiAgLy8gTGV4ZXIgZm9yIGxvZ2ljIGV4cHJlc3Npb24uXG4gIGNvbnN0IGxleGVyID0gbmV3IExleGVyKGxvZ2ljRXhwcmVzc2lvbik7XG4gIGNvbnN0IHRva2VucyA9IGxleGVyLmdldFRva2VucygpO1xuXG4gIC8vIFBhcnNlIHRoZSBsb2dpYyBleHByZXNzaW9uLlxuICBjb25zdCBwYXJzZXIgPSBuZXcgUGFyc2VyKHRva2Vucyk7XG4gIGNvbnN0IHBhcnNlZFRyZWUgPSBwYXJzZXIucGFyc2UoKTtcblxuICBjb25zdCBxdWVyeVBhcnNlciA9IG5ldyBRdWVyeVBhcnNlcihwYXJzZWRUcmVlLCByb2xlc0luZGV4U2V0KTtcbiAgcmV0dXJuIHF1ZXJ5UGFyc2VyLnBhcnNlKCk7XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSB2aWV3IGxvZ2ljIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge1N0cmluZ30gbG9naWNFeHByZXNzaW9uIFxuICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlVmlld0xvZ2ljRXhwcmVzc2lvbihsb2dpY0V4cHJlc3Npb24sIGluZGV4ZXMpIHtcbiAgY29uc3QgbG9naWNFeHBJbmRleGVzID0gbG9naWNFeHByZXNzaW9uLm1hdGNoKC9cXGQrL2cpIHx8IFtdO1xuICByZXR1cm4gIWRpZmZlcmVuY2UobG9naWNFeHBJbmRleGVzLm1hcChOdW1iZXIpLCBpbmRleGVzKS5sZW5ndGg7XG59XG5cbi8qKlxuICogXG4gKiBAcGFyYW0ge0FycmF5fSByb2xlcyAtXG4gKiBAcGFyYW0ge1N0cmluZ30gbG9naWNFeHByZXNzaW9uIC1cbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZVZpZXdSb2xlcyhyb2xlcywgbG9naWNFeHByZXNzaW9uKSB7XG4gIHJldHVybiB2YWxpZGF0ZVZpZXdMb2dpY0V4cHJlc3Npb24obG9naWNFeHByZXNzaW9uLCByb2xlcy5tYXAoKHIpID0+IHIuaW5kZXgpKTtcbn1cblxuLyoqXG4gKiBNYXBlcyB0aGUgdmlldyByb2xlcyB0byB2aWV3IGNvbmRpdGlvbmFscy5cbiAqIEBwYXJhbSB7QXJyYXl9IHZpZXdSb2xlcyAtXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcFZpZXdSb2xlc1RvQ29uZGl0aW9uYWxzKHZpZXdSb2xlcykge1xuICByZXR1cm4gdmlld1JvbGVzLm1hcCgodmlld1JvbGUpID0+ICh7XG4gICAgY29tcGFyYXRvcjogdmlld1JvbGUuY29tcGFyYXRvcixcbiAgICB2YWx1ZTogdmlld1JvbGUudmFsdWUsXG4gICAgY29sdW1uS2V5OiB2aWV3Um9sZS5maWVsZC5jb2x1bW5LZXksXG4gICAgc2x1Zzogdmlld1JvbGUuZmllbGQuc2x1ZyxcbiAgICBpbmRleDogdmlld1JvbGUuaW5kZXgsXG4gIH0pKTtcbn0iLCIvKiBlc2xpbnQtZGlzYWJsZSBnbG9iYWwtcmVxdWlyZSAqL1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IHsgZmxhdHRlbiB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcbmltcG9ydCB7dmlld1JvbGVzQnVpbGRlcn0gZnJvbSAnQC9saWIvVmlld1JvbGVzQnVpbGRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFjY291bnQgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdhY2NvdW50cyc7XG4gIH1cblxuICAvKipcbiAgICogTW9kZWwgbW9kaWZpZXJzLlxuICAgKi9cbiAgc3RhdGljIGdldCBtb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbHRlckFjY291bnRUeXBlcyhxdWVyeSwgdHlwZXNJZHMpIHtcbiAgICAgICAgaWYgKHR5cGVzSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBxdWVyeS53aGVyZUluKCdhY2NvdW5fdHlwZV9pZCcsIHR5cGVzSWRzKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHZpZXdSb2xlc0J1aWxkZXIocXVlcnksIGNvbmRpdGlvbmFscywgZXhwcmVzc2lvbikge1xuICAgICAgICB2aWV3Um9sZXNCdWlsZGVyKGNvbmRpdGlvbmFscywgZXhwcmVzc2lvbikocXVlcnkpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IEFjY291bnRUeXBlID0gcmVxdWlyZSgnQC9tb2RlbHMvQWNjb3VudFR5cGUnKTtcbiAgICBjb25zdCBBY2NvdW50QmFsYW5jZSA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnRCYWxhbmNlJyk7XG4gICAgY29uc3QgQWNjb3VudFRyYW5zYWN0aW9uID0gcmVxdWlyZSgnQC9tb2RlbHMvQWNjb3VudFRyYW5zYWN0aW9uJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBBY2NvdW50IG1vZGVsIG1heSBiZWxvbmdzIHRvIGFjY291bnQgdHlwZS5cbiAgICAgICAqL1xuICAgICAgdHlwZToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IEFjY291bnRUeXBlLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnYWNjb3VudHMuYWNjb3VudFR5cGVJZCcsXG4gICAgICAgICAgdG86ICdhY2NvdW50X3R5cGVzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogQWNjb3VudCBtb2RlbCBtYXkgaGFzIG1hbnkgYmFsYW5jZXMgYWNjb3VudHMuXG4gICAgICAgKi9cbiAgICAgIGJhbGFuY2U6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBBY2NvdW50QmFsYW5jZS5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRzLmlkJyxcbiAgICAgICAgICB0bzogJ2FjY291bnRfYmFsYW5jZXMuYWNjb3VudElkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogQWNjb3VudCBtb2RlbCBtYXkgaGFzIG1hbnkgdHJhbnNhY3Rpb25zLlxuICAgICAgICovXG4gICAgICB0cmFuc2FjdGlvbnM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudFRyYW5zYWN0aW9uLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnYWNjb3VudHMuaWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHNfdHJhbnNhY3Rpb25zLmFjY291bnRJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBzdGF0aWMgY29sbGVjdEpvdXJuYWxFbnRyaWVzKGFjY291bnRzKSB7XG4gICAgcmV0dXJuIGZsYXR0ZW4oYWNjb3VudHMubWFwKChhY2NvdW50KSA9PiBhY2NvdW50LnRyYW5zYWN0aW9ucy5tYXAoKHRyYW5zYWN0aW9uKSA9PiAoe1xuICAgICAgYWNjb3VudElkOiBhY2NvdW50LmlkLFxuICAgICAgLi4udHJhbnNhY3Rpb24sXG4gICAgICBhY2NvdW50Tm9ybWFsOiBhY2NvdW50LnR5cGUubm9ybWFsLFxuICAgIH0pKSkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWNjb3VudEJhbGFuY2UgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdhY2NvdW50X2JhbGFuY2VzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBBY2NvdW50ID0gcmVxdWlyZSgnQC9tb2RlbHMvQWNjb3VudCcpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY291bnQ6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBBY2NvdW50LmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnYWNjb3VudF9iYWxhbmNlLmFjY291bnRfaWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQWNjb3VudFRyYW5zYWN0aW9uIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYWNjb3VudHNfdHJhbnNhY3Rpb25zJztcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RlbCBtb2RpZmllcnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IG1vZGlmaWVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsdGVyQWNjb3VudHMocXVlcnksIGFjY291bnRzSWRzKSB7XG4gICAgICAgIGlmIChhY2NvdW50c0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmVJbignYWNjb3VudF9pZCcsIGFjY291bnRzSWRzKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGZpbHRlclRyYW5zYWN0aW9uVHlwZXMocXVlcnksIHR5cGVzKSB7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHR5cGVzKSAmJiB0eXBlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmVJbigncmVmZXJlbmNlX3R5cGUnLCB0eXBlcyk7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHR5cGVzID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdyZWZlcmVuY2VfdHlwZScsIHR5cGVzKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGZpbHRlckRhdGVSYW5nZShxdWVyeSwgc3RhcnREYXRlLCBlbmREYXRlLCB0eXBlID0gJ2RheScpIHtcbiAgICAgICAgY29uc3QgZGF0ZUZvcm1hdCA9ICdZWVlZLU1NLUREIEhIOm1tOnNzJztcbiAgICAgICAgY29uc3QgZnJvbURhdGUgPSBtb21lbnQoc3RhcnREYXRlKS5zdGFydE9mKHR5cGUpLmZvcm1hdChkYXRlRm9ybWF0KTtcbiAgICAgICAgY29uc3QgdG9EYXRlID0gbW9tZW50KGVuZERhdGUpLmVuZE9mKHR5cGUpLmZvcm1hdChkYXRlRm9ybWF0KTtcblxuICAgICAgICBpZiAoc3RhcnREYXRlKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ2RhdGUnLCAnPj0nLCBmcm9tRGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVuZERhdGUpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgnZGF0ZScsICc8PScsIHRvRGF0ZSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBmaWx0ZXJBbW91bnRSYW5nZShxdWVyeSwgZnJvbUFtb3VudCwgdG9BbW91bnQpIHtcbiAgICAgICAgaWYgKGZyb21BbW91bnQpIHtcbiAgICAgICAgICBxdWVyeS5hbmRXaGVyZSgocSkgPT4ge1xuICAgICAgICAgICAgcS53aGVyZSgnY3JlZGl0JywgJz49JywgZnJvbUFtb3VudCk7XG4gICAgICAgICAgICBxLm9yV2hlcmUoJ2RlYml0JywgJz49JywgZnJvbUFtb3VudCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRvQW1vdW50KSB7XG4gICAgICAgICAgcXVlcnkuYW5kV2hlcmUoKHEpID0+IHtcbiAgICAgICAgICAgIHEud2hlcmUoJ2NyZWRpdCcsICc8PScsIHRvQW1vdW50KTtcbiAgICAgICAgICAgIHEub3JXaGVyZSgnZGViaXQnLCAnPD0nLCB0b0Ftb3VudCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzdW1hdGlvbkNyZWRpdERlYml0KHF1ZXJ5KSB7XG4gICAgICAgIHF1ZXJ5LnN1bSgnY3JlZGl0IGFzIGNyZWRpdCcpO1xuICAgICAgICBxdWVyeS5zdW0oJ2RlYml0IGFzIGRlYml0Jyk7XG4gICAgICAgIHF1ZXJ5Lmdyb3VwQnkoJ2FjY291bnRfaWQnKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBBY2NvdW50ID0gcmVxdWlyZSgnQC9tb2RlbHMvQWNjb3VudCcpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFjY291bnQ6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBBY2NvdW50LmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnYWNjb3VudHNfdHJhbnNhY3Rpb25zLmFjY291bnRJZCcsXG4gICAgICAgICAgdG86ICdhY2NvdW50cy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsIi8vIGltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEFjY291bnRUeXBlIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWVcbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAnYWNjb3VudF90eXBlcyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgQWNjb3VudCA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnQnKTtcblxuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIEFjY291bnQgdHlwZSBtYXkgaGFzIG1hbnkgYXNzb2NpYXRlZCBhY2NvdW50cy5cbiAgICAgICAqL1xuICAgICAgYWNjb3VudHM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2FjY291bnRfdHlwZXMuaWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHMuYWNjb3VudFR5cGVJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdWRnZXQgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdidWRnZXRzJztcbiAgfVxuXG4gIHN0YXRpYyBnZXQgdmlydHVhbEF0dHJpYnV0ZXMoKSB7XG4gICAgcmV0dXJuIFsncmFuZ2VCeScsICdyYW5nZUluY3JlbWVudCddO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vZGVsIG1vZGlmaWVycy5cbiAgICovXG4gIHN0YXRpYyBnZXQgbW9kaWZpZXJzKCkge1xuICAgIHJldHVybiB7XG4gICAgICBmaWx0ZXJCeVllYXIocXVlcnksIHllYXIpIHtcbiAgICAgICAgcXVlcnkud2hlcmUoJ3llYXInLCB5ZWFyKTtcbiAgICAgIH0sXG4gICAgICBmaWx0ZXJCeUluY29tZVN0YXRlbWVudChxdWVyeSkge1xuICAgICAgICBxdWVyeS53aGVyZSgnYWNjb3VudF90eXBlcycsICdpbmNvbWVfc3RhdGVtZW50Jyk7XG4gICAgICB9LFxuICAgICAgZmlsdGVyQnlQcm9maXRMb3NzKHF1ZXJ5KSB7XG4gICAgICAgIHF1ZXJ5LndoZXJlKCdhY2NvdW50c190eXBlcycsICdwcm9maXRfbG9zcycpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0IHJhbmdlQnkoKSB7XG4gICAgc3dpdGNoICh0aGlzLnBlcmlvZCkge1xuICAgICAgY2FzZSAnaGFsZi15ZWFyJzpcbiAgICAgIGNhc2UgJ3F1YXJ0ZXInOlxuICAgICAgICByZXR1cm4gJ21vbnRoJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0aGlzLnBlcmlvZDtcbiAgICB9XG4gIH1cblxuICBnZXQgcmFuZ2VJbmNyZW1lbnQoKSB7XG4gICAgc3dpdGNoICh0aGlzLnBlcmlvZCkge1xuICAgICAgY2FzZSAnaGFsZi15ZWFyJzpcbiAgICAgICAgcmV0dXJuIDY7XG4gICAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgICAgcmV0dXJuIDM7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gMTtcbiAgICB9XG4gIH1cblxuICBnZXQgcmFuZ2VPZmZzZXQoKSB7XG4gICAgc3dpdGNoICh0aGlzLnBlcmlvZCkge1xuICAgICAgY2FzZSAnaGFsZi15ZWFyJzogcmV0dXJuIDU7XG4gICAgICBjYXNlICdxdWFydGVyJzogcmV0dXJuIDI7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gMDtcbiAgICB9XG4gIH1cbn1cbiIsImltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCdWRnZXQgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdidWRnZXRfZW50cmllcyc7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuaW1wb3J0IHt2aWV3Um9sZXNCdWlsZGVyfSBmcm9tICdAL2xpYi9WaWV3Um9sZXNCdWlsZGVyJztcbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEV4cGVuc2UgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdleHBlbnNlcyc7XG4gIH1cblxuICBzdGF0aWMgZ2V0IHJlZmVyZW5jZVR5cGUoKSB7XG4gICAgcmV0dXJuICdFeHBlbnNlJztcbiAgfVxuXG4gIC8qKlxuICAgKiBNb2RlbCBtb2RpZmllcnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IG1vZGlmaWVycygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZmlsdGVyQnlEYXRlUmFuZ2UocXVlcnksIHN0YXJ0RGF0ZSwgZW5kRGF0ZSkge1xuICAgICAgICBpZiAoc3RhcnREYXRlKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ2RhdGUnLCAnPj0nLCBzdGFydERhdGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChlbmREYXRlKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ2RhdGUnLCAnPD0nLCBlbmREYXRlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGZpbHRlckJ5QW1vdW50UmFuZ2UocXVlcnksIGZyb20sIHRvKSB7XG4gICAgICAgIGlmIChmcm9tKSB7XG4gICAgICAgICAgcXVlcnkud2hlcmUoJ2Ftb3VudCcsICc+PScsIGZyb20pO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0bykge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdhbW91bnQnLCAnPD0nLCB0byk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBmaWx0ZXJCeUV4cGVuc2VBY2NvdW50KHF1ZXJ5LCBhY2NvdW50SWQpIHtcbiAgICAgICAgaWYgKGFjY291bnRJZCkge1xuICAgICAgICAgIHF1ZXJ5LndoZXJlKCdleHBlbnNlX2FjY291bnRfaWQnLCBhY2NvdW50SWQpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZmlsdGVyQnlQYXltZW50QWNjb3VudChxdWVyeSwgYWNjb3VudElkKSB7XG4gICAgICAgIGlmIChhY2NvdW50SWQpIHtcbiAgICAgICAgICBxdWVyeS53aGVyZSgncGF5bWVudF9hY2NvdW50X2lkJywgYWNjb3VudElkKTtcbiAgICAgICAgfVxuICAgICAgfSxcblxuICAgICAgdmlld1JvbGVzQnVpbGRlcihxdWVyeSwgY29uZGl0aW9uYWxzLCBleHByZXNzaW9uKSB7XG4gICAgICAgIHZpZXdSb2xlc0J1aWxkZXIoY29uZGl0aW9uYWxzLCBleHByZXNzaW9uKShxdWVyeSk7XG4gICAgICB9LFxuXG4gICAgICBvcmRlckJ5KHF1ZXJ5KSB7XG4gICAgICAgIFxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgQWNjb3VudCA9IHJlcXVpcmUoJ0AvbW9kZWxzL0FjY291bnQnKTtcbiAgICBjb25zdCBVc2VyID0gcmVxdWlyZSgnQC9tb2RlbHMvVXNlcicpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHBheW1lbnRBY2NvdW50OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogQWNjb3VudC5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2V4cGVuc2VzLnBheW1lbnRBY2NvdW50SWQnLFxuICAgICAgICAgIHRvOiAnYWNjb3VudHMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgZXhwZW5zZUFjY291bnQ6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBBY2NvdW50LmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnZXhwZW5zZXMuZXhwZW5zZUFjY291bnRJZCcsXG4gICAgICAgICAgdG86ICdhY2NvdW50cy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICB1c2VyOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogVXNlci5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ2V4cGVuc2VzLnVzZXJJZCcsXG4gICAgICAgICAgdG86ICd1c2Vycy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEl0ZW0gZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdpdGVtcyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogSXRlbSBtYXkgaGFzIG1hbnkgbWV0YSBkYXRhLlxuICAgICAgICovXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuSGFzTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbEJhc2U6IHBhdGguam9pbihfX2Rpcm5hbWUsICdJdGVtTWV0YWRhdGEnKSxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdpdGVtcy5pZCcsXG4gICAgICAgICAgdG86ICdpdGVtc19tZXRhZGF0YS5pdGVtX2lkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogSXRlbSBtYXkgYmVsb25ncyB0byBjYXRlb2dvcnkgbW9kZWwuXG4gICAgICAgKi9cbiAgICAgIGNhdGVnb3J5OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnSXRlbUNhdGVnb3J5JyksXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnaXRlbXMuY2F0ZWdvcnlJZCcsXG4gICAgICAgICAgdG86ICdpdGVtc19jYXRlZ29yaWVzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgSXRlbUNhdGVnb3J5IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ2l0ZW1zX2NhdGVnb3JpZXMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIEl0ZW0gY2F0ZWdvcnkgbWF5IGhhcyBtYW55IGl0ZW1zLlxuICAgICAgICovXG4gICAgICBpdGVtczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuSGFzTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbEJhc2U6IHBhdGguam9pbihfX2Rpcm5hbWUsICdJdGVtJyksXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAnaXRlbXNfY2F0ZWdvcmllcy5pdGVtX2lkJyxcbiAgICAgICAgICB0bzogJ2l0ZW1zLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEpvdXJuYWxFbnRyeSBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdtYW51YWxfam91cm5hbHMnO1xuICB9XG59XG4iLCJpbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTWFudWFsSm91cm5hbCBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdtYW51YWxfam91cm5hbHMnO1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQge3RyYW5zZm9ybSwgc25ha2VDYXNlfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHttYXBLZXlzRGVlcH0gZnJvbSAnQC91dGlscyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIE1vZGVsQmFzZSBleHRlbmRzIE1vZGVsIHtcbiAgc3RhdGljIGdldCBjb2xsZWN0aW9uKCkge1xuICAgIHJldHVybiBBcnJheTtcbiAgfVxuXG4gIHN0YXRpYyBxdWVyeSguLi5hcmdzKSB7XG4gICAgcmV0dXJuIHN1cGVyLnF1ZXJ5KC4uLmFyZ3MpLnJ1bkFmdGVyKChyZXN1bHQpID0+IHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29sbGVjdGlvbi5mcm9tKHJlc3VsdCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgJGZvcm1hdEpzb24oanNvbiwgb3B0KSB7XG4gICAgY29uc3QgdHJhbnNmb3JtZWQgPSBtYXBLZXlzRGVlcChqc29uLCAodmFsdWUsIGtleSkgPT4ge1xuICAgICAgcmV0dXJuIHNuYWtlQ2FzZShrZXkpO1xuICAgIH0pO1xuICAgIGNvbnN0IHBhcnNlZEpzb24gPSBzdXBlci4kZm9ybWF0SnNvbih0cmFuc2Zvcm1lZCwgb3B0KTtcblxuICAgIHJldHVybiBwYXJzZWRKc29uO1xuICB9XG59XG4iLCJpbXBvcnQgeyBtaXhpbiB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcbmltcG9ydCBNZXRhYmxlQ29sbGVjdGlvbiBmcm9tICdAL2xpYi9NZXRhYmxlL01ldGFibGVDb2xsZWN0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgT3B0aW9uIGV4dGVuZHMgbWl4aW4oQmFzZU1vZGVsLCBbbWl4aW5dKSB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdvcHRpb25zJztcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVycmlkZSB0aGUgbW9kZWwgcXVlcnkuXG4gICAqIEBwYXJhbSAgey4uLmFueX0gYXJncyAtXG4gICAqL1xuICBzdGF0aWMgcXVlcnkoLi4uYXJncykge1xuICAgIHJldHVybiBzdXBlci5xdWVyeSguLi5hcmdzKS5ydW5BZnRlcigocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0IGluc3RhbmNlb2YgTWV0YWJsZUNvbGxlY3Rpb24pIHtcbiAgICAgICAgcmVzdWx0LnNldE1vZGVsKE9wdGlvbik7XG4gICAgICB9XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGdldCBjb2xsZWN0aW9uKCkge1xuICAgIHJldHVybiBNZXRhYmxlQ29sbGVjdGlvbjtcbiAgfVxufVxuIiwiaW1wb3J0IE1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUGFzc3dvcmRSZXNldHMgZXh0ZW5kcyBNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3Bhc3N3b3JkX3Jlc2V0cyc7XG4gIH1cbn1cbiIsImltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFBlcm1pc3Npb24gZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZSBvZiBSb2xlIG1vZGVsLlxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdwZXJtaXNzaW9ucyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUGVybWlzc2lvbiBtb2RlbCBtYXkgYmVsb25ncyB0byByb2xlIG1vZGVsLlxuICAgICAgICovXG4gICAgICByb2xlOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnUm9sZScpLFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3Blcm1pc3Npb25zLnJvbGVfaWQnLFxuICAgICAgICAgIHRvOiAncm9sZXMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcblxuICAgICAgLy8gcmVzb3VyY2U6IHtcbiAgICAgIC8vICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgLy8gICBtb2RlbEJhc2U6IHBhdGguam9pbihfX2Rpcm5hbWUsICdSZXNvdXJjZScpLFxuICAgICAgLy8gICBqb2luOiB7XG4gICAgICAvLyAgICAgZnJvbTogJ3Blcm1pc3Npb25zLicsXG4gICAgICAvLyAgICAgdG86ICcnLFxuICAgICAgLy8gICB9XG4gICAgICAvLyB9XG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVzb3VyY2UgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAncmVzb3VyY2VzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaW1lc3RhbXAgY29sdW1ucy5cbiAgICovXG4gIHN0YXRpYyBnZXQgaGFzVGltZXN0YW1wcygpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgVmlldyA9IHJlcXVpcmUoJ0AvbW9kZWxzL1ZpZXcnKTtcbiAgICBjb25zdCBSZXNvdXJjZUZpZWxkID0gcmVxdWlyZSgnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZCcpO1xuICAgIGNvbnN0IFBlcm1pc3Npb24gPSByZXF1aXJlKCdAL21vZGVscy9QZXJtaXNzaW9uJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBSZXNvdXJjZSBtb2RlbCBtYXkgaGFzIG1hbnkgdmlld3MuXG4gICAgICAgKi9cbiAgICAgIHZpZXdzOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5IYXNNYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFZpZXcuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyZXNvdXJjZXMuaWQnLFxuICAgICAgICAgIHRvOiAndmlld3MucmVzb3VyY2VJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJlc291cmNlIG1vZGVsIG1heSBoYXMgbWFueSBmaWVsZHMuXG4gICAgICAgKi9cbiAgICAgIGZpZWxkczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuSGFzTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBSZXNvdXJjZUZpZWxkLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlX2ZpZWxkcy5yZXNvdXJjZUlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUmVzb3VyY2UgbW9kZWwgbWF5IGhhcyBtYW55IGFzc29jaWF0ZWQgcGVybWlzc2lvbnMuXG4gICAgICAgKi9cbiAgICAgIHBlcm1pc3Npb25zOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5NYW55VG9NYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFBlcm1pc3Npb24uZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyZXNvdXJjZXMuaWQnLFxuICAgICAgICAgIHRocm91Z2g6IHtcbiAgICAgICAgICAgIGZyb206ICdyb2xlX2hhc19wZXJtaXNzaW9ucy5yZXNvdXJjZUlkJyxcbiAgICAgICAgICAgIHRvOiAncm9sZV9oYXNfcGVybWlzc2lvbnMucGVybWlzc2lvbklkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvOiAncGVybWlzc2lvbnMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBzbmFrZUNhc2UgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgQmFzZU1vZGVsIGZyb20gJ0AvbW9kZWxzL01vZGVsJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgUmVzb3VyY2VGaWVsZCBleHRlbmRzIEJhc2VNb2RlbCB7XG4gIC8qKlxuICAgKiBUYWJsZSBuYW1lLlxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdyZXNvdXJjZV9maWVsZHMnO1xuICB9XG5cbiAgc3RhdGljIGdldCBqc29uQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydvcHRpb25zJ107XG4gIH1cblxuICAvKipcbiAgICogTW9kZWwgbW9kaWZpZXJzLlxuICAgKi9cbiAgc3RhdGljIGdldCBtb2RpZmllcnMoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHdoZXJlTm90UHJlZGVmaW5lZChxdWVyeSkge1xuICAgICAgICBxdWVyeS53aGVyZU5vdCgncHJlZGVmaW5lZCcsIHRydWUpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRpbWVzdGFtcCBjb2x1bW5zLlxuICAgKi9cbiAgc3RhdGljIGdldCBoYXNUaW1lc3RhbXBzKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWaXJ0dWFsIGF0dHJpYnV0ZXMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHZpcnR1YWxBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2tleSddO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc291cmNlIGZpZWxkIGtleS5cbiAgICovXG4gIGtleSgpIHtcbiAgICByZXR1cm4gc25ha2VDYXNlKHRoaXMubGFiZWxOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBSZXNvdXJjZSBmaWVsZCBtYXkgYmVsb25ncyB0byByZXNvdXJjZSBtb2RlbC5cbiAgICAgICAqL1xuICAgICAgcmVzb3VyY2U6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkJlbG9uZ3NUb09uZVJlbGF0aW9uLFxuICAgICAgICBtb2RlbEJhc2U6IHBhdGguam9pbihfX2Rpcm5hbWUsICdSZXNvdXJjZScpLFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3Jlc291cmNlX2ZpZWxkcy5yZXNvdXJjZV9pZCcsXG4gICAgICAgICAgdG86ICdyZXNvdXJjZXMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBNb2RlbCB9IGZyb20gJ29iamVjdGlvbic7XG5pbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuaW1wb3J0IFJlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24gZnJvbSAnQC9jb2xsZWN0aW9uL1Jlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24nO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBSZXNvdXJjZUZpZWxkTWV0YWRhdGEgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAncmVzb3VyY2VfY3VzdG9tX2ZpZWxkc19tZXRhZGF0YSc7XG4gIH1cblxuICAvKipcbiAgICogT3ZlcnJpZGUgdGhlIHJlc291cmNlIGZpZWxkIG1ldGFkYXRhIGNvbGxlY3Rpb24uXG4gICAqL1xuICBzdGF0aWMgZ2V0IGNvbGxlY3Rpb24oKSB7XG4gICAgcmV0dXJuIFJlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb247XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIC8qKlxuICAgICAgICogUmVzb3VyY2UgZmllbGQgbWF5IGJlbG9uZ3MgdG8gcmVzb3VyY2UgbW9kZWwuXG4gICAgICAgKi9cbiAgICAgIHJlc291cmNlOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxCYXNlOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnUmVzb3VyY2UnKSxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyZXNvdXJjZV9maWVsZHMucmVzb3VyY2VfaWQnLFxuICAgICAgICAgIHRvOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJvbGUgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvKipcbiAgICogVGFibGUgbmFtZSBvZiBSb2xlIG1vZGVsLlxuICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICdyb2xlcyc7XG4gIH1cblxuICAvKipcbiAgICogVGltZXN0YW1wIGNvbHVtbnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IGhhc1RpbWVzdGFtcHMoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IFBlcm1pc3Npb24gPSByZXF1aXJlKCdAL21vZGVscy9QZXJtaXNzaW9uJyk7XG4gICAgY29uc3QgUmVzb3VyY2UgPSByZXF1aXJlKCdAL21vZGVscy9SZXNvdXJjZScpO1xuICAgIGNvbnN0IFVzZXIgPSByZXF1aXJlKCdAL21vZGVscy9Vc2VyJyk7XG4gICAgY29uc3QgUmVzb3VyY2VGaWVsZCA9IHJlcXVpcmUoJ0AvbW9kZWxzL1Jlc291cmNlRmllbGQnKTtcblxuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIFJvbGUgbWF5IGhhcyBtYW55IHBlcm1pc3Npb25zLlxuICAgICAgICovXG4gICAgICBwZXJtaXNzaW9uczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuTWFueVRvTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBQZXJtaXNzaW9uLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncm9sZXMuaWQnLFxuICAgICAgICAgIHRocm91Z2g6IHtcbiAgICAgICAgICAgIGZyb206ICdyb2xlX2hhc19wZXJtaXNzaW9ucy5yb2xlSWQnLFxuICAgICAgICAgICAgdG86ICdyb2xlX2hhc19wZXJtaXNzaW9ucy5wZXJtaXNzaW9uSWQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdG86ICdwZXJtaXNzaW9ucy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFJvbGUgbWF5IGhhcyBtYW55IHJlc291cmNlcy5cbiAgICAgICAqL1xuICAgICAgcmVzb3VyY2VzOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5NYW55VG9NYW55UmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFJlc291cmNlLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAncm9sZXMuaWQnLFxuICAgICAgICAgIHRocm91Z2g6IHtcbiAgICAgICAgICAgIGZyb206ICdyb2xlX2hhc19wZXJtaXNzaW9ucy5yb2xlSWQnLFxuICAgICAgICAgICAgdG86ICdyb2xlX2hhc19wZXJtaXNzaW9ucy5yZXNvdXJjZUlkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvOiAncmVzb3VyY2VzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUm9sZSBtYXkgaGFzIHJlc291cmNlIGZpZWxkLlxuICAgICAgICovXG4gICAgICBmaWVsZDoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFJlc291cmNlRmllbGQuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICdyb2xlcy5maWVsZElkJyxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlX2ZpZWxkcy5pZCcsXG4gICAgICAgIH1cbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogUm9sZSBtYXkgaGFzIG1hbnkgYXNzb2NpYXRlZCB1c2Vycy5cbiAgICAgICAqL1xuICAgICAgdXNlcnM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLk1hbnlUb01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogVXNlci5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3JvbGVzLmlkJyxcbiAgICAgICAgICB0aHJvdWdoOiB7XG4gICAgICAgICAgICBmcm9tOiAndXNlcl9oYXNfcm9sZXMucm9sZUlkJyxcbiAgICAgICAgICAgIHRvOiAndXNlcl9oYXNfcm9sZXMudXNlcklkJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvOiAndXNlcnMuaWQnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuICB9XG59XG4iLCJpbXBvcnQgYmNyeXB0IGZyb20gJ2JjcnlwdGpzJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuLy8gaW1wb3J0IFBlcm1pc3Npb25zU2VydmljZSBmcm9tICdAL3NlcnZpY2VzL1Blcm1pc3Npb25zU2VydmljZSc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFVzZXIgZXh0ZW5kcyBCYXNlTW9kZWwge1xuICAvLyAuLi5QZXJtaXNzaW9uc1NlcnZpY2VcblxuICBzdGF0aWMgZ2V0IHZpcnR1YWxBdHRyaWJ1dGVzKCkge1xuICAgIHJldHVybiBbJ2Z1bGxOYW1lJ107XG4gIH1cblxuICAvKipcbiAgICogVGFibGUgbmFtZVxuICAgKi9cbiAgc3RhdGljIGdldCB0YWJsZU5hbWUoKSB7XG4gICAgcmV0dXJuICd1c2Vycyc7XG4gIH1cblxuICAvKipcbiAgICogUmVsYXRpb25zaGlwIG1hcHBpbmcuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHJlbGF0aW9uTWFwcGluZ3MoKSB7XG4gICAgY29uc3QgUm9sZSA9IHJlcXVpcmUoJ0AvbW9kZWxzL1JvbGUnKTtcblxuICAgIHJldHVybiB7XG4gICAgICByb2xlczoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuTWFueVRvTWFueVJlbGF0aW9uLFxuICAgICAgICBtb2RlbENsYXNzOiBSb2xlLmRlZmF1bHQsXG4gICAgICAgIGpvaW46IHtcbiAgICAgICAgICBmcm9tOiAndXNlcnMuaWQnLFxuICAgICAgICAgIHRocm91Z2g6IHtcbiAgICAgICAgICAgIGZyb206ICd1c2VyX2hhc19yb2xlcy51c2VySWQnLFxuICAgICAgICAgICAgdG86ICd1c2VyX2hhc19yb2xlcy5yb2xlSWQnLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgdG86ICdyb2xlcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZ5IHRoZSBwYXNzd29yZCBvZiB0aGUgdXNlci5cbiAgICogQHBhcmFtICB7U3RyaW5nfSBwYXNzd29yZCAtIFRoZSBnaXZlbiBwYXNzd29yZC5cbiAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICovXG4gIHZlcmlmeVBhc3N3b3JkKHBhc3N3b3JkKSB7XG4gICAgcmV0dXJuIGJjcnlwdC5jb21wYXJlU3luYyhwYXNzd29yZCwgdGhpcy5wYXNzd29yZCk7XG4gIH1cblxuICBmdWxsTmFtZSgpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5maXJzdE5hbWV9ICR7dGhpcy5sYXN0TmFtZX1gO1xuICB9XG59XG4iLCJpbXBvcnQgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSAnb2JqZWN0aW9uJztcbmltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3IGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3ZpZXdzJztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWxhdGlvbnNoaXAgbWFwcGluZy5cbiAgICovXG4gIHN0YXRpYyBnZXQgcmVsYXRpb25NYXBwaW5ncygpIHtcbiAgICBjb25zdCBSZXNvdXJjZSA9IHJlcXVpcmUoJ0AvbW9kZWxzL1Jlc291cmNlJyk7XG4gICAgY29uc3QgVmlld0NvbHVtbiA9IHJlcXVpcmUoJ0AvbW9kZWxzL1ZpZXdDb2x1bW4nKTtcbiAgICBjb25zdCBWaWV3Um9sZSA9IHJlcXVpcmUoJ0AvbW9kZWxzL1ZpZXdSb2xlJyk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLyoqXG4gICAgICAgKiBWaWV3IG1vZGVsIGJlbG9uZ3MgdG8gcmVzb3VyY2UgbW9kZWwuXG4gICAgICAgKi9cbiAgICAgIHJlc291cmNlOiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogUmVzb3VyY2UuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICd2aWV3cy5yZXNvdXJjZUlkJyxcbiAgICAgICAgICB0bzogJ3Jlc291cmNlcy5pZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuXG4gICAgICAvKipcbiAgICAgICAqIFZpZXcgbW9kZWwgbWF5IGhhcyBtYW55IGNvbHVtbnMuXG4gICAgICAgKi9cbiAgICAgIGNvbHVtbnM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogVmlld0NvbHVtbi5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3ZpZXdzLmlkJyxcbiAgICAgICAgICB0bzogJ3ZpZXdfaGFzX2NvbHVtbnMudmlld0lkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogVmlldyBtb2RlbCBtYXkgaGFzIG1hbnkgdmlldyByb2xlcy5cbiAgICAgICAqL1xuICAgICAgcm9sZXM6IHtcbiAgICAgICAgcmVsYXRpb246IE1vZGVsLkhhc01hbnlSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogVmlld1JvbGUuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICd2aWV3cy5pZCcsXG4gICAgICAgICAgdG86ICd2aWV3X3JvbGVzLnZpZXdJZCcsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG4gIH1cbn1cbiIsImltcG9ydCBCYXNlTW9kZWwgZnJvbSAnQC9tb2RlbHMvTW9kZWwnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWaWV3Q29sdW1uIGV4dGVuZHMgQmFzZU1vZGVsIHtcbiAgLyoqXG4gICAqIFRhYmxlIG5hbWUuXG4gICAqL1xuICBzdGF0aWMgZ2V0IHRhYmxlTmFtZSgpIHtcbiAgICByZXR1cm4gJ3ZpZXdfaGFzX2NvbHVtbnMnO1xuICB9XG5cbiAgLyoqXG4gICAqIFRpbWVzdGFtcCBjb2x1bW5zLlxuICAgKi9cbiAgc3RhdGljIGdldCBoYXNUaW1lc3RhbXBzKCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IEJhc2VNb2RlbCBmcm9tICdAL21vZGVscy9Nb2RlbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZpZXdSb2xlIGV4dGVuZHMgQmFzZU1vZGVsIHtcblxuICAvKipcbiAgICogVmlydHVhbCBhdHRyaWJ1dGVzLlxuICAgKi9cbiAgc3RhdGljIGdldCB2aXJ0dWFsQXR0cmlidXRlcygpIHtcbiAgICByZXR1cm4gWydjb21wYXJhdG9ycyddO1xuICB9XG5cbiAgc3RhdGljIGdldCBjb21wYXJhdG9ycygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgJ2VxdWFscycsICdub3RfZXF1YWwnLCAnY29udGFpbnMnLCAnbm90X2NvbnRhaW4nLFxuICAgIF07XG4gIH1cblxuICAvKipcbiAgICogVGFibGUgbmFtZS5cbiAgICovXG4gIHN0YXRpYyBnZXQgdGFibGVOYW1lKCkge1xuICAgIHJldHVybiAndmlld19yb2xlcyc7XG4gIH1cblxuICAvKipcbiAgICogVGltZXN0YW1wIGNvbHVtbnMuXG4gICAqL1xuICBzdGF0aWMgZ2V0IGhhc1RpbWVzdGFtcHMoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlbGF0aW9uc2hpcCBtYXBwaW5nLlxuICAgKi9cbiAgc3RhdGljIGdldCByZWxhdGlvbk1hcHBpbmdzKCkge1xuICAgIGNvbnN0IFJlc291cmNlRmllbGQgPSByZXF1aXJlKCdAL21vZGVscy9SZXNvdXJjZUZpZWxkJyk7XG4gICAgY29uc3QgVmlldyA9IHJlcXVpcmUoJ0AvbW9kZWxzL1ZpZXcnKTtcblxuICAgIHJldHVybiB7XG4gICAgICAvKipcbiAgICAgICAqIFZpZXcgcm9sZSBtb2RlbCBtYXkgYmVsb25ncyB0byB2aWV3IG1vZGVsLlxuICAgICAgICovXG4gICAgICB2aWV3OiB7XG4gICAgICAgIHJlbGF0aW9uOiBNb2RlbC5CZWxvbmdzVG9PbmVSZWxhdGlvbixcbiAgICAgICAgbW9kZWxDbGFzczogVmlldy5kZWZhdWx0LFxuICAgICAgICBqb2luOiB7XG4gICAgICAgICAgZnJvbTogJ3ZpZXdfcm9sZXMudmlld0lkJyxcbiAgICAgICAgICB0bzogJ3ZpZXdzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG5cbiAgICAgIC8qKlxuICAgICAgICogVmlldyByb2xlIG1vZGVsIG1heSBiZWxvbmdzIHRvIHJlc291cmNlIGZpZWxkIG1vZGVsLlxuICAgICAgICovXG4gICAgICBmaWVsZDoge1xuICAgICAgICByZWxhdGlvbjogTW9kZWwuQmVsb25nc1RvT25lUmVsYXRpb24sXG4gICAgICAgIG1vZGVsQ2xhc3M6IFJlc291cmNlRmllbGQuZGVmYXVsdCxcbiAgICAgICAgam9pbjoge1xuICAgICAgICAgIGZyb206ICd2aWV3X3JvbGVzLmZpZWxkSWQnLFxuICAgICAgICAgIHRvOiAncmVzb3VyY2VfZmllbGRzLmlkJyxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgTW9kZWwgfSBmcm9tICdvYmplY3Rpb24nO1xuaW1wb3J0IGtuZXggZnJvbSAnQC9kYXRhYmFzZS9rbmV4JztcblxuLy8gQmluZCBhbGwgTW9kZWxzIHRvIGEga25leCBpbnN0YW5jZS4gSWYgeW91IG9ubHkgaGF2ZSBvbmUgZGF0YWJhc2UgaW5cbi8vIHlvdXIgc2VydmVyIHRoaXMgaXMgYWxsIHlvdSBoYXZlIHRvIGRvLiBGb3IgbXVsdGkgZGF0YWJhc2Ugc3lzdGVtcywgc2VlXG4vLyB0aGUgTW9kZWwuYmluZEtuZXgoKSBtZXRob2QuXG5Nb2RlbC5rbmV4KGtuZXgpO1xuIiwiaW1wb3J0IGVycm9ySGFuZGxlciBmcm9tICdlcnJvcmhhbmRsZXInO1xuaW1wb3J0IGFwcCBmcm9tICdAL2FwcCc7XG5cbmFwcC51c2UoZXJyb3JIYW5kbGVyKTtcblxuY29uc3Qgc2VydmVyID0gYXBwLmxpc3RlbihhcHAuZ2V0KCdwb3J0JyksICgpID0+IHtcbiAgY29uc29sZS5sb2coXG4gICAgJyAgQXBwIGlzIHJ1bm5pbmcgYXQgaHR0cDovL2xvY2FsaG9zdDolZCBpbiAlcyBtb2RlJyxcbiAgICBhcHAuZ2V0KCdwb3J0JyksXG4gICAgYXBwLmdldCgnZW52JyksXG4gICk7XG4gIGNvbnNvbGUubG9nKCcgIFByZXNzIENUUkwtQyB0byBzdG9wJyk7XG59KTtcblxuZXhwb3J0IGRlZmF1bHQgc2VydmVyO1xuIiwiXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBKb3VybmFsRW50cnkge1xuICBjb25zdHJ1Y3RvcihlbnRyeSkge1xuICAgIGNvbnN0IGRlZmF1bHRzID0ge1xuICAgICAgY3JlZGl0OiAwLFxuICAgICAgZGViaXQ6IDAsXG4gICAgfTtcbiAgICB0aGlzLmVudHJ5ID0geyAuLi5kZWZhdWx0cywgLi4uZW50cnkgfTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgcGljayB9IGZyb20gJ2xvZGFzaCc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgSm91cm5hbEVudHJ5IGZyb20gJ0Avc2VydmljZXMvQWNjb3VudGluZy9Kb3VybmFsRW50cnknO1xuaW1wb3J0IEFjY291bnRUcmFuc2FjdGlvbiBmcm9tICdAL21vZGVscy9BY2NvdW50VHJhbnNhY3Rpb24nO1xuaW1wb3J0IEFjY291bnRCYWxhbmNlIGZyb20gJ0AvbW9kZWxzL0FjY291bnRCYWxhbmNlJztcbmltcG9ydCB7cHJvbWlzZVNlcmlhbH0gZnJvbSAnQC91dGlscyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEpvdXJuYWxQb3N0ZXIge1xuICAvKipcbiAgICogSm91cm5hbCBwb3N0ZXIgY29uc3RydWN0b3IuXG4gICAqL1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmVudHJpZXMgPSBbXTtcbiAgICB0aGlzLmJhbGFuY2VzQ2hhbmdlID0ge307XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIHRoZSBjcmVkaXQgZW50cnkgZm9yIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKiBAcGFyYW0ge0pvdXJuYWxFbnRyeX0gZW50cnkgLVxuICAgKi9cbiAgY3JlZGl0KGVudHJ5TW9kZWwpIHtcbiAgICBpZiAoZW50cnlNb2RlbCBpbnN0YW5jZW9mIEpvdXJuYWxFbnRyeSA9PT0gZmFsc2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIGVudHJ5IGlzIG5vdCBpbnN0YW5jZSBvZiBKb3VybmFsRW50cnkuJyk7XG4gICAgfVxuICAgIHRoaXMuZW50cmllcy5wdXNoKGVudHJ5TW9kZWwuZW50cnkpO1xuICAgIHRoaXMuc2V0QWNjb3VudEJhbGFuY2VDaGFuZ2UoZW50cnlNb2RlbC5lbnRyeSwgJ2NyZWRpdCcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlcyB0aGUgZGViaXQgZW50cnkgZm9yIHRoZSBnaXZlbiBhY2NvdW50LlxuICAgKiBAcGFyYW0ge0pvdXJuYWxFbnRyeX0gZW50cnkgLVxuICAgKi9cbiAgZGViaXQoZW50cnlNb2RlbCkge1xuICAgIGlmIChlbnRyeU1vZGVsIGluc3RhbmNlb2YgSm91cm5hbEVudHJ5ID09PSBmYWxzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgZW50cnkgaXMgbm90IGluc3RhbmNlIG9mIEpvdXJuYWxFbnRyeS4nKTtcbiAgICB9XG4gICAgdGhpcy5lbnRyaWVzLnB1c2goZW50cnlNb2RlbC5lbnRyeSk7XG4gICAgdGhpcy5zZXRBY2NvdW50QmFsYW5jZUNoYW5nZShlbnRyeU1vZGVsLmVudHJ5LCAnZGViaXQnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIGFjY291bnQgYmFsYW5jZSBjaGFuZ2UuXG4gICAqIEBwYXJhbSB7Sm91cm5hbEVudHJ5fSBlbnRyeVxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICAgKi9cbiAgc2V0QWNjb3VudEJhbGFuY2VDaGFuZ2UoZW50cnksIHR5cGUpIHtcbiAgICBpZiAoIXRoaXMuYmFsYW5jZXNDaGFuZ2VbZW50cnkuYWNjb3VudF0pIHtcbiAgICAgIHRoaXMuYmFsYW5jZXNDaGFuZ2VbZW50cnkuYWNjb3VudF0gPSAwO1xuICAgIH1cbiAgICBsZXQgY2hhbmdlID0gMDtcblxuICAgIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnY3JlZGl0Jykge1xuICAgICAgY2hhbmdlID0gKHR5cGUgPT09ICdjcmVkaXQnKSA/IGVudHJ5LmNyZWRpdCA6IC0xICogZW50cnkuZGViaXQ7XG4gICAgfSBlbHNlIGlmIChlbnRyeS5hY2NvdW50Tm9ybWFsID09PSAnZGViaXQnKSB7XG4gICAgICBjaGFuZ2UgPSAodHlwZSA9PT0gJ2RlYml0JykgPyBlbnRyeS5kZWJpdCA6IC0xICogZW50cnkuY3JlZGl0O1xuICAgIH1cbiAgICB0aGlzLmJhbGFuY2VzQ2hhbmdlW2VudHJ5LmFjY291bnRdICs9IGNoYW5nZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXBwaW5nIHRoZSBiYWxhbmNlIGNoYW5nZSB0byBsaXN0LlxuICAgKi9cbiAgbWFwQmFsYW5jZUNoYW5nZXNUb0xpc3QoKSB7XG4gICAgY29uc3QgbWFwcGVkTGlzdCA9IFtdO1xuXG4gICAgT2JqZWN0LmtleXModGhpcy5iYWxhbmNlc0NoYW5nZSkuZm9yRWFjaCgoYWNjb3VudElkKSA9PiB7XG4gICAgICBjb25zdCBiYWxhbmNlID0gdGhpcy5iYWxhbmNlc0NoYW5nZVthY2NvdW50SWRdO1xuXG4gICAgICBtYXBwZWRMaXN0LnB1c2goe1xuICAgICAgICBhY2NvdW50X2lkOiBhY2NvdW50SWQsXG4gICAgICAgIGFtb3VudDogYmFsYW5jZSxcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBtYXBwZWRMaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBiYWxhbmNlIGNoYW5nZSBvZiBqb3VybmFsIGVudHJpZXMuXG4gICAqL1xuICBhc3luYyBzYXZlQmFsYW5jZSgpIHtcbiAgICBjb25zdCBiYWxhbmNlc0xpc3QgPSB0aGlzLm1hcEJhbGFuY2VDaGFuZ2VzVG9MaXN0KCk7XG4gICAgY29uc3QgYmFsYW5jZVVwZGF0ZU9wZXJzID0gW107XG4gICAgY29uc3QgYmFsYW5jZUluc2VydE9wZXJzID0gW107XG4gICAgY29uc3QgYmFsYW5jZUZpbmRPbmVPcGVycyA9IFtdO1xuICAgIGxldCBiYWxhbmNlQWNjb3VudHMgPSBbXTtcblxuICAgIGJhbGFuY2VzTGlzdC5mb3JFYWNoKChiYWxhbmNlKSA9PiB7XG4gICAgICBjb25zdCBvcGVyID0gQWNjb3VudEJhbGFuY2UucXVlcnkoKS5maW5kT25lKCdhY2NvdW50X2lkJywgYmFsYW5jZS5hY2NvdW50X2lkKTtcbiAgICAgIGJhbGFuY2VGaW5kT25lT3BlcnMucHVzaChvcGVyKTtcbiAgICB9KTtcbiAgICBiYWxhbmNlQWNjb3VudHMgPSBhd2FpdCBQcm9taXNlLmFsbChiYWxhbmNlRmluZE9uZU9wZXJzKTtcblxuICAgIGJhbGFuY2VzTGlzdC5mb3JFYWNoKChiYWxhbmNlKSA9PiB7XG4gICAgICBjb25zdCBtZXRob2QgPSBiYWxhbmNlLmFtb3VudCA8IDAgPyAnZGVjcmVtZW50JyA6ICdpbmNyZW1lbnQnO1xuXG4gICAgICAvLyBEZXRhcm1pbmUgaWYgdGhlIGFjY291bnQgYmFsYW5jZSBpcyBhbHJlYWR5IGV4aXN0cyBvciBub3QuXG4gICAgICBjb25zdCBmb3VuZEFjY0JhbGFuY2UgPSBiYWxhbmNlQWNjb3VudHMuc29tZSgoYWNjb3VudCkgPT4gKFxuICAgICAgICBhY2NvdW50ICYmIGFjY291bnQuYWNjb3VudF9pZCA9PT0gYmFsYW5jZS5hY2NvdW50X2lkXG4gICAgICApKTtcbiAgICAgIGlmIChmb3VuZEFjY0JhbGFuY2UpIHtcbiAgICAgICAgY29uc3QgcXVlcnkgPSBBY2NvdW50QmFsYW5jZVxuICAgICAgICAgIC5xdWVyeSgpW21ldGhvZF0oJ2Ftb3VudCcsIE1hdGguYWJzKGJhbGFuY2UuYW1vdW50KSlcbiAgICAgICAgICAud2hlcmUoJ2FjY291bnRfaWQnLCBiYWxhbmNlLmFjY291bnRfaWQpO1xuXG4gICAgICAgIGJhbGFuY2VVcGRhdGVPcGVycy5wdXNoKHF1ZXJ5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHF1ZXJ5ID0gQWNjb3VudEJhbGFuY2UucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICAgIGFjY291bnRfaWQ6IGJhbGFuY2UuYWNjb3VudF9pZCxcbiAgICAgICAgICBhbW91bnQ6IGJhbGFuY2UuYW1vdW50LFxuICAgICAgICAgIGN1cnJlbmN5X2NvZGU6ICdVU0QnLFxuICAgICAgICB9KTtcbiAgICAgICAgYmFsYW5jZUluc2VydE9wZXJzLnB1c2gocXVlcnkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIC4uLmJhbGFuY2VVcGRhdGVPcGVycywgLi4uYmFsYW5jZUluc2VydE9wZXJzLFxuICAgIF0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFNhdmVzIHRoZSBzdGFja2VkIGpvdXJuYWwgZW50cmllcyB0byB0aGUgc3RvcmFnZS5cbiAgICovXG4gIGFzeW5jIHNhdmVFbnRyaWVzKCkge1xuICAgIGNvbnN0IHNhdmVPcGVyYXRpb25zID0gW107XG5cbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIGNvbnN0IG9wZXIgPSBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKS5pbnNlcnQoe1xuICAgICAgICBhY2NvdW50SWQ6IGVudHJ5LmFjY291bnQsXG4gICAgICAgIC4uLnBpY2soZW50cnksIFsnY3JlZGl0JywgJ2RlYml0JywgJ3RyYW5zYWN0aW9uVHlwZScsICdkYXRlJywgJ3VzZXJJZCcsXG4gICAgICAgICAgJ3JlZmVyZW5jZVR5cGUnLCAncmVmZXJlbmNlSWQnLCAnbm90ZSddKSxcbiAgICAgIH0pO1xuICAgICAgc2F2ZU9wZXJhdGlvbnMucHVzaCgoKSA9PiBvcGVyKTtcbiAgICB9KTtcbiAgICBhd2FpdCBwcm9taXNlU2VyaWFsKHNhdmVPcGVyYXRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXZlcnNlcyB0aGUgc3RhY2tlZCBqb3VybmFsIGVudHJpZXMuXG4gICAqL1xuICByZXZlcnNlRW50cmllcygpIHtcbiAgICBjb25zdCByZXZlcnNlRW50cmllcyA9IFtdO1xuXG4gICAgdGhpcy5lbnRyaWVzLmZvckVhY2goKGVudHJ5KSA9PiB7XG4gICAgICBjb25zdCByZXZlcnNlRW50cnkgPSB7IC4uLmVudHJ5IH07XG5cbiAgICAgIGlmIChlbnRyeS5jcmVkaXQpIHtcbiAgICAgICAgcmV2ZXJzZUVudHJ5LmRlYml0ID0gZW50cnkuY3JlZGl0O1xuICAgICAgfVxuICAgICAgaWYgKGVudHJ5LmRlYml0KSB7XG4gICAgICAgIHJldmVyc2VFbnRyeS5jcmVkaXQgPSBlbnRyeS5kZWJpdDtcbiAgICAgIH1cbiAgICAgIHJldmVyc2VFbnRyaWVzLnB1c2gocmV2ZXJzZUVudHJ5KTtcbiAgICB9KTtcbiAgICB0aGlzLmVudHJpZXMgPSByZXZlcnNlRW50cmllcztcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWxldGUgdGhlIGdpdmVuIG9yIGFsbCBzdGFja2VkIGVudHJpZXMuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGlkcyAtXG4gICAqL1xuICBhc3luYyBkZWxldGVFbnRyaWVzKGlkcykge1xuICAgIGNvbnN0IGVudHJpZXNJZHMgPSBpZHMgfHwgdGhpcy5lbnRyaWVzLm1hcCgoZSkgPT4gZS5pZCk7XG5cbiAgICBpZiAoZW50cmllc0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICBhd2FpdCBBY2NvdW50VHJhbnNhY3Rpb24ucXVlcnkoKS53aGVyZUluKCdpZCcsIGVudHJpZXNJZHMpLmRlbGV0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgY2xvc2luZyBiYWxhbmNlIGZvciB0aGUgZ2l2ZW4gYWNjb3VudCBhbmQgY2xvc2luZyBkYXRlLlxuICAgKiBAcGFyYW0ge051bWJlcn0gYWNjb3VudElkIC1cbiAgICogQHBhcmFtIHtEYXRlfSBjbG9zaW5nRGF0ZSAtXG4gICAqL1xuICBnZXRDbG9zaW5nQmFsYW5jZShhY2NvdW50SWQsIGNsb3NpbmdEYXRlLCBkYXRlVHlwZSA9ICdkYXknKSB7XG4gICAgbGV0IGNsb3NpbmdCYWxhbmNlID0gMDtcbiAgICBjb25zdCBtb21lbnRDbG9zaW5nRGF0ZSA9IG1vbWVudChjbG9zaW5nRGF0ZSk7XG5cbiAgICB0aGlzLmVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIC8vIENhbiBub3QgY29udGludWUgaWYgbm90IGJlZm9yZSBvciBldmVudCBzYW1lIGNsb3NpbmcgZGF0ZS5cbiAgICAgIGlmICgoIW1vbWVudENsb3NpbmdEYXRlLmlzQWZ0ZXIoZW50cnkuZGF0ZSwgZGF0ZVR5cGUpXG4gICAgICAgICYmICFtb21lbnRDbG9zaW5nRGF0ZS5pc1NhbWUoZW50cnkuZGF0ZSwgZGF0ZVR5cGUpKVxuICAgICAgICB8fCAoZW50cnkuYWNjb3VudCAhPT0gYWNjb3VudElkICYmIGFjY291bnRJZCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGVudHJ5LmFjY291bnROb3JtYWwgPT09ICdjcmVkaXQnKSB7XG4gICAgICAgIGNsb3NpbmdCYWxhbmNlICs9IChlbnRyeS5jcmVkaXQpID8gZW50cnkuY3JlZGl0IDogLTEgKiBlbnRyeS5kZWJpdDtcbiAgICAgIH0gZWxzZSBpZiAoZW50cnkuYWNjb3VudE5vcm1hbCA9PT0gJ2RlYml0Jykge1xuICAgICAgICBjbG9zaW5nQmFsYW5jZSArPSAoZW50cnkuZGViaXQpID8gZW50cnkuZGViaXQgOiAtMSAqIGVudHJ5LmNyZWRpdDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY2xvc2luZ0JhbGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIGNyZWRpdC9kZWJpdCBzdW1hdGlvbiBmb3IgdGhlIGdpdmVuIGFjY291bnQgYW5kIGRhdGUuXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBhY2NvdW50IC1cbiAgICogQHBhcmFtIHtEYXRlfFN0cmluZ30gY2xvc2luZ0RhdGUgLVxuICAgKi9cbiAgZ2V0VHJpYWxCYWxhbmNlKGFjY291bnRJZCwgY2xvc2luZ0RhdGUsIGRhdGVUeXBlKSB7XG4gICAgY29uc3QgbW9tZW50Q2xvc2luZ0RhdGUgPSBtb21lbnQoY2xvc2luZ0RhdGUpO1xuICAgIGNvbnN0IHJlc3VsdCA9IHtcbiAgICAgIGNyZWRpdDogMCxcbiAgICAgIGRlYml0OiAwLFxuICAgICAgYmFsYW5jZTogMCxcbiAgICB9O1xuICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKCghbW9tZW50Q2xvc2luZ0RhdGUuaXNBZnRlcihlbnRyeS5kYXRlLCBkYXRlVHlwZSlcbiAgICAgICAgJiYgIW1vbWVudENsb3NpbmdEYXRlLmlzU2FtZShlbnRyeS5kYXRlLCBkYXRlVHlwZSkpXG4gICAgICAgIHx8IChlbnRyeS5hY2NvdW50ICE9PSBhY2NvdW50SWQgJiYgYWNjb3VudElkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICByZXN1bHQuY3JlZGl0ICs9IGVudHJ5LmNyZWRpdDtcbiAgICAgIHJlc3VsdC5kZWJpdCArPSBlbnRyeS5kZWJpdDtcblxuICAgICAgaWYgKGVudHJ5LmFjY291bnROb3JtYWwgPT09ICdjcmVkaXQnKSB7XG4gICAgICAgIHJlc3VsdC5iYWxhbmNlICs9IChlbnRyeS5jcmVkaXQpID8gZW50cnkuY3JlZGl0IDogLTEgKiBlbnRyeS5kZWJpdDtcbiAgICAgIH0gZWxzZSBpZiAoZW50cnkuYWNjb3VudE5vcm1hbCA9PT0gJ2RlYml0Jykge1xuICAgICAgICByZXN1bHQuYmFsYW5jZSArPSAoZW50cnkuZGViaXQpID8gZW50cnkuZGViaXQgOiAtMSAqIGVudHJ5LmNyZWRpdDtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgZmV0Y2hlZCBhY2NvdW50cyBqb3VybmFsIGVudHJpZXMuXG4gICAqIEBwYXJhbSB7QXJyYXl9IGVudHJpZXMgLVxuICAgKi9cbiAgbG9hZEVudHJpZXMoZW50cmllcykge1xuICAgIGVudHJpZXMuZm9yRWFjaCgoZW50cnkpID0+IHtcbiAgICAgIHRoaXMuZW50cmllcy5wdXNoKHtcbiAgICAgICAgLi4uZW50cnksXG4gICAgICAgIGFjY291bnQ6IGVudHJ5LmFjY291bnQgPyBlbnRyeS5hY2NvdW50LmlkIDogZW50cnkuYWNjb3VudElkLFxuICAgICAgICBhY2NvdW50Tm9ybWFsOiAoZW50cnkuYWNjb3VudCAmJiBlbnRyeS5hY2NvdW50LnR5cGUpXG4gICAgICAgICAgPyBlbnRyeS5hY2NvdW50LnR5cGUubm9ybWFsIDogZW50cnkuYWNjb3VudE5vcm1hbCxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGxvYWRBY2NvdW50cygpIHtcblxuICB9XG59XG4iLCJpbXBvcnQgUmVzb3VyY2UgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2UnO1xuaW1wb3J0IFJlc291cmNlRmllbGQgZnJvbSAnQC9tb2RlbHMvUmVzb3VyY2VGaWVsZCc7XG5pbXBvcnQgUmVzb3VyY2VGaWVsZE1ldGFkYXRhIGZyb20gJ0AvbW9kZWxzL1Jlc291cmNlRmllbGRNZXRhZGF0YSc7XG5pbXBvcnQgUmVzb3VyY2VGaWVsZE1ldGFkYXRhQ29sbGVjdGlvbiBmcm9tICdAL2NvbGxlY3Rpb24vUmVzb3VyY2VGaWVsZE1ldGFkYXRhQ29sbGVjdGlvbic7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFJlc291cmNlQ3VzdG9tRmllbGRSZXBvc2l0b3J5IHtcbiAgLyoqXG4gICAqIENsYXNzIGNvbnN0cnVjdG9yLlxuICAgKi9cbiAgY29uc3RydWN0b3IobW9kZWwpIHtcbiAgICBpZiAodHlwZW9mIG1vZGVsID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aGlzLnJlc291cmNlTmFtZSA9IG1vZGVsLm5hbWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbW9kZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICB0aGlzLnJlc291cmNlTmFtZSA9IG1vZGVsO1xuICAgIH1cbiAgICAvLyBDdXN0b20gZmllbGRzIG9mIHRoZSBnaXZlbiByZXNvdXJjZS5cbiAgICB0aGlzLmN1c3RvbUZpZWxkcyA9IFtdO1xuICAgIHRoaXMuZmlsbGVkQ3VzdG9tRmllbGRzID0ge307XG5cbiAgICAvLyBtZXRhZGF0YSBvZiBjdXN0b20gZmllbGRzIG9mIHRoZSBnaXZlbiByZXNvdXJjZS5cbiAgICB0aGlzLmZpZWxkc01ldGFkYXRhID0ge307XG4gICAgdGhpcy5yZXNvdXJjZSA9IHt9O1xuICB9XG5cbiAgLyoqXG4gICAqIEZldGNoZXMgbWV0YWRhdGEgb2YgY3VzdG9tIGZpZWxkcyBvZiB0aGUgZ2l2ZW4gcmVzb3VyY2UuXG4gICAqIEBwYXJhbSB7SW50ZWdlcn0gaWQgLSBSZXNvdXJjZSBpdGVtIGlkLlxuICAgKi9cbiAgYXN5bmMgZmV0Y2hDdXN0b21GaWVsZHNNZXRhZGF0YShpZCkge1xuICAgIGlmICh0eXBlb2YgaWQgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BsZWFzZSBkZWZpbmUgdGhlIHJlc291cmNlIGl0ZW0gaWQuJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5yZXNvdXJjZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUYXJnZXQgcmVzb3VyY2UgbW9kZWwgaXMgbm90IGZvdW5kLicpO1xuICAgIH1cbiAgICBjb25zdCBtZXRhZGF0YSA9IGF3YWl0IFJlc291cmNlRmllbGRNZXRhZGF0YS5xdWVyeSgpXG4gICAgICAud2hlcmUoJ3Jlc291cmNlX2lkJywgdGhpcy5yZXNvdXJjZS5pZClcbiAgICAgIC53aGVyZSgncmVzb3VyY2VfaXRlbV9pZCcsIGlkKTtcblxuICAgIHRoaXMuZmllbGRzTWV0YWRhdGFbaWRdID0gbWV0YWRhdGE7XG4gIH1cblxuICAvKipcbiAgICogTG9hZCByZXNvdXJjZS5cbiAgICovXG4gIGFzeW5jIGxvYWRSZXNvdXJjZSgpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IGF3YWl0IFJlc291cmNlLnF1ZXJ5KCkud2hlcmUoJ25hbWUnLCB0aGlzLnJlc291cmNlTmFtZSkuZmlyc3QoKTtcblxuICAgIGlmICghcmVzb3VyY2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgaXMgbm8gc3RvcmVkIHJlc291cmNlIGluIHRoZSBzdG9yYWdlIHdpdGggdGhlIGdpdmVuIG1vZGVsIG5hbWUuJyk7XG4gICAgfVxuICAgIHRoaXMuc2V0UmVzb3VyY2UocmVzb3VyY2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIExvYWQgbWV0YWRhdGEgb2YgdGhlIHJlc291cmNlLlxuICAgKi9cbiAgYXN5bmMgbG9hZFJlc291cmNlQ3VzdG9tRmllbGRzKCkge1xuICAgIGlmICh0eXBlb2YgdGhpcy5yZXNvdXJjZS5pZCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignUGxlYXNlIGZldGNoIHJlc291cmNlIGRldGFpbHMgYmVmb3JlIGZldGNoIGN1c3RvbSBmaWVsZHMgb2YgdGhlIHJlc291cmNlLicpO1xuICAgIH1cbiAgICBjb25zdCBjdXN0b21GaWVsZHMgPSBhd2FpdCBSZXNvdXJjZUZpZWxkLnF1ZXJ5KClcbiAgICAgIC53aGVyZSgncmVzb3VyY2VfaWQnLCB0aGlzLnJlc291cmNlLmlkKVxuICAgICAgLm1vZGlmeSgnd2hlcmVOb3RQcmVkZWZpbmVkJyk7XG5cbiAgICB0aGlzLnNldFJlc291cmNlQ3VzdG9tRmllbGRzKGN1c3RvbUZpZWxkcyk7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyByZXNvdXJjZSBtb2RlbC5cbiAgICogQHBhcmFtIHtSZXNvdXJjZX0gcmVzb3VyY2UgLVxuICAgKi9cbiAgc2V0UmVzb3VyY2UocmVzb3VyY2UpIHtcbiAgICB0aGlzLnJlc291cmNlID0gcmVzb3VyY2U7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyByZXNvdXJjZSBjdXN0b20gZmllbGRzIGNvbGxlY3Rpb24uXG4gICAqIEBwYXJhbSB7QXJyYXl9IGN1c3RvbUZpZWxkcyAtXG4gICAqL1xuICBzZXRSZXNvdXJjZUN1c3RvbUZpZWxkcyhjdXN0b21GaWVsZHMpIHtcbiAgICB0aGlzLmN1c3RvbUZpZWxkcyA9IGN1c3RvbUZpZWxkcztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSBtZXRhZGF0YSBvZiB0aGUgcmVzb3VyY2UgY3VzdG9tIGZpZWxkcy5cbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBpdGVtSWQgLVxuICAgKi9cbiAgZ2V0TWV0YWRhdGEoaXRlbUlkKSB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGRzTWV0YWRhdGFbaXRlbUlkXSB8fCB0aGlzLmZpZWxkc01ldGFkYXRhO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbGwgbWV0YWRhdGEgb2YgdGhlIGN1c3RvbSBmaWVsZHMgdGhhdCBhc3NvY2lhdGVkIHRvIHRoZSByZXNvdXJjZS5cbiAgICogQHBhcmFtIHtJbnRlcn0gaWQgLSBSZXNvdXJjZSBpdGVtIGlkLlxuICAgKiBAcGFyYW0ge0FycmF5fSBhdHRyaWJ1dGVzIC1cbiAgICovXG4gIGZpbGxDdXN0b21GaWVsZHMoaWQsIGF0dHJpYnV0ZXMpIHtcbiAgICBpZiAodHlwZW9mIHRoaXMuZmlsbGVkQ3VzdG9tRmllbGRzW2lkXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMuZmlsbGVkQ3VzdG9tRmllbGRzW2lkXSA9IFtdO1xuICAgIH1cbiAgICBhdHRyaWJ1dGVzLmZvckVhY2goKGF0dHIpID0+IHtcbiAgICAgIHRoaXMuZmlsbGVkQ3VzdG9tRmllbGRzW2lkXS5wdXNoKGF0dHIpO1xuXG4gICAgICBpZiAoIXRoaXMuZmllbGRzTWV0YWRhdGFbaWRdKSB7XG4gICAgICAgIHRoaXMuZmllbGRzTWV0YWRhdGFbaWRdID0gbmV3IFJlc291cmNlRmllbGRNZXRhZGF0YUNvbGxlY3Rpb24oKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZmllbGRzTWV0YWRhdGFbaWRdLnNldE1ldGEoYXR0ci5rZXksIGF0dHIudmFsdWUsIHtcbiAgICAgICAgcmVzb3VyY2VfaWQ6IHRoaXMucmVzb3VyY2UuaWQsXG4gICAgICAgIHJlc291cmNlX2l0ZW1faWQ6IGlkLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU2F2ZXMgdGhlIGluc3RlcmVkLCB1cGRhdGVkIGFuZCBkZWxldGVkICBjdXN0b20gZmllbGRzIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge0ludGVnZXJ9IGlkIC0gT3B0aW9uYWwgcmVzb3VyY2UgaXRlbSBpZC5cbiAgICovXG4gIGFzeW5jIHNhdmVDdXN0b21GaWVsZHMoaWQpIHtcbiAgICBpZiAoaWQpIHtcbiAgICAgIGlmICh0eXBlb2YgdGhpcy5maWVsZHNNZXRhZGF0YVtpZF0gPT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignVGhlcmUgaXMgbm8gcmVzb3VyY2UgaXRlbSB3aXRoIHRoZSBnaXZlbiBpZC4nKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMuZmllbGRzTWV0YWRhdGFbaWRdLnNhdmVNZXRhKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG9wZXJzID0gW107XG4gICAgICB0aGlzLmZpZWxkc01ldGFkYXRhLmZvckVhY2goKG1ldGFkYXRhKSA9PiB7XG4gICAgICAgIGNvbnN0IG9wZXIgPSBtZXRhZGF0YS5zYXZlTWV0YSgpO1xuICAgICAgICBvcGVycy5wdXNoKG9wZXIpO1xuICAgICAgfSk7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChvcGVycyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyB0aGUgZXhpc3QgY3VzdG9tIGZpZWxkcy5cbiAgICovXG4gIHZhbGlkYXRlRXhpc3RDdXN0b21GaWVsZHMoKSB7XG5cbiAgfVxuXG4gIHRvQXJyYXkoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGRzTWV0YWRhdGEudG9BcnJheSgpO1xuICB9XG5cbiAgYXN5bmMgbG9hZCgpIHtcbiAgICBhd2FpdCB0aGlzLmxvYWRSZXNvdXJjZSgpO1xuICAgIGF3YWl0IHRoaXMubG9hZFJlc291cmNlQ3VzdG9tRmllbGRzKCk7XG4gIH1cblxuICBzdGF0aWMgZm9yZ2VNZXRhZGF0YUNvbGxlY3Rpb24oKSB7XG5cbiAgfVxufVxuIiwiaW1wb3J0IE1vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHsgZXh0ZW5kTW9tZW50IH0gZnJvbSAnbW9tZW50LXJhbmdlJztcblxuY29uc3QgbW9tZW50ID0gZXh0ZW5kTW9tZW50KE1vbWVudCk7XG5cbmV4cG9ydCBkZWZhdWx0IG1vbWVudDtcbiIsImltcG9ydCBub2RlbWFpbGVyIGZyb20gJ25vZGVtYWlsZXInO1xuXG4vLyBjcmVhdGUgcmV1c2FibGUgdHJhbnNwb3J0ZXIgb2JqZWN0IHVzaW5nIHRoZSBkZWZhdWx0IFNNVFAgdHJhbnNwb3J0XG5jb25zdCB0cmFuc3BvcnRlciA9IG5vZGVtYWlsZXIuY3JlYXRlVHJhbnNwb3J0KHtcbiAgaG9zdDogcHJvY2Vzcy5lbnYuTUFJTF9IT1NULFxuICBwb3J0OiBOdW1iZXIocHJvY2Vzcy5lbnYuTUFJTF9QT1JUKSxcbiAgc2VjdXJlOiBwcm9jZXNzLmVudi5NQUlMX1NFQ1VSRSA9PT0gJ3RydWUnLCAvLyB0cnVlIGZvciA0NjUsIGZhbHNlIGZvciBvdGhlciBwb3J0c1xuICBhdXRoOiB7XG4gICAgdXNlcjogcHJvY2Vzcy5lbnYuTUFJTF9VU0VSTkFNRSxcbiAgICBwYXNzOiBwcm9jZXNzLmVudi5NQUlMX1BBU1NXT1JELFxuICB9LFxufSk7XG5cbmV4cG9ydCBkZWZhdWx0IHRyYW5zcG9ydGVyO1xuIiwiaW1wb3J0IGJjcnlwdCBmcm9tICdiY3J5cHRqcyc7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5pbXBvcnQgXyBmcm9tICdsb2Rhc2gnO1xuY29uc3QgeyBtYXAsIGlzQXJyYXksIGlzUGxhaW5PYmplY3QsIG1hcEtleXMsIG1hcFZhbHVlcyB9ID0gcmVxdWlyZSgnbG9kYXNoJylcblxuXG5jb25zdCBoYXNoUGFzc3dvcmQgPSAocGFzc3dvcmQpID0+IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG4gIGJjcnlwdC5nZW5TYWx0KDEwLCAoZXJyb3IsIHNhbHQpID0+IHtcbiAgICBiY3J5cHQuaGFzaChwYXNzd29yZCwgc2FsdCwgKGVyciwgaGFzaCkgPT4geyByZXNvbHZlKGhhc2gpOyB9KTtcbiAgfSk7XG59KTtcblxuY29uc3Qgb3JpZ2luID0gKHJlcXVlc3QpID0+IGAke3JlcXVlc3QucHJvdG9jb2x9Oi8vJHtyZXF1ZXN0Lmhvc3RuYW1lfWA7XG5cbmNvbnN0IGRhdGVSYW5nZUNvbGxlY3Rpb24gPSAoZnJvbURhdGUsIHRvRGF0ZSwgYWRkVHlwZSA9ICdkYXknLCBpbmNyZW1lbnQgPSAxKSA9PiB7XG4gIGNvbnN0IGNvbGxlY3Rpb24gPSBbXTtcbiAgY29uc3QgbW9tZW50RnJvbURhdGUgPSBtb21lbnQoZnJvbURhdGUpO1xuICBsZXQgZGF0ZUZvcm1hdCA9ICcnO1xuXG4gIHN3aXRjaCAoYWRkVHlwZSkge1xuICAgIGNhc2UgJ2RheSc6XG4gICAgZGVmYXVsdDpcbiAgICAgIGRhdGVGb3JtYXQgPSAnWVlZWS1NTS1ERCc7IGJyZWFrO1xuICAgIGNhc2UgJ21vbnRoJzpcbiAgICBjYXNlICdxdWFydGVyJzpcbiAgICAgIGRhdGVGb3JtYXQgPSAnWVlZWS1NTSc7IGJyZWFrO1xuICAgIGNhc2UgJ3llYXInOlxuICAgICAgZGF0ZUZvcm1hdCA9ICdZWVlZJzsgYnJlYWs7XG4gIH1cbiAgZm9yIChsZXQgaSA9IG1vbWVudEZyb21EYXRlO1xuICAgIChpLmlzQmVmb3JlKHRvRGF0ZSwgYWRkVHlwZSkgfHwgaS5pc1NhbWUodG9EYXRlLCBhZGRUeXBlKSk7XG4gICAgaS5hZGQoaW5jcmVtZW50LCBgJHthZGRUeXBlfXNgKSkge1xuICAgIGNvbGxlY3Rpb24ucHVzaChpLmVuZE9mKGFkZFR5cGUpLmZvcm1hdChkYXRlRm9ybWF0KSk7XG4gIH1cbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59O1xuXG5jb25zdCBkYXRlUmFuZ2VGb3JtYXQgPSAocmFuZ2VUeXBlKSA9PiB7XG4gIHN3aXRjaCAocmFuZ2VUeXBlKSB7XG4gICAgY2FzZSAneWVhcic6XG4gICAgICByZXR1cm4gJ1lZWVknO1xuICAgIGNhc2UgJ21vbnRoJzpcbiAgICBjYXNlICdxdWFydGVyJzpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICdZWVlZLU1NJztcbiAgfVxufTtcblxuXG5jb25zdCBtYXBLZXlzRGVlcCA9IChvYmosIGNiKSA9PiB7XG4gIGlmIChfLmlzQXJyYXkob2JqKSkge1xuICAgICAgcmV0dXJuIG9iai5tYXAoaW5uZXJPYmogPT4gbWFwS2V5c0RlZXAoaW5uZXJPYmosIGNiKSk7XG4gIH1cbiAgZWxzZSBpZiAoXy5pc09iamVjdChvYmopKSB7XG4gICAgICByZXR1cm4gXy5tYXBWYWx1ZXMoXG4gICAgICAgICAgXy5tYXBLZXlzKG9iaiwgY2IpLFxuICAgICAgICAgIHZhbCA9PiBtYXBLZXlzRGVlcCh2YWwsIGNiKSxcbiAgICAgIClcbiAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBvYmo7XG4gIH1cbn1cblxuY29uc3QgbWFwVmFsdWVzRGVlcCA9ICh2LCBjYWxsYmFjaykgPT4gKFxuICBfLmlzT2JqZWN0KHYpXG4gICAgPyBfLm1hcFZhbHVlcyh2LCB2ID0+IG1hcFZhbHVlc0RlZXAodiwgY2FsbGJhY2spKVxuICAgIDogY2FsbGJhY2sodikpO1xuXG5cbmNvbnN0IHByb21pc2VTZXJpYWwgPSAoZnVuY3MpID0+IHtcbiAgcmV0dXJuIGZ1bmNzLnJlZHVjZSgocHJvbWlzZSwgZnVuYykgPT4gcHJvbWlzZS50aGVuKChyZXN1bHQpID0+IGZ1bmMoKS50aGVuKEFycmF5LnByb3RvdHlwZS5jb25jYXQuYmluZChyZXN1bHQpKSksXG4gICAgUHJvbWlzZS5yZXNvbHZlKFtdKSk7XG59XG5cbmV4cG9ydCB7XG4gIGhhc2hQYXNzd29yZCxcbiAgb3JpZ2luLFxuICBkYXRlUmFuZ2VDb2xsZWN0aW9uLFxuICBkYXRlUmFuZ2VGb3JtYXQsXG4gIG1hcFZhbHVlc0RlZXAsXG4gIG1hcEtleXNEZWVwLFxuICBwcm9taXNlU2VyaWFsLFxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9wbHVnaW4tdHJhbnNmb3JtLXJ1bnRpbWVcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9hc3luY1RvR2VuZXJhdG9yXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvY2xhc3NDYWxsQ2hlY2tcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9jcmVhdGVDbGFzc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL2RlZmluZVByb3BlcnR5XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvZ2V0UHJvdG90eXBlT2ZcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9pbmhlcml0c1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJAYmFiZWwvcnVudGltZS9oZWxwZXJzL3Bvc3NpYmxlQ29uc3RydWN0b3JSZXR1cm5cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvaGVscGVycy9zbGljZWRUb0FycmF5XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIkBiYWJlbC9ydW50aW1lL2hlbHBlcnMvdG9Db25zdW1hYmxlQXJyYXlcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiQGJhYmVsL3J1bnRpbWUvcmVnZW5lcmF0b3JcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiYmNyeXB0anNcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiZG90ZW52XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImVycm9yaGFuZGxlclwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJleHByZXNzXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcImV4cHJlc3MtYm9vbVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJleHByZXNzLXZhbGlkYXRvclwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJmc1wiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJoZWxtZXRcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwiaTE4blwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJqc29ud2VidG9rZW5cIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwia25leFwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJsb2Rhc2hcIik7IiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKFwibW9tZW50XCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm1vbWVudC1yYW5nZVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJtdXN0YWNoZVwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJub2RlbWFpbGVyXCIpOyIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZShcIm9iamVjdGlvblwiKTsiLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCJwYXRoXCIpOyJdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUNsRkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2hEQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3hFQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7OztBQ1hBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNKQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNWQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQy9JQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUM3QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFwR0E7QUFzR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3pPQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBSUE7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBbkJBO0FBQ0E7QUFDQTtBQXFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ2hZQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDaE1BO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNsUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUE3RUE7QUErRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFUQTs7Ozs7Ozs7Ozs7O0FDNUdBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDdkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDWkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQU1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNsRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUlBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBaERBO0FBa0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTdEQTtBQUNBO0FBK0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXZGQTtBQXlGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3RmQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDdE9BO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDMWlCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDcExBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQW5DQTtBQXFDQTtBQUNBO0FBQ0E7QUF2Q0E7QUF5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDOVFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDdEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3pGQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFoSUE7QUFDQTtBQUNBO0FBQ0E7QUFrSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDdlZBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDUkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQy9PQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDdlFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNwREE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ1JBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2ZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFEQTtBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUEzQkE7QUErQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBOUVBO0FBbUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUF2RkE7QUE0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXRHQTtBQXdHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBbEhBO0FBb0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFqSUE7QUFtSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzS0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUM3SkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTBCQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFwRUE7QUF3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNqUEE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FBTUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUFNQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDeEZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBekVBOztBQU9BOztBQWdCQTs7QUFTQTs7QUFZQTs7QUFZQTs7Ozs7Ozs7Ozs7O0FDbEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQzNCQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDL0VBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQy9CQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBcERBOztBQVdBOzs7Ozs7Ozs7Ozs7QUNqQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDNUZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDekNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7QUM3QkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ1JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDekJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFmQTtBQWtCQTtBQUNBOzs7Ozs7Ozs7Ozs7QUMzQkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBcEJBO0FBc0JBOzs7Ozs7Ozs7Ozs7O0FDdkNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ3BFQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQTNDQTs7QUFHQTs7QUFXQTs7QUFXQTs7QUFPQTs7QUFtQkE7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDbEVBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7O0FDckNBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDekZBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQTVDQTs7QUFPQTs7QUFPQTs7Ozs7Ozs7Ozs7O0FDdEJBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUN6REE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNmQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNoRUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDTkE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7QUNSQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FBS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2hQQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FBSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUFLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7Ozs7O0FDeEpBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ0xBO0FBQUE7QUFBQTtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7OztBQ2JBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FDekVBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7Ozs7Ozs7OztBQ0FBOzs7O0EiLCJzb3VyY2VSb290IjoiIn0= \ No newline at end of file diff --git a/server/package-lock.json b/server/package-lock.json index 795c59d81..398d78773 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -2228,14 +2228,6 @@ "object-visit": "^1.0.0" } }, - "collections": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/collections/-/collections-5.1.9.tgz", - "integrity": "sha512-omsKk7VkxuYKsxKG9jdyNtqTVJXZuwLnK53lc7M7AW4cXKcEyK3F+4cfQFVOy4ivT+UWhJlvClrJI7qF2Ts6iA==", - "requires": { - "weak-map": "~1.0.x" - } - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -3915,8 +3907,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "1.2.9", @@ -4788,6 +4779,26 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "i18n": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/i18n/-/i18n-0.8.5.tgz", + "integrity": "sha512-6UgLbhJGgn4XFeuZc/dDdrrri0ij24EK4hxv4Pbi5hloYAZ1B2+0eQchEryBFezLKYOHhVGV/5+H4i0oxng94w==", + "requires": { + "debug": "*", + "make-plural": "^6.0.1", + "math-interval-parser": "^2.0.1", + "messageformat": "^2.3.0", + "mustache": "*", + "sprintf-js": "^1.1.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -4869,7 +4880,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5570,6 +5580,36 @@ } } }, + "knex-db-manager": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/knex-db-manager/-/knex-db-manager-0.6.1.tgz", + "integrity": "sha512-H1IBb/zUwFXYyok8n/WmtRNV/DcZ77lV9qXqjpoF4otFPgf3W85/l79Dq/8gOE+0WnawLsYKXD8Hdz5VsaHIzQ==", + "requires": { + "bluebird": "^3.7.2", + "glob": "^7.1.6", + "lodash": "^4.17.15" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "knex-factory": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/knex-factory/-/knex-factory-0.0.6.tgz", @@ -5847,6 +5887,11 @@ "kind-of": "^6.0.2" } }, + "make-plural": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-6.1.0.tgz", + "integrity": "sha512-0ekbPHqxcdRcmjZ43TkRuejK5rXgMF1OjG4FVnVHgCvOcjrexaSX7a0dfAvqhOm1qWPgjYnXtmz3cHpHW5ZewA==" + }, "mamacro": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", @@ -5875,6 +5920,11 @@ "object-visit": "^1.0.0" } }, + "math-interval-parser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", + "integrity": "sha512-VmlAmb0UJwlvMyx8iPhXUDnVW1F9IrGEd9CIOmv+XL8AErCUUuozoDMrgImvnYt2A+53qVX/tPW6YJurMKYsvA==" + }, "md5.js": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", @@ -5939,6 +5989,42 @@ } } }, + "messageformat": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-2.3.0.tgz", + "integrity": "sha512-uTzvsv0lTeQxYI2y1NPa1lItL5VRI8Gb93Y2K2ue5gBPyrbJxfDi/EYWxh2PKv5yO42AJeeqblS9MJSh/IEk4w==", + "requires": { + "make-plural": "^4.3.0", + "messageformat-formatters": "^2.0.1", + "messageformat-parser": "^4.1.2" + }, + "dependencies": { + "make-plural": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", + "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", + "requires": { + "minimist": "^1.2.0" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "optional": true + } + } + }, + "messageformat-formatters": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/messageformat-formatters/-/messageformat-formatters-2.0.1.tgz", + "integrity": "sha512-E/lQRXhtHwGuiQjI7qxkLp8AHbMD5r2217XNe/SREbBlSawe0lOqsFb7rflZJmlQFSULNLIqlcjjsCPlB3m3Mg==" + }, + "messageformat-parser": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.2.tgz", + "integrity": "sha512-7dWuifeyldz7vhEuL96Kwq1fhZXBW+TUfbnHN4UCrCxoXQTYjHnR78eI66Gk9LaLLsAvzPNVJBaa66DRfFNaiA==" + }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -6944,7 +7030,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -9100,11 +9185,6 @@ "neo-async": "^2.5.0" } }, - "weak-map": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/weak-map/-/weak-map-1.0.5.tgz", - "integrity": "sha1-eWkVhNmGB/UHC9O3CkDmuyLkAes=" - }, "webpack": { "version": "4.39.2", "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.2.tgz", @@ -9556,8 +9636,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", diff --git a/server/package.json b/server/package.json index 0b5e6447a..6f919349c 100644 --- a/server/package.json +++ b/server/package.json @@ -29,8 +29,10 @@ "express-oauth-server": "^2.0.0", "express-validator": "^6.2.0", "helmet": "^3.21.0", + "i18n": "^0.8.5", "jsonwebtoken": "^8.5.1", "knex": "^0.20.3", + "knex-db-manager": "^0.6.1", "lodash": "^4.17.15", "memory-cache": "^0.2.0", "moment": "^2.24.0", diff --git a/server/src/app.js b/server/src/app.js index d7b76f077..55403acfc 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -1,12 +1,27 @@ import express from 'express'; import helmet from 'helmet'; import boom from 'express-boom'; +import i18n from 'i18n'; import '../config'; import routes from '@/http'; import '@/models'; const app = express(); +// i18n.configure({ +// // setup some locales - other locales default to en silently +// locales: ['en'], + +// // sets a custom cookie name to parse locale settings from. +// cookie: 'yourcookiename', + +// // where to store json files - defaults to './locales' +// directory: `${__dirname}/resources/locale`, +// }); + +// i18n init parses req for language headers, cookies, etc. +// app.use(i18n.init); + // Express configuration app.set('port', process.env.PORT || 3000); diff --git a/server/src/database/manager.js b/server/src/database/manager.js new file mode 100644 index 000000000..b42a3a3f0 --- /dev/null +++ b/server/src/database/manager.js @@ -0,0 +1,17 @@ +import knexManager from 'knex-db-manager'; +import knexfile from '@/../knexfile'; + +const config = knexfile[process.env.NODE_ENV]; + +const dbManager = knexManager.databaseManagerFactory({ + knex: config, + dbManager: { + // db manager related configuration + collate: [], + superUser: 'root', + superPassword: 'root', + // populatePathPattern: 'data/**/*.js', // glob format for searching seeds + }, +}); + +export default dbManager; \ No newline at end of file diff --git a/server/src/database/migrations/20190822214244_create_user_has_roles_table.js b/server/src/database/migrations/20190822214244_create_user_has_roles_table.js index 44f49755a..c35b826c4 100644 --- a/server/src/database/migrations/20190822214244_create_user_has_roles_table.js +++ b/server/src/database/migrations/20190822214244_create_user_has_roles_table.js @@ -2,8 +2,8 @@ exports.up = function (knex) { return knex.schema.createTable('user_has_roles', (table) => { table.increments(); - table.integer('user_id').unsigned().references('id').inTable('users'); - table.integer('role_id').unsigned().references('id').inTable('roles'); + table.integer('user_id').unsigned(); + table.integer('role_id').unsigned(); }); }; diff --git a/server/src/database/migrations/20190822214247_create_oauth_tokens_table.js b/server/src/database/migrations/20190822214247_create_oauth_tokens_table.js index f91d4a01a..0b7ded2ef 100644 --- a/server/src/database/migrations/20190822214247_create_oauth_tokens_table.js +++ b/server/src/database/migrations/20190822214247_create_oauth_tokens_table.js @@ -7,7 +7,7 @@ exports.up = function(knex) { table.integer('client_id').unsigned(); table.string('refresh_token'); table.date('refresh_token_expires_on'); - table.integer('user_id').unsigned().references('id').inTable('users'); + table.integer('user_id').unsigned(); }); }; diff --git a/server/src/database/migrations/20190822214302_create_settings_table.js b/server/src/database/migrations/20190822214302_create_settings_table.js index 57aeb37b3..bd7c0b43a 100644 --- a/server/src/database/migrations/20190822214302_create_settings_table.js +++ b/server/src/database/migrations/20190822214302_create_settings_table.js @@ -2,7 +2,7 @@ exports.up = function (knex) { return knex.schema.createTable('settings', (table) => { table.increments(); - table.integer('user_id').unsigned().references('id').inTable('users'); + table.integer('user_id').unsigned(); table.string('group'); table.string('type'); table.string('key'); diff --git a/server/src/database/migrations/20190822214905_create_resource_fields_table.js b/server/src/database/migrations/20190822214905_create_resource_fields_table.js index 9e01be943..d8fbe2d32 100644 --- a/server/src/database/migrations/20190822214905_create_resource_fields_table.js +++ b/server/src/database/migrations/20190822214905_create_resource_fields_table.js @@ -13,7 +13,7 @@ exports.up = function (knex) { table.boolean('columnable'); table.integer('index'); table.json('options'); - table.integer('resource_id').unsigned().references('id').inTable('resources'); + table.integer('resource_id').unsigned(); }); }; diff --git a/server/src/database/migrations/20190822214905_create_role_has_accounts.js b/server/src/database/migrations/20190822214905_create_role_has_accounts.js index e66e7df5e..6bc9c0d15 100644 --- a/server/src/database/migrations/20190822214905_create_role_has_accounts.js +++ b/server/src/database/migrations/20190822214905_create_role_has_accounts.js @@ -2,8 +2,8 @@ exports.up = function (knex) { return knex.schema.createTable('role_has_accounts', (table) => { table.increments(); - table.integer('role_id').unsigned().references('id').inTable('roles'); - table.integer('account_id').unsigned().references('id').inTable('accounts'); + table.integer('role_id').unsigned(); + table.integer('account_id').unsigned(); }); }; diff --git a/server/src/database/migrations/20190822214905_create_role_has_permissions.js b/server/src/database/migrations/20190822214905_create_role_has_permissions.js index 26e19e8be..d25020eab 100644 --- a/server/src/database/migrations/20190822214905_create_role_has_permissions.js +++ b/server/src/database/migrations/20190822214905_create_role_has_permissions.js @@ -2,9 +2,9 @@ exports.up = function (knex) { return knex.schema.createTable('role_has_permissions', (table) => { table.increments(); - table.integer('role_id').unsigned().references('id').inTable('roles'); - table.integer('permission_id').unsigned().references('id').inTable('permissions'); - table.integer('resource_id').unsigned().references('id').inTable('resources'); + table.integer('role_id').unsigned(); + table.integer('permission_id').unsigned(); + table.integer('resource_id').unsigned(); }); }; diff --git a/server/src/database/migrations/20190822214905_create_views_roles_table.js b/server/src/database/migrations/20190822214905_create_views_roles_table.js index c7a30b359..79a2bb0cd 100644 --- a/server/src/database/migrations/20190822214905_create_views_roles_table.js +++ b/server/src/database/migrations/20190822214905_create_views_roles_table.js @@ -3,7 +3,7 @@ exports.up = function (knex) { return knex.schema.createTable('view_roles', (table) => { table.increments(); table.integer('index'); - table.integer('field_id').unsigned().references('id').inTable('resource_fields'); + table.integer('field_id').unsigned(); table.string('comparator'); table.string('value'); table.integer('view_id').unsigned(); diff --git a/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js b/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js index 389472121..2ca5339e3 100644 --- a/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js +++ b/server/src/database/migrations/20200104232647_create_accounts_transactions_table.js @@ -7,10 +7,10 @@ exports.up = function(knex) { table.string('transaction_type'); table.string('reference_type'); table.integer('reference_id'); - table.integer('account_id').unsigned().references('id').inTable('accounts'); + table.integer('account_id').unsigned(); table.string('note'); table.boolean('draft').defaultTo(false); - table.integer('user_id').unsigned().references('id').inTable('users'); + table.integer('user_id').unsigned(); table.date('date'); table.timestamps(); }); diff --git a/server/src/database/migrations/20200105014405_create_expenses_table.js b/server/src/database/migrations/20200105014405_create_expenses_table.js index 4cb326302..f6f8e383d 100644 --- a/server/src/database/migrations/20200105014405_create_expenses_table.js +++ b/server/src/database/migrations/20200105014405_create_expenses_table.js @@ -6,11 +6,11 @@ exports.up = function(knex) { table.string('currency_code'); table.decimal('exchange_rate'); table.text('description'); - table.integer('expense_account_id').unsigned().references('id').inTable('accounts'); - table.integer('payment_account_id').unsigned().references('id').inTable('accounts'); + table.integer('expense_account_id').unsigned(); + table.integer('payment_account_id').unsigned(); table.string('reference'); table.boolean('published').defaultTo(false); - table.integer('user_id').unsigned().references('id').inTable('users'); + table.integer('user_id').unsigned(); table.date('date'); // table.timestamps(); }) diff --git a/server/src/database/migrations/20200105195823_create_manual_journals_table.js b/server/src/database/migrations/20200105195823_create_manual_journals_table.js index f254aec7c..5dee2b6e4 100644 --- a/server/src/database/migrations/20200105195823_create_manual_journals_table.js +++ b/server/src/database/migrations/20200105195823_create_manual_journals_table.js @@ -7,7 +7,7 @@ exports.up = function(knex) { table.decimal('amount'); table.date('date'); table.string('note'); - table.integer('user_id').unsigned().references('id').inTable('users'); + table.integer('user_id').unsigned(); table.timestamps(); }); }; diff --git a/server/src/database/migrations/20200120145342_create_budget_entries_table.js b/server/src/database/migrations/20200120145342_create_budget_entries_table.js index 60a7d49a2..bd7795ef5 100644 --- a/server/src/database/migrations/20200120145342_create_budget_entries_table.js +++ b/server/src/database/migrations/20200120145342_create_budget_entries_table.js @@ -2,8 +2,8 @@ exports.up = function(knex) { return knex.schema.createTable('budget_entries', (table) => { table.increments(); - table.integer('budget_id').unsigned().references('id').inTable('budgets'); - table.integer('account_id').unsigned().references('id').inTable('accounts'); + table.integer('budget_id').unsigned(); + table.integer('account_id').unsigned(); table.decimal('amount', 15, 5); table.integer('order'); }) diff --git a/server/src/database/migrations/20200125173323_create_resource_custom_fields_metadata_table.js b/server/src/database/migrations/20200125173323_create_resource_custom_fields_metadata_table.js index 74c1c89c3..b1731a3ea 100644 --- a/server/src/database/migrations/20200125173323_create_resource_custom_fields_metadata_table.js +++ b/server/src/database/migrations/20200125173323_create_resource_custom_fields_metadata_table.js @@ -2,11 +2,11 @@ exports.up = function(knex) { return knex.schema.createTable('resource_custom_fields_metadata', (table) => { table.increments(); - table.integer('resource_id').unsigned().references('id').inTable('resources'); + table.integer('resource_id').unsigned(); table.integer('resource_item_id').unsigned(); table.string('key'); table.string('value'); - }) + }); }; exports.down = function(knex) { diff --git a/server/src/database/seeds/account_types.js b/server/src/database/seeds/account_types.js index 003a2f05b..91a07d65e 100644 --- a/server/src/database/seeds/account_types.js +++ b/server/src/database/seeds/account_types.js @@ -8,54 +8,63 @@ exports.seed = (knex) => { { id: 1, name: 'Fixed Asset', + normal: 'debit', balance_sheet: true, income_sheet: false, }, { id: 2, name: 'Current Asset', + normal: 'debit', balance_sheet: true, income_sheet: false, }, { id: 3, name: 'Long Term Liability', + normal: 'credit', balance_sheet: false, income_sheet: true, }, { id: 4, name: 'Current Liability', + normal: 'credit', balance_sheet: false, income_sheet: true, }, { id: 5, name: 'Equity', + normal: 'credit', balance_sheet: false, income_sheet: true, }, { id: 6, name: 'Expense', + normal: 'debit', balance_sheet: false, income_sheet: true, }, { id: 7, name: 'Income', + normal: 'credit', balance_sheet: false, income_sheet: true, }, { id: 8, name: 'Accounts Receivable', + normal: 'debit', balance_sheet: true, income_sheet: false, }, { id: 9, name: 'Accounts Payable', + normal: 'credit', balance_sheet: true, income_sheet: false, }, diff --git a/server/src/http/controllers/Accounting.js b/server/src/http/controllers/Accounting.js index a3696ec1a..bf611bdc7 100644 --- a/server/src/http/controllers/Accounting.js +++ b/server/src/http/controllers/Accounting.js @@ -1,6 +1,7 @@ -import { check, query, validationResult } from 'express-validator'; +import { check, query, oneOf, validationResult } from 'express-validator'; import express from 'express'; import { difference } from 'lodash'; +import moment from 'moment'; import Account from '@/models/Account'; import asyncMiddleware from '@/http/middleware/asyncMiddleware'; import JWTAuth from '@/http/middleware/jwtAuth'; @@ -38,9 +39,10 @@ export default { validation: [ check('date').isISO8601(), check('reference').exists(), + check('memo').optional().trim().escape(), check('entries').isArray({ min: 1 }), - check('entries.*.credit').isNumeric().toInt(), - check('entries.*.debit').isNumeric().toInt(), + check('entries.*.credit').optional({ nullable: true }).isNumeric().toInt(), + check('entries.*.debit').optional({ nullable: true }).isNumeric().toInt(), check('entries.*.account_id').isNumeric().toInt(), check('entries.*.note').optional(), ], @@ -56,11 +58,16 @@ export default { date: new Date(), ...req.body, }; - const errorReasons = []; + let totalCredit = 0; let totalDebit = 0; - form.entries.forEach((entry) => { + const { user } = req; + const errorReasons = []; + const entries = form.entries.filter((entry) => (entry.credit || entry.debit)); + const formattedDate = moment(form.date).format('YYYY-MM-DD'); + + entries.forEach((entry) => { if (entry.credit > 0) { totalCredit += entry.credit; } @@ -68,6 +75,7 @@ export default { totalDebit += entry.debit; } }); + if (totalCredit <= 0 || totalDebit <= 0) { errorReasons.push({ type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', @@ -77,7 +85,7 @@ export default { if (totalCredit !== totalDebit) { errorReasons.push({ type: 'CREDIT.DEBIT.NOT.EQUALS', code: 100 }); } - const accountsIds = form.entries.map((entry) => entry.account_id); + const accountsIds = entries.map((entry) => entry.account_id); const accounts = await Account.query().whereIn('id', accountsIds) .withGraphFetched('type'); @@ -95,18 +103,30 @@ export default { if (errorReasons.length > 0) { return res.status(400).send({ errors: errorReasons }); } + + // Save manual journal transaction. + const manualJournal = await ManualJournal.query().insert({ + reference: form.reference, + transaction_type: 'Journal', + amount: totalCredit, + date: formattedDate, + note: form.memo, + user_id: user.id, + }); const journalPoster = new JournalPoster(); - form.entries.forEach((entry) => { + entries.forEach((entry) => { const account = accounts.find((a) => a.id === entry.account_id); const jouranlEntry = new JournalEntry({ - date: entry.date, debit: entry.debit, credit: entry.credit, account: account.id, + transactionType: 'Journal', accountNormal: account.type.normal, note: entry.note, + date: formattedDate, + userId: user.id, }); if (entry.debit) { journalPoster.debit(jouranlEntry); @@ -120,7 +140,7 @@ export default { journalPoster.saveEntries(), journalPoster.saveBalance(), ]); - return res.status(200).send(); + return res.status(200).send({ id: manualJournal.id }); }, }, diff --git a/server/src/http/controllers/Customers.js b/server/src/http/controllers/Customers.js index f7a91021d..4a56bd130 100644 --- a/server/src/http/controllers/Customers.js +++ b/server/src/http/controllers/Customers.js @@ -1,10 +1,71 @@ import express from 'express'; +import { + check, + param, + query, + validationResult, +} from 'express-validator'; +import asyncMiddleware from '@/http/middleware/asyncMiddleware'; export default { router() { const router = express.Router(); + router.post('/', + this.newCustomer.validation, + asyncMiddleware(this.newCustomer.handler)); + + router.post('/:id', + this.editCustomer.validation, + asyncMiddleware(this.editCustomer.handler)); + return router; }, + + newCustomer: { + validation: [ + check('custom_type').exists().trim().escape(), + check('first_name').exists().trim().escape(), + check('last_name'), + check('company_name'), + check('email'), + check('work_phone'), + check('personal_phone'), + + check('billing_address.country'), + check('billing_address.address'), + check('billing_address.city'), + check('billing_address.phone'), + check('billing_address.zip_code'), + + check('shiping_address.country'), + check('shiping_address.address'), + check('shiping_address.city'), + check('shiping_address.phone'), + check('shiping_address.zip_code'), + + check('contact.additional_phone'), + check('contact.additional_email'), + + check('custom_fields').optional().isArray({ min: 1 }), + check('custom_fields.*.key').exists().trim().escape(), + check('custom_fields.*.value').exists(), + + check('inactive').optional().isBoolean().toBoolean(), + ], + + async handler(req, res) { + + }, + }, + + editCustomer: { + validation: [ + + ], + async handler(req, res) { + + }, + }, }; diff --git a/server/src/http/controllers/Expenses.js b/server/src/http/controllers/Expenses.js index 8d2e66d45..9a55775b8 100644 --- a/server/src/http/controllers/Expenses.js +++ b/server/src/http/controllers/Expenses.js @@ -317,6 +317,12 @@ export default { query('page').optional().isNumeric().toInt(), query('page_size').optional().isNumeric().toInt(), query('custom_view_id').optional().isNumeric().toInt(), + + query('filter_roles').optional().isArray(), + query('filter_roles.*.field_key').exists().escape().trim(), + query('filter_roles.*.value').exists().escape().trim(), + query('filter_roles.*.comparator').exists().escape().trim(), + query('filter_roles.*.index').exists().isNumeric().toInt(), ], async handler(req, res) { const validationErrors = validationResult(req); diff --git a/server/src/http/controllers/FinancialStatements.js b/server/src/http/controllers/FinancialStatements.js index 27684dc2c..d8abec9d9 100644 --- a/server/src/http/controllers/FinancialStatements.js +++ b/server/src/http/controllers/FinancialStatements.js @@ -122,6 +122,7 @@ export default { query('number_format.no_cents').optional().isBoolean().toBoolean(), query('number_format.divide_1000').optional().isBoolean().toBoolean(), query('none_zero').optional().isBoolean().toBoolean(), + query('accounts_ids').optional().trim().escape(), ], async handler(req, res) { const validationErrors = validationResult(req); @@ -134,16 +135,21 @@ export default { const filter = { from_date: moment().startOf('year').format('YYYY-MM-DD'), to_date: moment().endOf('year').format('YYYY-MM-DD'), + basis: 'cash', number_format: { no_cents: false, divide_1000: false, }, none_zero: false, + accounts_ids: [], ...req.query, }; + const accounts = await Account.query() .orderBy('index', 'DESC') + .modify('filterAccounts', filter.accounts_ids) .withGraphFetched('transactions') + .withGraphFetched('type') .modifyGraph('transactions', (builder) => { builder.modify('filterDateRange', filter.from_date, filter.to_date); }); @@ -167,33 +173,40 @@ export default { // Transaction amount formatter based on the given query. const formatNumber = formatNumberClosure(filter.number_format); - const items = [ - ...accounts - .filter((account) => ( - account.transactions.length > 0 || !filter.none_zero - )) - .map((account) => ({ - ...pick(account, ['id', 'name', 'code', 'index']), - transactions: [ - ...account.transactions.map((transaction) => ({ + const items = accounts + .filter((account) => ( + account.transactions.length > 0 || !filter.none_zero + )) + .map((account) => ({ + ...pick(account, ['id', 'name', 'code', 'index']), + transactions: [ + ...account.transactions.map((transaction) => { + let amount = 0; + + if (account.type.normal === 'credit') { + amount += transaction.credit - transaction.credit; + } else if (account.type.normal === 'debit') { + amount += transaction.debit - transaction.credit; + } + return { ...transaction, - credit: formatNumber(transaction.credit), - debit: formatNumber(transaction.debit), - })), - ], - opening: { - date: filter.from_date, - balance: opeingBalanceCollection.getClosingBalance(account.id), - }, - closing: { - date: filter.to_date, - balance: closingBalanceCollection.getClosingBalance(account.id), - }, - })), - ]; + amount: formatNumber(amount), + }; + }), + ], + opening: { + date: filter.from_date, + balance: opeingBalanceCollection.getClosingBalance(account.id), + }, + closing: { + date: filter.to_date, + balance: closingBalanceCollection.getClosingBalance(account.id), + }, + })); + return res.status(200).send({ - meta: { ...filter }, - items, + query: { ...filter }, + accounts: items, }); }, }, @@ -206,7 +219,7 @@ export default { query('accounting_method').optional().isIn(['cash', 'accural']), query('from_date').optional(), query('to_date').optional(), - query('display_columns_by').optional().isIn(['year', 'month', 'week', 'day', 'quarter']), + query('display_columns_by').optional().isIn(['total', 'year', 'month', 'week', 'day', 'quarter']), query('number_format.no_cents').optional().isBoolean().toBoolean(), query('number_format.divide_1000').optional().isBoolean().toBoolean(), query('none_zero').optional().isBoolean().toBoolean(), @@ -220,7 +233,7 @@ export default { }); } const filter = { - display_columns_by: 'year', + display_columns_by: 'total', from_date: moment().startOf('year').format('YYYY-MM-DD'), to_date: moment().endOf('year').format('YYYY-MM-DD'), number_format: { @@ -228,11 +241,11 @@ export default { divide_1000: false, }, none_zero: false, + basis: 'cash', ...req.query, }; - const balanceSheetTypes = await AccountType.query() - .where('balance_sheet', true); + const balanceSheetTypes = await AccountType.query().where('balance_sheet', true); // Fetch all balance sheet accounts. const accounts = await Account.query() @@ -249,51 +262,92 @@ export default { // Account balance formmatter based on the given query. const balanceFormatter = formatNumberClosure(filter.number_format); + const filterDateType = filter.display_columns_by === 'total' + ? 'day' : filter.display_columns_by; // Gets the date range set from start to end date. const dateRangeSet = dateRangeCollection( filter.from_date, filter.to_date, - filter.display_columns_by, + filterDateType, ); + // Retrieve the asset balance sheet. - const assets = [ - ...accounts - .filter((account) => ( - account.type.normal === 'debit' + const assets = accounts + .filter((account) => ( + account.type.normal === 'debit' && (account.transactions.length > 0 || !filter.none_zero) - )) - .map((account) => ({ + )) + .map((account) => { + // Calculates the closing balance to the given date. + const closingBalance = journalEntries.getClosingBalance(account.id, filter.to_date); + const type = filter.display_columns_by; + + return { ...pick(account, ['id', 'index', 'name', 'code']), - transactions: dateRangeSet.map((date) => { - const type = filter.display_columns_by; - const balance = journalEntries.getClosingBalance(account.id, date, type); - return { date, balance: balanceFormatter(balance) }; - }), - })), - ]; + ...(type !== 'total') ? { + periods_balance: dateRangeSet.map((date) => { + const balance = journalEntries.getClosingBalance(account.id, date, filterDateType); + + return { + date, + formatted_amount: balanceFormatter(balance), + amount: balance, + }; + }), + } : {}, + balance: { + formatted_amount: balanceFormatter(closingBalance), + amount: closingBalance, + date: filter.to_date, + }, + }; + }); + // Retrieve liabilities and equity balance sheet. - const liabilitiesEquity = [ - ...accounts - .filter((account) => ( - account.type.normal === 'credit' + const liabilitiesEquity = accounts + .filter((account) => ( + account.type.normal === 'credit' && (account.transactions.length > 0 || !filter.none_zero) - )) - .map((account) => ({ + )) + .map((account) => { + // Calculates the closing balance to the given date. + const closingBalance = journalEntries.getClosingBalance(account.id, filter.to_date); + const type = filter.display_columns_by; + + return { ...pick(account, ['id', 'index', 'name', 'code']), - transactions: dateRangeSet.map((date) => { - const type = filter.display_columns_by; - const balance = journalEntries.getClosingBalance(account.id, date, type); - return { date, balance: balanceFormatter(balance) }; - }), - })), - ]; + ...(type !== 'total') ? { + periods_balance: dateRangeSet.map((date) => { + const balance = journalEntries.getClosingBalance(account.id, date, filterDateType); + + return { + date, + formatted_amount: balanceFormatter(balance), + amount: balance, + }; + }), + } : {}, + balance: { + formattedAmount: balanceFormatter(closingBalance), + amount: closingBalance, + date: filter.to_date, + }, + }; + }); + return res.status(200).send({ query: { ...filter }, columns: { ...dateRangeSet }, balance_sheet: { - assets, - liabilities_equity: liabilitiesEquity, + assets: { + title: 'Assets', + accounts: [...assets], + }, + liabilities_equity: { + title: 'Liabilities & Equity', + accounts: [...liabilitiesEquity], + }, }, }); }, @@ -363,7 +417,7 @@ export default { }; }); return res.status(200).send({ - meta: { ...filter }, + query: { ...filter }, items: [...items], }); }, @@ -381,8 +435,12 @@ export default { query('number_format.divide_1000').optional().isBoolean(), query('basis').optional(), query('none_zero').optional(), - query('display_columns_by').optional().isIn(['year', 'month', 'week', 'day', 'quarter']), - query('accounts').optional().isArray(), + query('display_columns_type').optional().isIn([ + 'total', 'date_periods', + ]), + query('display_columns_by').optional().isIn([ + 'year', 'month', 'week', 'day', 'quarter', + ]), ], async handler(req, res) { const validationErrors = validationResult(req); @@ -401,19 +459,22 @@ export default { }, basis: 'accural', none_zero: false, - display_columns_by: 'month', + display_columns_type: 'total', + display_columns_by: 'total', ...req.query, }; const incomeStatementTypes = await AccountType.query().where('income_sheet', true); + // Fetch all income accounts from storage. const accounts = await Account.query() .whereIn('account_type_id', incomeStatementTypes.map((t) => t.id)) .withGraphFetched('type') .withGraphFetched('transactions'); - const filteredAccounts = accounts.filter((account) => { - return account.transactions.length > 0 || !filter.none_zero; - }); + // Filter all none zero accounts if it was enabled. + const filteredAccounts = accounts.filter((account) => ( + account.transactions.length > 0 || !filter.none_zero + )); const journalEntriesCollected = Account.collectJournalEntries(accounts); const journalEntries = new JournalPoster(); journalEntries.loadEntries(journalEntriesCollected); @@ -427,75 +488,130 @@ export default { filter.to_date, filter.display_columns_by, ); - const accountsIncome = filteredAccounts - .filter((account) => account.type.normal === 'credit') - .map((account) => ({ + + const accountsMapper = (incomeExpenseAccounts) => ( + incomeExpenseAccounts.map((account) => ({ ...pick(account, ['id', 'index', 'name', 'code']), - dates: dateRangeSet.map((date) => { - const type = filter.display_columns_by; - const amount = journalEntries.getClosingBalance(account.id, date, type); - return { date, rawAmount: amount, amount: numberFormatter(amount) }; - }), - })); + // Total closing balance of the account. + ...(filter.display_columns_type === 'total') && { + total: (() => { + const amount = journalEntries.getClosingBalance(account.id, filter.to_date); + return { amount, date: filter.to_date, formatted_amount: numberFormatter(amount) }; + })(), + }, + // Date periods when display columns type `periods`. + ...(filter.display_columns_type === 'date_periods') && { + periods: dateRangeSet.map((date) => { + const type = filter.display_columns_by; + const amount = journalEntries.getClosingBalance(account.id, date, type); - const accountsExpenses = filteredAccounts - .filter((account) => account.type.normal === 'debit') - .map((account) => ({ - ...pick(account, ['id', 'index', 'name', 'code']), - dates: dateRangeSet.map((date) => { - const type = filter.display_columns_by; - const amount = journalEntries.getClosingBalance(account.id, date, type); + return { date, amount, formatted_amount: numberFormatter(amount) }; + }), + }, + }))); - return { date, rawAmount: amount, amount: numberFormatter(amount) }; - }), - })); + const totalAccountsReducer = (incomeExpenseAccounts) => ( + incomeExpenseAccounts.reduce((acc, account) => { + const amount = (account) ? account.total.amount : 0; + return amount + acc; + }, 0)); - // Calculates the total income of income accounts. - const totalAccountsIncome = dateRangeSet.reduce((acc, date, index) => { - let amount = 0; - accountsIncome.forEach((account) => { - const currentDate = account.dates[index]; - amount += currentDate.rawAmount || 0; - }); - acc[date] = { date, rawAmount: amount, amount: numberFormatter(amount) }; - return acc; - }, {}); + const accountsIncome = accountsMapper(filteredAccounts + .filter((account) => account.type.normal === 'credit')); - // Calculates the total expenses of expenses accounts. - const totalAccountsExpenses = dateRangeSet.reduce((acc, date, index) => { - let amount = 0; - accountsExpenses.forEach((account) => { - const currentDate = account.dates[index]; - amount += currentDate.rawAmount || 0; - }); - acc[date] = { date, rawAmount: amount, amount: numberFormatter(amount) }; - return acc; - }, {}); + const accountsExpenses = accountsMapper(filteredAccounts + .filter((account) => account.type.normal === 'debit')); + + // @return {Array} + const totalPeriodsMapper = (incomeExpenseAccounts) => ( + Object.values(dateRangeSet.reduce((acc, date, index) => { + let amount = 0; + + incomeExpenseAccounts.forEach((account) => { + const currentDate = account.periods[index]; + amount += currentDate.amount || 0; + }); + acc[date] = { date, amount, formatted_amount: numberFormatter(amount) }; + return acc; + }, {}))); // Total income(date) - Total expenses(date) = Net income(date) - const netIncome = dateRangeSet.map((date) => { - const totalIncome = totalAccountsIncome[date]; - const totalExpenses = totalAccountsExpenses[date]; + // @return {Array} + const netIncomePeriodsMapper = (totalIncomeAcocunts, totalExpenseAccounts) => ( + dateRangeSet.map((date, index) => { + const totalIncome = totalIncomeAcocunts[index]; + const totalExpenses = totalExpenseAccounts[index]; - let amount = totalIncome.rawAmount || 0; - amount -= totalExpenses.rawAmount || 0; - return { date, rawAmount: amount, amount: numberFormatter(amount) }; - }); + let amount = totalIncome.amount || 0; + amount -= totalExpenses.amount || 0; + return { date, amount, formatted_amount: numberFormatter(amount) }; + })); + // @return {Object} + const netIncomeTotal = (totalIncome, totalExpenses) => { + const netIncomeAmount = totalIncome.amount - totalExpenses.amount; + return { amount: netIncomeAmount, formatted_amount: netIncomeAmount }; + }; + + const totalIncomeAccounts = totalAccountsReducer(accountsIncome); + const totalExpensesAccounts = totalAccountsReducer(accountsExpenses); + + const incomeResponse = { + entry_normal: 'credit', + accounts: accountsIncome, + + ...(filter.display_columns_type === 'total') && { + total: { + amount: totalIncomeAccounts, + date: filter.to_date, + formatted_amount: numberFormatter(totalIncomeAccounts), + }, + }, + ...(filter.display_columns_type === 'date_periods') && { + total_periods: [ + ...totalPeriodsMapper(accountsIncome), + ], + }, + }; + const expenseResponse = { + entry_normal: 'debit', + accounts: accountsExpenses, + + ...(filter.display_columns_type === 'total') && { + total: { + amount: totalExpensesAccounts, + date: filter.to_date, + formatted_amount: numberFormatter(totalExpensesAccounts), + }, + }, + ...(filter.display_columns_type === 'date_periods') && { + total_periods: [ + ...totalPeriodsMapper(accountsExpenses), + ], + }, + }; + const netIncomeResponse = { + ...(filter.display_columns_type === 'total') && { + total: { + ...netIncomeTotal(incomeResponse.total, expenseResponse.total), + }, + }, + ...(filter.display_columns_type === 'date_periods') && { + total_periods: [ + ...netIncomePeriodsMapper( + incomeResponse.total_periods, + expenseResponse.total_periods, + ), + ], + }, + }; return res.status(200).send({ - meta: { ...filter }, - income: { - entry_normal: 'credit', - accounts: accountsIncome, - }, - expenses: { - entry_normal: 'debit', - accounts: accountsExpenses, - }, - total_income: Object.values(totalAccountsIncome), - total_expenses: Object.values(totalAccountsExpenses), - total_net_income: netIncome, + query: { ...filter }, + columns: [...dateRangeSet], + income: incomeResponse, + expenses: expenseResponse, + net_income: netIncomeResponse, }); }, }, diff --git a/server/src/models/Account.js b/server/src/models/Account.js index dbad7f73f..53e900af2 100644 --- a/server/src/models/Account.js +++ b/server/src/models/Account.js @@ -17,6 +17,11 @@ export default class Account extends BaseModel { */ static get modifiers() { return { + filterAccounts(query, accountIds) { + if (accountIds.length > 0) { + query.whereIn('id', accountIds); + } + }, filterAccountTypes(query, typesIds) { if (typesIds.length > 0) { query.whereIn('accoun_type_id', typesIds); diff --git a/server/src/services/Accounting/JournalPoster.js b/server/src/services/Accounting/JournalPoster.js index d6ab875c6..b18dec636 100644 --- a/server/src/services/Accounting/JournalPoster.js +++ b/server/src/services/Accounting/JournalPoster.js @@ -3,6 +3,7 @@ import moment from 'moment'; import JournalEntry from '@/services/Accounting/JournalEntry'; import AccountTransaction from '@/models/AccountTransaction'; import AccountBalance from '@/models/AccountBalance'; +import {promiseSerial} from '@/utils'; export default class JournalPoster { /** @@ -125,12 +126,12 @@ export default class JournalPoster { this.entries.forEach((entry) => { const oper = AccountTransaction.query().insert({ accountId: entry.account, - ...pick(entry, ['credit', 'debit', 'transactionType', + ...pick(entry, ['credit', 'debit', 'transactionType', 'date', 'userId', 'referenceType', 'referenceId', 'note']), }); - saveOperations.push(oper); + saveOperations.push(() => oper); }); - await Promise.all(saveOperations); + await promiseSerial(saveOperations); } /** diff --git a/server/src/utils/index.js b/server/src/utils/index.js index 06c1fad3a..6dd921b8f 100644 --- a/server/src/utils/index.js +++ b/server/src/utils/index.js @@ -66,6 +66,12 @@ const mapValuesDeep = (v, callback) => ( ? _.mapValues(v, v => mapValuesDeep(v, callback)) : callback(v)); + +const promiseSerial = (funcs) => { + return funcs.reduce((promise, func) => promise.then((result) => func().then(Array.prototype.concat.bind(result))), + Promise.resolve([])); +} + export { hashPassword, origin, @@ -73,4 +79,5 @@ export { dateRangeFormat, mapValuesDeep, mapKeysDeep, + promiseSerial, }; diff --git a/server/tests/routes/accounting.test.js b/server/tests/routes/accounting.test.js index 49ce26757..1ba7c7587 100644 --- a/server/tests/routes/accounting.test.js +++ b/server/tests/routes/accounting.test.js @@ -1,8 +1,16 @@ -import { request, expect, create, login } from '~/testInit'; +import { + request, + expect, + create, + login, +} from '~/testInit'; +import moment from 'moment'; +import ManualJournal from '@/models/ManualJournal'; +import AccountTransaction from '@/models/AccountTransaction'; let loginRes; -describe('routes: /accounting', () => { +describe('routes: `/accounting`', () => { beforeEach(async () => { loginRes = await login(); }); @@ -127,8 +135,113 @@ describe('routes: /accounting', () => { }); }); - it('Should store all journal entries to the storage.', async () => { + it('Should discard journal entries that has null credit and debit amount.', async () => { + const account1 = await create('account'); + const account2 = await create('account'); + const res = await request() + .post('/api/accounting/make-journal-entries') + .set('x-access-token', loginRes.body.token) + .send({ + date: new Date().toISOString(), + reference: '1000', + entries: [ + { + credit: null, + debit: 0, + account_id: account1.id, + }, + { + credit: null, + debit: 0, + account_id: account2.id, + }, + ], + }); + + expect(res.status).equals(400); + expect(res.body.errors).include.something.that.deep.equal({ + type: 'CREDIT.DEBIT.SUMATION.SHOULD.NOT.EQUAL.ZERO', + code: 400, + }); + }); + + it('Should store manual journal transaction to the storage.', async () => { + const account1 = await create('account'); + const account2 = await create('account'); + + const res = await request() + .post('/api/accounting/make-journal-entries') + .set('x-access-token', loginRes.body.token) + .send({ + date: new Date('2020-2-2').toISOString(), + reference: '1000', + memo: 'Description here.', + entries: [ + { + credit: 1000, + account_id: account1.id, + }, + { + debit: 1000, + account_id: account2.id, + }, + ], + }); + + const foundManualJournal = await ManualJournal.query(); + + expect(foundManualJournal.length).equals(1); + expect(foundManualJournal[0].reference).equals('1000'); + expect(foundManualJournal[0].transactionType).equals('Journal'); + expect(foundManualJournal[0].amount).equals(1000); + expect(moment(foundManualJournal[0].date).format('YYYY-MM-DD')).equals('2020-02-02'); + expect(foundManualJournal[0].note).equals('Description here.'); + expect(foundManualJournal[0].userId).equals(1); + }); + + it('Should store journal transactions to the storage.', async () => { + const account1 = await create('account'); + const account2 = await create('account'); + + const res = await request() + .post('/api/accounting/make-journal-entries') + .set('x-access-token', loginRes.body.token) + .send({ + date: new Date('2020-1-1').toISOString(), + reference: '1000', + memo: 'Description here.', + entries: [ + { + credit: 1000, + account_id: account1.id, + note: 'First note', + }, + { + debit: 1000, + account_id: account2.id, + note: 'Second note', + }, + ], + }); + + const foundAccountsTransactions = await AccountTransaction.query(); + + expect(foundAccountsTransactions.length).equals(2); + + expect(foundAccountsTransactions[0].credit).equals(1000); + expect(foundAccountsTransactions[0].debit).equals(null); + expect(foundAccountsTransactions[0].accountId).equals(account1.id); + expect(foundAccountsTransactions[0].note).equals('First note'); + expect(foundAccountsTransactions[0].transactionType).equals('Journal'); + expect(foundAccountsTransactions[0].userId).equals(1); + + expect(foundAccountsTransactions[1].credit).equals(null); + expect(foundAccountsTransactions[1].debit).equals(1000); + expect(foundAccountsTransactions[1].accountId).equals(account2.id); + expect(foundAccountsTransactions[1].note).equals('Second note'); + expect(foundAccountsTransactions[1].transactionType).equals('Journal'); + expect(foundAccountsTransactions[1].userId).equals(1); }); }); diff --git a/server/tests/routes/financial_statements.test.js b/server/tests/routes/financial_statements.test.js index 0ff4ab5a1..5fb167d68 100644 --- a/server/tests/routes/financial_statements.test.js +++ b/server/tests/routes/financial_statements.test.js @@ -4,6 +4,7 @@ import { login, create, } from '~/testInit'; +import moment from 'moment'; let loginRes; let creditAccount; @@ -145,56 +146,95 @@ describe('routes: `/financial_statements`', () => { }); }); - describe('routes: `/financial_statements/general_ledger`', () => { + describe.only('routes: `/financial_statements/general_ledger`', () => { it('Should response unauthorized in case the user was not authorized.', async () => { const res = await request() .get('/api/financial_statements/general_ledger') .send(); - expect(res.status).equals(400); + expect(res.status).equals(401); }); - it('Should retrieve the genereal ledger transactions.', async () => { + it('Should retrieve request query meta on response schema.', async () => { const res = await request() .get('/api/financial_statements/general_ledger') .set('x-access-token', loginRes.body.token) .send(); - expect(res.body.items).to.be.a('array'); - expect(res.body.items.length).equals(4); + expect(res.body.query.from_date).equals(moment().startOf('year').format('YYYY-MM-DD')); + expect(res.body.query.to_date).equals(moment().endOf('year').format('YYYY-MM-DD')); + expect(res.body.query.basis).equals('cash'); + expect(res.body.query.number_format.no_cents).equals(false); + expect(res.body.query.number_format.divide_1000).equals(false); + expect(res.body.query.none_zero).equals(false); + expect(res.body.query.accounts_ids).to.be.an('array'); }); - it('Should retrieve opeing and closing balance in each account.', async () => { + it('Should retrieve the general ledger accounts with associated transactions and opening/closing balance.', async () => { const res = await request() .get('/api/financial_statements/general_ledger') .set('x-access-token', loginRes.body.token) .send(); - const foundCreditAccount = res.body.items.find((a) => a.id === creditAccount.id); - - expect(foundCreditAccount.closing.balance).equals(2000); - expect(foundCreditAccount.opening.balance).equals(0); + expect(res.body.accounts).is.an('array'); + expect(res.body.accounts[0].id).to.be.an('number'); + expect(res.body.accounts[0].name).to.be.a('string'); + expect(res.body.accounts[0].code).to.be.a('string'); + expect(res.body.accounts[0].transactions).to.be.a('array'); + expect(res.body.accounts[0].opening).to.be.a('object'); + expect(res.body.accounts[0].opening.balance).to.be.a('number'); + expect(res.body.accounts[0].opening.date).to.be.a('string'); + expect(res.body.accounts[0].closing).to.be.a('object'); + expect(res.body.accounts[0].closing.balance).to.be.a('number'); + expect(res.body.accounts[0].closing.date).to.be.a('string'); }); - it('Should retrieve the general ledger transactions between date range.', async () => { + it('Should retrieve opening and closing balance.', async () => { const res = await request() .get('/api/financial_statements/general_ledger') .set('x-access-token', loginRes.body.token) - .query({ - from_date: '2020-04-04', - to_date: '2020-05-05', - }) .send(); - - const foundCreditAccount = res.body.items.find((a) => a.id === creditAccount.id); - expect(foundCreditAccount.transactions.length).equals(0); + + const targetAccount = res.body.accounts.find((a) => a.id === creditAccount.id); + + expect(targetAccount).to.be.an('object'); + expect(targetAccount.opening).to.deep.equal({ + balance: 0, date: '2020-01-01', + }); + expect(targetAccount.closing).to.deep.equal({ + balance: 2000, date: '2020-12-31', + }); }); - it('Should retrieve the general ledger transactions with no cents numbers.', () => { + it('Should retrieve opening and closing balance between the given date range.', () => { }); - it('Should retrieve the transacvtions divided on 1000.', () => { + it('Should retrieve transactions of accounts that has transactions between date range.', () => { + + }); + + it('Should retrieve accounts transactions only that between date range.', () => { + + }); + + it('Should not retrieve all accounts that have no transactions in the given date range when `none_zero` is `false`.', () => { + + }); + + it('Should retrieve all accounts even it have no transactions in the given date range when `none_zero` is `true`', () => { + + }); + + it('Should amount transactions divided on 1000 when `number_format.none_zero` is `true`.', () => { + + }); + + it('Should amount transactions rounded with no decimals when `number_format.no_cents` is `true`.', () => { + + }); + + it('Should retrieve only accounts that given in the query.', () => { }); }); @@ -208,6 +248,27 @@ describe('routes: `/financial_statements`', () => { expect(res.status).equals(401); }); + it('Should retrieve query of the balance sheet with default values.', async () => { + const res = await request() + .get('/api/financial_statements/balance_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + display_columns_by: 'year', + from_date: '2020-01-01', + to_date: '2020-02-01', + }) + .send(); + + expect(res.body.query.display_columns_by).equals('year'); + expect(res.body.query.from_date).equals('2020-01-01'); + expect(res.body.query.to_date).equals('2020-02-01'); + + expect(res.body.query.number_format.no_cents).equals(false); + expect(res.body.query.number_format.divide_1000).equals(false); + + expect(res.body.query.none_zero).equals(false); + }); + it('Should retrieve the asset accounts balance.', async () => { const res = await request() .get('/api/financial_statements/balance_sheet') @@ -217,11 +278,30 @@ describe('routes: `/financial_statements`', () => { }) .send(); - expect(res.body.balance_sheet.assets).to.be.a('array'); - expect(res.body.balance_sheet.liabilities_equity).to.be.a('array'); + expect(res.body.balance_sheet.assets.accounts).to.be.a('array'); + expect(res.body.balance_sheet.liabilities_equity.accounts).to.be.a('array'); }); - it('Should retrieve asset/liabilities balance sheet between the given date range.', async () => { + it('Should retrieve assets/liabilities total balance between the given date range.', async () => { + const res = await request() + .get('/api/financial_statements/balance_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + display_columns_by: 'total', + from_date: '2012-01-01', + to_date: '2032-02-02', + }) + .send(); + + expect(res.body.balance_sheet.assets.accounts[0].balance).deep.equals({ + amount: 4000, formattedAmount: 4000, date: '2032-02-02', + }); + expect(res.body.balance_sheet.liabilities_equity.accounts[0].balance).deep.equals({ + amount: 2000, formattedAmount: 2000, date: '2032-02-02', + }); + }); + + it('Should retrieve asset/liabilities balance sheet with display columns by `year`.', async () => { const res = await request() .get('/api/financial_statements/balance_sheet') .set('x-access-token', loginRes.body.token) @@ -232,121 +312,142 @@ describe('routes: `/financial_statements`', () => { }) .send(); - const { balance_sheet: balanceSheet } = res.body; - const foundCreditAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance.length).equals(7); + expect(res.body.balance_sheet.liabilities_equity.accounts[0].periods_balance.length).equals(7); - expect(foundCreditAccount.transactions.length).equals(6); - foundCreditAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(0); - }); - - const foundDebitAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - - expect(foundDebitAccount.transactions.length).equals(6); - foundDebitAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(0); - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { + amount: 0, + formatted_amount: 0, + date: '2012', + }, + { + amount: 0, + formatted_amount: 0, + date: '2013', + }, + { + amount: 0, + formatted_amount: 0, + date: '2014', + }, + { + amount: 0, + formatted_amount: 0, + date: '2015', + }, + { + amount: 0, + formatted_amount: 0, + date: '2016', + }, + { + amount: 0, + formatted_amount: 0, + date: '2017', + }, + { + amount: 0, + formatted_amount: 0, + date: '2018', + }, + ]); }); - it('Should retrieve balance sheet with display columns day.', async () => { + it('Should retrieve balance sheet with display columns by `day`.', async () => { const res = await request() .get('/api/financial_statements/balance_sheet') .set('x-access-token', loginRes.body.token) .query({ display_columns_by: 'day', - from_date: '2020-03-01', - to_date: '2020-04-01', + from_date: '2020-01-08', + to_date: '2020-01-12', }) .send(); - const { balance_sheet: balanceSheet } = res.body; - - const foundDebitAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); - const foundCreditAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - - expect(foundDebitAccount.transactions.length).equals(31); - expect(foundCreditAccount.transactions.length).equals(31); - - foundDebitAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(4000); - }); - foundCreditAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(2000); - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { date: '2020-01-08', formatted_amount: 0, amount: 0 }, + { date: '2020-01-09', formatted_amount: 0, amount: 0 }, + { date: '2020-01-10', formatted_amount: 4000, amount: 4000 }, + { date: '2020-01-11', formatted_amount: 4000, amount: 4000 }, + { date: '2020-01-12', formatted_amount: 4000, amount: 4000 }, + ]); }); - it('Should retrieve the balance sheet with display columns month.', async () => { + it('Should retrieve the balance sheet with display columns by `month`.', async () => { const res = await request() .get('/api/financial_statements/balance_sheet') .set('x-access-token', loginRes.body.token) .query({ display_columns_by: 'month', - from_date: '2020', - to_date: '2021', + from_date: '2019-07-01', + to_date: '2020-06-30', }) .send(); - const { balance_sheet: balanceSheet } = res.body; + expect(res.body.balance_sheet.assets.accounts[0].periods_balance.length).equals(12); + expect(res.body.balance_sheet.liabilities_equity.accounts[0].periods_balance.length).equals(12); - const foundDebitAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); - const foundCreditAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - - expect(foundDebitAccount.transactions.length).equals(12); - expect(foundCreditAccount.transactions.length).equals(12); - - foundDebitAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(4000); - }); - foundCreditAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(2000); - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { date: '2019-07', formatted_amount: 0, amount: 0 }, + { date: '2019-08', formatted_amount: 0, amount: 0 }, + { date: '2019-09', formatted_amount: 0, amount: 0 }, + { date: '2019-10', formatted_amount: 0, amount: 0 }, + { date: '2019-11', formatted_amount: 0, amount: 0 }, + { date: '2019-12', formatted_amount: 0, amount: 0 }, + { date: '2020-01', formatted_amount: 4000, amount: 4000 }, + { date: '2020-02', formatted_amount: 4000, amount: 4000 }, + { date: '2020-03', formatted_amount: 4000, amount: 4000 }, + { date: '2020-04', formatted_amount: 4000, amount: 4000 }, + { date: '2020-05', formatted_amount: 4000, amount: 4000 }, + { date: '2020-06', formatted_amount: 4000, amount: 4000 }, + ]); }); - it('Should retrieve the balance sheet with display columns quarter.', async () => { + it('Should retrieve the balance sheet with display columns `quarter`.', async () => { const res = await request() .get('/api/financial_statements/balance_sheet') .set('x-access-token', loginRes.body.token) .query({ display_columns_by: 'quarter', - from_date: '2020', - to_date: '2021', + from_date: '2020-01-01', + to_date: '2020-12-31', }) .send(); - const { balance_sheet: balanceSheet } = res.body; - - const foundDebitAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); - const foundCreditAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - - expect(foundDebitAccount.transactions.length).equals(4); - expect(foundCreditAccount.transactions.length).equals(4); - - foundDebitAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(4000); - }); - foundCreditAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(2000); - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance.length).equals(4); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { date: '2020-03', formatted_amount: 4000, amount: 4000 }, + { date: '2020-06', formatted_amount: 4000, amount: 4000 }, + { date: '2020-09', formatted_amount: 4000, amount: 4000 }, + { date: '2020-12', formatted_amount: 4000, amount: 4000 }, + ]); }); - it('Should retrieve the balance sheet amounts without cents.', () => { - + it('Should retrieve the balance sheet amounts without cents.', async () => { + await create('account_transaction', { + debit: 0.25, credit: 0, account_id: debitAccount.id, date: '2020-1-10', + }); + const res = await request() + .get('/api/financial_statements/balance_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + display_columns_by: 'quarter', + from_date: '2020-01-01', + to_date: '2020-12-31', + number_format: { + no_cents: true, + }, + }) + .send(); + + expect(res.body.balance_sheet.assets.accounts[0].periods_balance.length).equals(4); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { date: '2020-03', formatted_amount: 4000, amount: 4000.25 }, + { date: '2020-06', formatted_amount: 4000, amount: 4000.25 }, + { date: '2020-09', formatted_amount: 4000, amount: 4000.25 }, + { date: '2020-12', formatted_amount: 4000, amount: 4000.25 }, + ]); }); it('Should retrieve the balance sheet amounts divided on 1000.', async () => { @@ -363,23 +464,13 @@ describe('routes: `/financial_statements`', () => { }) .send(); - const { balance_sheet: balanceSheet } = res.body; - const foundDebitAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); - const foundCreditAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - - expect(foundDebitAccount.transactions.length).equals(4); - expect(foundCreditAccount.transactions.length).equals(4); - - foundDebitAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(4); - }); - foundCreditAccount.transactions.forEach((transaction) => { - expect(transaction.balance).equals(2); - }); + expect(res.body.balance_sheet.assets.accounts[0].periods_balance).deep.equals([ + { date: '2020-03', formatted_amount: 4, amount: 4000 }, + { date: '2020-06', formatted_amount: 4, amount: 4000 }, + { date: '2020-09', formatted_amount: 4, amount: 4000 }, + { date: '2020-12', formatted_amount: 4, amount: 4000 }, + { date: '2021-03', formatted_amount: 4, amount: 4000 }, + ]); }); it('Should not retrieve accounts has no transactions between the given date range in case query none_zero is true.', async () => { @@ -397,16 +488,8 @@ describe('routes: `/financial_statements`', () => { }) .send(); - const { balance_sheet: balanceSheet } = res.body; - const foundDebitAccount = balanceSheet.assets.find((account) => { - return account.id === debitAccount.id; - }); - - const foundCreditAccount = balanceSheet.liabilities_equity.find((account) => { - return account.id === creditAccount.id; - }); - expect(foundDebitAccount).equals(undefined); - expect(foundCreditAccount).equals(undefined); + expect(res.body.balance_sheet.assets.accounts.length).equals(0); + expect(res.body.balance_sheet.liabilities_equity.accounts.length).equals(0); }); }); @@ -441,14 +524,11 @@ describe('routes: `/financial_statements`', () => { // There is no transactions between these dates. from_date: '2002-01-01', to_date: '2003-01-01', + none_zero: true, }) .send(); - res.body.items.forEach((item) => { - expect(item.credit).equals(0); - expect(item.debit).equals(0); - expect(item.balance).equals(0); - }); + expect(res.body.items.length).equals(0); }); it('Should retrieve trial balance of accounts between the given date range.', async () => { @@ -506,6 +586,10 @@ describe('routes: `/financial_statements`', () => { }) .send(); }); + + it('Should retrieve associated account details in accounts list.', async () => { + + }); }); describe('routes: `/api/financial_statements/profit_loss_sheet`', () => { @@ -515,7 +599,111 @@ describe('routes: `/financial_statements`', () => { .send(); expect(res.status).equals(401); - expect(res.body.message).equals('unauthorzied'); + expect(res.body.message).equals('unauthorized'); + }); + + it('Should retrieve columns when display type `date_periods` and columns by `month` between date range.', async () => { + const res = await request() + .get('/api/financial_statements/profit_loss_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + from_date: '2020-01-01', + to_date: '2020-12-12', + display_columns_type: 'date_periods', + display_columns_by: 'month', + }) + .send(); + + expect(res.body.columns.length).equals(12); + expect(res.body.columns).deep.equals([ + '2020-01', '2020-02', + '2020-03', '2020-04', + '2020-05', '2020-06', + '2020-07', '2020-08', + '2020-09', '2020-10', + '2020-11', '2020-12', + ]); + }); + + it('Should retrieve columns when display type `date_periods` and columns by `quarter`.', async () => { + const res = await request() + .get('/api/financial_statements/profit_loss_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + from_date: moment().startOf('year').format('YYYY-MM-DD'), + to_date: moment().endOf('year').format('YYYY-MM-DD'), + display_columns_type: 'date_periods', + display_columns_by: 'month', + }) + .send(); + + expect(res.body.columns.length).equals(12); + expect(res.body.columns).deep.equals([ + '2020-03', '2020-06', '2020-09', '2020-12', + ]); + }); + + it('Should retrieve columns when display type `date_periods` and columns by `day` between date range.', async () => { + const res = await request() + .get('/api/financial_statements/profit_loss_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), + to_date: moment('2020-01-01').endOf('month').format('YYYY-MM-DD'), + display_columns_type: 'date_periods', + display_columns_by: 'day', + }) + .send(); + + expect(res.body.columns.length).equals(31); + expect(res.body.columns).deep.equals([ + '2020-01-01', '2020-01-02', '2020-01-03', + '2020-01-04', '2020-01-05', '2020-01-06', + '2020-01-07', '2020-01-08', '2020-01-09', + '2020-01-10', '2020-01-11', '2020-01-12', + '2020-01-13', '2020-01-14', '2020-01-15', + '2020-01-16', '2020-01-17', '2020-01-18', + '2020-01-19', '2020-01-20', '2020-01-21', + '2020-01-22', '2020-01-23', '2020-01-24', + '2020-01-25', '2020-01-26', '2020-01-27', + '2020-01-28', '2020-01-29', '2020-01-30', + '2020-01-31', + ]); + }); + + it('Should retrieve all income accounts even it has no transactions.', async () => { + const res = await request() + .get('/api/financial_statements/profit_loss_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), + to_date: moment('2020-01-01').endOf('month').format('YYYY-MM-DD'), + display_columns_type: 'total', + display_columns_by: 'day', + }) + .send(); + + console.log(res.body); + + // expect(res.body.income.accounts.length).equals(2); + // expect(res.body.income.accounts[0].name).to.be.an('string'); + // expect(res.body.income.accounts[0].code).to.be.an('string'); + // expect(res.body.income.accounts[0].periods).to.be.an('array'); + // expect(res.body.income.accounts[0].periods.length).equals(31); + }); + + it('Should retrieve total of each income account when display columns by `total`.', async () => { + const res = await request() + .get('/api/financial_statements/profit_loss_sheet') + .set('x-access-token', loginRes.body.token) + .query({ + from_date: moment('2020-01-01').startOf('month').format('YYYY-MM-DD'), + to_date: moment('2020-01-01').endOf('month').format('YYYY-MM-DD'), + display_columns_by: 'day', + }) + .send(); + + expect(res.body.income).deep.equals(); }); it('Should retrieve credit sumation of income accounts.', async () => { @@ -531,6 +719,8 @@ describe('routes: `/financial_statements`', () => { }) .send(); + console.log(res.body); + res.body.income.accounts[0].dates.forEach((item) => { expect(item.rawAmount).equals(2000); }); diff --git a/server/tests/routes/views.test.js b/server/tests/routes/views.test.js index d4ecdbf0b..e82ede2b7 100644 --- a/server/tests/routes/views.test.js +++ b/server/tests/routes/views.test.js @@ -11,7 +11,7 @@ import ViewColumn from '../../src/models/ViewColumn'; let loginRes; -describe.only('routes: `/views`', () => { +describe('routes: `/views`', () => { beforeEach(async () => { loginRes = await login(); }); diff --git a/server/tests/testInit.js b/server/tests/testInit.js index e75284053..86667ee09 100644 --- a/server/tests/testInit.js +++ b/server/tests/testInit.js @@ -1,22 +1,29 @@ import chai from 'chai'; import chaiHttp from 'chai-http'; import chaiThings from 'chai-things'; + import knex from '@/database/knex'; import '@/models'; import app from '@/app'; import factory from '@/database/factories'; +import knexConfig from '@/../knexfile'; +import dbManager from '@/database/manager'; // import { hashPassword } from '@/utils'; const request = () => chai.request(app); const { expect } = chai; +before(async () => { + await dbManager.dropDb(); + await dbManager.createDb('ratteb'); +}); + beforeEach(async () => { await knex.migrate.rollback(); await knex.migrate.latest(); }); afterEach(async () => { - await knex.migrate.rollback(); }); chai.use(chaiHttp);