@openmrs/esm-app-shell 10.0.1-pre.5635 → 10.0.1-pre.5649

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/.tmp/openmrs.css +83 -14
  2. package/.tmp/{openmrs.0bec35ab6fc6bff6.css → openmrs.f542494f33fc3fd1.css} +1 -1
  3. package/.turbo/turbo-build.log +4 -4
  4. package/dist/08548eeb70eab808.js +1 -0
  5. package/dist/{05ce2d37a1daa834.js.map → 08548eeb70eab808.js.map} +1 -1
  6. package/dist/82f4c9ff65af3be0.js +1 -0
  7. package/dist/82f4c9ff65af3be0.js.map +1 -0
  8. package/dist/{415d3f92b43b446a.js → ec68dad9d5d18a20.js} +6 -6
  9. package/dist/ec68dad9d5d18a20.js.map +1 -0
  10. package/dist/index.html +1 -3
  11. package/dist/{openmrs.7c9a1b50c6b0e314.js → openmrs.0b5d40e54172194f.js} +3 -3
  12. package/dist/{openmrs.7c9a1b50c6b0e314.js.map → openmrs.0b5d40e54172194f.js.map} +1 -1
  13. package/dist/{openmrs.0bec35ab6fc6bff6.css → openmrs.f542494f33fc3fd1.css} +1 -1
  14. package/lib/{0f63a955dacaced7.js → 0a6b767a56d12e92.js} +5 -5
  15. package/lib/364dacef27c6d708.js +8 -0
  16. package/lib/{29f55baeca95f68a.js → cfeaaf9344214cc7.js} +21 -2
  17. package/lib/index.html +29 -27
  18. package/lib/openmrs.css +83 -14
  19. package/lib/openmrs.js +6 -6
  20. package/package.json +3 -3
  21. package/setup-tests.ts +5 -0
  22. package/src/index.ejs +28 -26
  23. package/src/language-detection.ts +5 -0
  24. package/src/locale.ts +2 -4
  25. package/src/run.test.ts +164 -14
  26. package/src/run.ts +73 -7
  27. package/src/static-page-translations.test.ts +68 -0
  28. package/src/static-page-translations.ts +53 -0
  29. package/src/ui/server-starting.component.tsx +74 -0
  30. package/src/ui/server-starting.test.tsx +45 -0
  31. package/vitest.config.ts +3 -0
  32. package/dist/05ce2d37a1daa834.js +0 -1
  33. package/dist/415d3f92b43b446a.js.map +0 -1
  34. package/dist/ac0d2d52a052f5ee.js +0 -1
  35. package/dist/ac0d2d52a052f5ee.js.map +0 -1
  36. package/lib/28cd0b4d1d48499c.js +0 -8
@@ -491,7 +491,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
491
491
  },
492
492
  "../../framework/esm-styleguide/dist/config-schema.js"(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
493
493
  "use strict";
494
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n esmStyleGuideSchema: () => (esmStyleGuideSchema)\n});\n/* import */ var _openmrs_esm_config__rspack_import_0 = __webpack_require__(\"../../framework/esm-config/dist/index.js\");\n/* import */ var _utils_js__rspack_import_1 = __webpack_require__(\"../../framework/esm-styleguide/dist/utils.js\");\n\n\nconst diagnosisTagConfigSchema = {\n primaryColor: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'The color for displaying primary diagnoses tags',\n _default: 'red',\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf(_utils_js__rspack_import_1.carbonTagColors)\n ]\n },\n secondaryColor: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'The color for displaying secondary diagnoses tags',\n _default: 'blue',\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf(_utils_js__rspack_import_1.carbonTagColors)\n ]\n }\n};\nconst esmStyleGuideSchema = {\n 'Brand color #1': {\n _default: '#005d5d',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n 'Brand color #2': {\n _default: '#004144',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n 'Brand color #3': {\n _default: '#007d79',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n excludePatientIdentifierCodeTypes: {\n uuids: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Array,\n _description: 'List of UUIDs of patient identifier types to exclude from rendering in the patient banner',\n _default: [],\n _elements: {\n _type: _openmrs_esm_config__rspack_import_0.Type.UUID\n }\n }\n },\n implementationName: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'A name of the place (or authority) where all possible locations a user can choose are located.',\n _default: 'Clinic'\n },\n patientPhotoConceptUuid: {\n _type: _openmrs_esm_config__rspack_import_0.Type.ConceptUuid,\n _default: '736e8771-e501-4615-bfa7-570c03f4bef5',\n _description: \"Used to look up the patient photo, which is stored as an attachment obs. Set to `null` in order to disable the feature and use only generated avatars. To remove the avatars entirely, use extension configuration's `remove` feature.\"\n },\n preferredCalendar: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Object,\n _description: \"Keys should be locale codes, and values should be the preferred calendar for that locale. For example, {'am': 'ethiopic'}.\",\n _default: {\n am: 'ethiopic'\n },\n _elements: {\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf([\n 'buddhist',\n 'chinese',\n 'coptic',\n 'dangi',\n 'ethioaa',\n 'ethiopic',\n 'gregory',\n 'hebrew',\n 'indian',\n 'islamic',\n 'islamic-umalqura',\n 'islamic-tbla',\n 'islamic-civil',\n 'islamic-rgsa',\n 'iso8601',\n 'japanese',\n 'persian',\n 'roc',\n 'islamicc'\n ])\n ]\n }\n },\n preferredDateLocale: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Object,\n _description: \"Allows setting the locale used for date formatting for any browser locale. Does not affect time formatting. Keys should be locale codes, and values should be the preferred locale for formatting dates. For example, {'en': 'en-US', 'fr-CA': 'en-CA'}.\",\n _default: {\n en: 'en-GB'\n },\n _elements: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n }\n },\n diagnosisTags: diagnosisTagConfigSchema\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1zdHlsZWd1aWRlL2Rpc3QvY29uZmlnLXNjaGVtYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1zdHlsZWd1aWRlL2Rpc3QvY29uZmlnLXNjaGVtYS5qcz80OGU3Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFR5cGUsIHZhbGlkYXRvcnMgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWNvbmZpZ1wiO1xuaW1wb3J0IHsgY2FyYm9uVGFnQ29sb3JzIH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcbmNvbnN0IGRpYWdub3Npc1RhZ0NvbmZpZ1NjaGVtYSA9IHtcbiAgICBwcmltYXJ5Q29sb3I6IHtcbiAgICAgICAgX3R5cGU6IFR5cGUuU3RyaW5nLFxuICAgICAgICBfZGVzY3JpcHRpb246ICdUaGUgY29sb3IgZm9yIGRpc3BsYXlpbmcgcHJpbWFyeSBkaWFnbm9zZXMgdGFncycsXG4gICAgICAgIF9kZWZhdWx0OiAncmVkJyxcbiAgICAgICAgX3ZhbGlkYXRvcnM6IFtcbiAgICAgICAgICAgIHZhbGlkYXRvcnMub25lT2YoY2FyYm9uVGFnQ29sb3JzKVxuICAgICAgICBdXG4gICAgfSxcbiAgICBzZWNvbmRhcnlDb2xvcjoge1xuICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmcsXG4gICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBjb2xvciBmb3IgZGlzcGxheWluZyBzZWNvbmRhcnkgZGlhZ25vc2VzIHRhZ3MnLFxuICAgICAgICBfZGVmYXVsdDogJ2JsdWUnLFxuICAgICAgICBfdmFsaWRhdG9yczogW1xuICAgICAgICAgICAgdmFsaWRhdG9ycy5vbmVPZihjYXJib25UYWdDb2xvcnMpXG4gICAgICAgIF1cbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGVzbVN0eWxlR3VpZGVTY2hlbWEgPSB7XG4gICAgJ0JyYW5kIGNvbG9yICMxJzoge1xuICAgICAgICBfZGVmYXVsdDogJyMwMDVkNWQnLFxuICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmdcbiAgICB9LFxuICAgICdCcmFuZCBjb2xvciAjMic6IHtcbiAgICAgICAgX2RlZmF1bHQ6ICcjMDA0MTQ0JyxcbiAgICAgICAgX3R5cGU6IFR5cGUuU3RyaW5nXG4gICAgfSxcbiAgICAnQnJhbmQgY29sb3IgIzMnOiB7XG4gICAgICAgIF9kZWZhdWx0OiAnIzAwN2Q3OScsXG4gICAgICAgIF90eXBlOiBUeXBlLlN0cmluZ1xuICAgIH0sXG4gICAgZXhjbHVkZVBhdGllbnRJZGVudGlmaWVyQ29kZVR5cGVzOiB7XG4gICAgICAgIHV1aWRzOiB7XG4gICAgICAgICAgICBfdHlwZTogVHlwZS5BcnJheSxcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ0xpc3Qgb2YgVVVJRHMgb2YgcGF0aWVudCBpZGVudGlmaWVyIHR5cGVzIHRvIGV4Y2x1ZGUgZnJvbSByZW5kZXJpbmcgaW4gdGhlIHBhdGllbnQgYmFubmVyJyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiBbXSxcbiAgICAgICAgICAgIF9lbGVtZW50czoge1xuICAgICAgICAgICAgICAgIF90eXBlOiBUeXBlLlVVSURcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgaW1wbGVtZW50YXRpb25OYW1lOiB7XG4gICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiAnQSBuYW1lIG9mIHRoZSBwbGFjZSAob3IgYXV0aG9yaXR5KSB3aGVyZSBhbGwgcG9zc2libGUgbG9jYXRpb25zIGEgdXNlciBjYW4gY2hvb3NlIGFyZSBsb2NhdGVkLicsXG4gICAgICAgIF9kZWZhdWx0OiAnQ2xpbmljJ1xuICAgIH0sXG4gICAgcGF0aWVudFBob3RvQ29uY2VwdFV1aWQ6IHtcbiAgICAgICAgX3R5cGU6IFR5cGUuQ29uY2VwdFV1aWQsXG4gICAgICAgIF9kZWZhdWx0OiAnNzM2ZTg3NzEtZTUwMS00NjE1LWJmYTctNTcwYzAzZjRiZWY1JyxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiBcIlVzZWQgdG8gbG9vayB1cCB0aGUgcGF0aWVudCBwaG90bywgd2hpY2ggaXMgc3RvcmVkIGFzIGFuIGF0dGFjaG1lbnQgb2JzLiBTZXQgdG8gYG51bGxgIGluIG9yZGVyIHRvIGRpc2FibGUgdGhlIGZlYXR1cmUgYW5kIHVzZSBvbmx5IGdlbmVyYXRlZCBhdmF0YXJzLiBUbyByZW1vdmUgdGhlIGF2YXRhcnMgZW50aXJlbHksIHVzZSBleHRlbnNpb24gY29uZmlndXJhdGlvbidzIGByZW1vdmVgIGZlYXR1cmUuXCJcbiAgICB9LFxuICAgIHByZWZlcnJlZENhbGVuZGFyOiB7XG4gICAgICAgIF90eXBlOiBUeXBlLk9iamVjdCxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiBcIktleXMgc2hvdWxkIGJlIGxvY2FsZSBjb2RlcywgYW5kIHZhbHVlcyBzaG91bGQgYmUgdGhlIHByZWZlcnJlZCBjYWxlbmRhciBmb3IgdGhhdCBsb2NhbGUuIEZvciBleGFtcGxlLCB7J2FtJzogJ2V0aGlvcGljJ30uXCIsXG4gICAgICAgIF9kZWZhdWx0OiB7XG4gICAgICAgICAgICBhbTogJ2V0aGlvcGljJ1xuICAgICAgICB9LFxuICAgICAgICBfZWxlbWVudHM6IHtcbiAgICAgICAgICAgIF92YWxpZGF0b3JzOiBbXG4gICAgICAgICAgICAgICAgdmFsaWRhdG9ycy5vbmVPZihbXG4gICAgICAgICAgICAgICAgICAgICdidWRkaGlzdCcsXG4gICAgICAgICAgICAgICAgICAgICdjaGluZXNlJyxcbiAgICAgICAgICAgICAgICAgICAgJ2NvcHRpYycsXG4gICAgICAgICAgICAgICAgICAgICdkYW5naScsXG4gICAgICAgICAgICAgICAgICAgICdldGhpb2FhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2V0aGlvcGljJyxcbiAgICAgICAgICAgICAgICAgICAgJ2dyZWdvcnknLFxuICAgICAgICAgICAgICAgICAgICAnaGVicmV3JyxcbiAgICAgICAgICAgICAgICAgICAgJ2luZGlhbicsXG4gICAgICAgICAgICAgICAgICAgICdpc2xhbWljJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbGFtaWMtdW1hbHF1cmEnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pYy10YmxhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbGFtaWMtY2l2aWwnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pYy1yZ3NhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbzg2MDEnLFxuICAgICAgICAgICAgICAgICAgICAnamFwYW5lc2UnLFxuICAgICAgICAgICAgICAgICAgICAncGVyc2lhbicsXG4gICAgICAgICAgICAgICAgICAgICdyb2MnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pY2MnXG4gICAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgcHJlZmVycmVkRGF0ZUxvY2FsZToge1xuICAgICAgICBfdHlwZTogVHlwZS5PYmplY3QsXG4gICAgICAgIF9kZXNjcmlwdGlvbjogXCJBbGxvd3Mgc2V0dGluZyB0aGUgbG9jYWxlIHVzZWQgZm9yIGRhdGUgZm9ybWF0dGluZyBmb3IgYW55IGJyb3dzZXIgbG9jYWxlLiBEb2VzIG5vdCBhZmZlY3QgdGltZSBmb3JtYXR0aW5nLiBLZXlzIHNob3VsZCBiZSBsb2NhbGUgY29kZXMsIGFuZCB2YWx1ZXMgc2hvdWxkIGJlIHRoZSBwcmVmZXJyZWQgbG9jYWxlIGZvciBmb3JtYXR0aW5nIGRhdGVzLiBGb3IgZXhhbXBsZSwgeydlbic6ICdlbi1VUycsICdmci1DQSc6ICdlbi1DQSd9LlwiLFxuICAgICAgICBfZGVmYXVsdDoge1xuICAgICAgICAgICAgZW46ICdlbi1HQidcbiAgICAgICAgfSxcbiAgICAgICAgX2VsZW1lbnRzOiB7XG4gICAgICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmdcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZGlhZ25vc2lzVGFnczogZGlhZ25vc2lzVGFnQ29uZmlnU2NoZW1hXG59O1xuIl0sIm5hbWVzIjpbIlR5cGUiLCJ2YWxpZGF0b3JzIiwiY2FyYm9uVGFnQ29sb3JzIiwiZGlhZ25vc2lzVGFnQ29uZmlnU2NoZW1hIiwiZXNtU3R5bGVHdWlkZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQXVEO0FBQ1Y7QUFDN0MsTUFBTUcsMkJBQTJCO0lBQzdCLGNBQWM7UUFDVixPQUFPSCxnREFBVztRQUNsQixjQUFjO1FBQ2QsVUFBVTtRQUNWLGFBQWE7WUFDVEMscURBQWdCLENBQUNDLDBDQUFlQTtTQUNuQztJQUNMO0lBQ0EsZ0JBQWdCO1FBQ1osT0FBT0YsZ0RBQVc7UUFDbEIsY0FBYztRQUNkLFVBQVU7UUFDVixhQUFhO1lBQ1RDLHFEQUFnQixDQUFDQywwQ0FBZUE7U0FDbkM7SUFDTDtBQUNKO0FBQ08sTUFBTUUsc0JBQXNCO0lBQy9CLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPSixnREFBVztJQUN0QjtJQUNBLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPQSxnREFBVztJQUN0QjtJQUNBLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPQSxnREFBVztJQUN0QjtJQUNBLG1DQUFtQztRQUMvQixPQUFPO1lBQ0gsT0FBT0EsK0NBQVU7WUFDakIsY0FBYztZQUNkLFVBQVUsRUFBRTtZQUNaLFdBQVc7Z0JBQ1AsT0FBT0EsOENBQVM7WUFDcEI7UUFDSjtJQUNKO0lBQ0Esb0JBQW9CO1FBQ2hCLE9BQU9BLGdEQUFXO1FBQ2xCLGNBQWM7UUFDZCxVQUFVO0lBQ2Q7SUFDQSx5QkFBeUI7UUFDckIsT0FBT0EscURBQWdCO1FBQ3ZCLFVBQVU7UUFDVixjQUFjO0lBQ2xCO0lBQ0EsbUJBQW1CO1FBQ2YsT0FBT0EsZ0RBQVc7UUFDbEIsY0FBYztRQUNkLFVBQVU7WUFDTixJQUFJO1FBQ1I7UUFDQSxXQUFXO1lBQ1AsYUFBYTtnQkFDVEMscURBQWdCLENBQUM7b0JBQ2I7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7b0JBQ0E7aUJBQ0g7YUFDSjtRQUNMO0lBQ0o7SUFDQSxxQkFBcUI7UUFDakIsT0FBT0QsZ0RBQVc7UUFDbEIsY0FBYztRQUNkLFVBQVU7WUFDTixJQUFJO1FBQ1I7UUFDQSxXQUFXO1lBQ1AsT0FBT0EsZ0RBQVc7UUFDdEI7SUFDSjtJQUNBLGVBQWVHO0FBQ25CLEVBQUUifQ==\n//# sourceURL=webpack-internal:///../../framework/esm-styleguide/dist/config-schema.js\n\n}");
494
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n esmStyleGuideSchema: () => (esmStyleGuideSchema)\n});\n/* import */ var _openmrs_esm_config__rspack_import_0 = __webpack_require__(\"../../framework/esm-config/dist/index.js\");\n/* import */ var _utils_js__rspack_import_1 = __webpack_require__(\"../../framework/esm-styleguide/dist/utils.js\");\n\n\nconst diagnosisTagConfigSchema = {\n primaryColor: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'The color for displaying primary diagnoses tags',\n _default: 'red',\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf(_utils_js__rspack_import_1.carbonTagColors)\n ]\n },\n secondaryColor: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'The color for displaying secondary diagnoses tags',\n _default: 'blue',\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf(_utils_js__rspack_import_1.carbonTagColors)\n ]\n }\n};\nconst esmStyleGuideSchema = {\n 'Brand color #1': {\n _default: '#005d5d',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n 'Brand color #2': {\n _default: '#004144',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n 'Brand color #3': {\n _default: '#007d79',\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n },\n excludePatientIdentifierCodeTypes: {\n uuids: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Array,\n _description: 'List of UUIDs of patient identifier types to exclude from rendering in the patient banner',\n _default: [],\n _elements: {\n _type: _openmrs_esm_config__rspack_import_0.Type.UUID\n }\n }\n },\n implementationName: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _description: 'A name of the place (or authority) where all possible locations a user can choose are located.',\n _default: 'Clinic'\n },\n logo: {\n src: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _default: '',\n _description: 'The path or URL to the logo shown on the login page and while the server is starting up. If set to an empty string, the default OpenMRS logo is used.',\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.isUrl\n ]\n },\n alt: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String,\n _default: 'Logo',\n _description: 'The alternative text for the logo image, displayed when the image cannot be loaded or on hover.'\n }\n },\n patientPhotoConceptUuid: {\n _type: _openmrs_esm_config__rspack_import_0.Type.ConceptUuid,\n _default: '736e8771-e501-4615-bfa7-570c03f4bef5',\n _description: \"Used to look up the patient photo, which is stored as an attachment obs. Set to `null` in order to disable the feature and use only generated avatars. To remove the avatars entirely, use extension configuration's `remove` feature.\"\n },\n preferredCalendar: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Object,\n _description: \"Keys should be locale codes, and values should be the preferred calendar for that locale. For example, {'am': 'ethiopic'}.\",\n _default: {\n am: 'ethiopic'\n },\n _elements: {\n _validators: [\n _openmrs_esm_config__rspack_import_0.validators.oneOf([\n 'buddhist',\n 'chinese',\n 'coptic',\n 'dangi',\n 'ethioaa',\n 'ethiopic',\n 'gregory',\n 'hebrew',\n 'indian',\n 'islamic',\n 'islamic-umalqura',\n 'islamic-tbla',\n 'islamic-civil',\n 'islamic-rgsa',\n 'iso8601',\n 'japanese',\n 'persian',\n 'roc',\n 'islamicc'\n ])\n ]\n }\n },\n preferredDateLocale: {\n _type: _openmrs_esm_config__rspack_import_0.Type.Object,\n _description: \"Allows setting the locale used for date formatting for any browser locale. Does not affect time formatting. Keys should be locale codes, and values should be the preferred locale for formatting dates. For example, {'en': 'en-US', 'fr-CA': 'en-CA'}.\",\n _default: {\n en: 'en-GB'\n },\n _elements: {\n _type: _openmrs_esm_config__rspack_import_0.Type.String\n }\n },\n diagnosisTags: diagnosisTagConfigSchema\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1zdHlsZWd1aWRlL2Rpc3QvY29uZmlnLXNjaGVtYS5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1zdHlsZWd1aWRlL2Rpc3QvY29uZmlnLXNjaGVtYS5qcz80OGU3Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFR5cGUsIHZhbGlkYXRvcnMgfSBmcm9tIFwiQG9wZW5tcnMvZXNtLWNvbmZpZ1wiO1xuaW1wb3J0IHsgY2FyYm9uVGFnQ29sb3JzIH0gZnJvbSBcIi4vdXRpbHMuanNcIjtcbmNvbnN0IGRpYWdub3Npc1RhZ0NvbmZpZ1NjaGVtYSA9IHtcbiAgICBwcmltYXJ5Q29sb3I6IHtcbiAgICAgICAgX3R5cGU6IFR5cGUuU3RyaW5nLFxuICAgICAgICBfZGVzY3JpcHRpb246ICdUaGUgY29sb3IgZm9yIGRpc3BsYXlpbmcgcHJpbWFyeSBkaWFnbm9zZXMgdGFncycsXG4gICAgICAgIF9kZWZhdWx0OiAncmVkJyxcbiAgICAgICAgX3ZhbGlkYXRvcnM6IFtcbiAgICAgICAgICAgIHZhbGlkYXRvcnMub25lT2YoY2FyYm9uVGFnQ29sb3JzKVxuICAgICAgICBdXG4gICAgfSxcbiAgICBzZWNvbmRhcnlDb2xvcjoge1xuICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmcsXG4gICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBjb2xvciBmb3IgZGlzcGxheWluZyBzZWNvbmRhcnkgZGlhZ25vc2VzIHRhZ3MnLFxuICAgICAgICBfZGVmYXVsdDogJ2JsdWUnLFxuICAgICAgICBfdmFsaWRhdG9yczogW1xuICAgICAgICAgICAgdmFsaWRhdG9ycy5vbmVPZihjYXJib25UYWdDb2xvcnMpXG4gICAgICAgIF1cbiAgICB9XG59O1xuZXhwb3J0IGNvbnN0IGVzbVN0eWxlR3VpZGVTY2hlbWEgPSB7XG4gICAgJ0JyYW5kIGNvbG9yICMxJzoge1xuICAgICAgICBfZGVmYXVsdDogJyMwMDVkNWQnLFxuICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmdcbiAgICB9LFxuICAgICdCcmFuZCBjb2xvciAjMic6IHtcbiAgICAgICAgX2RlZmF1bHQ6ICcjMDA0MTQ0JyxcbiAgICAgICAgX3R5cGU6IFR5cGUuU3RyaW5nXG4gICAgfSxcbiAgICAnQnJhbmQgY29sb3IgIzMnOiB7XG4gICAgICAgIF9kZWZhdWx0OiAnIzAwN2Q3OScsXG4gICAgICAgIF90eXBlOiBUeXBlLlN0cmluZ1xuICAgIH0sXG4gICAgZXhjbHVkZVBhdGllbnRJZGVudGlmaWVyQ29kZVR5cGVzOiB7XG4gICAgICAgIHV1aWRzOiB7XG4gICAgICAgICAgICBfdHlwZTogVHlwZS5BcnJheSxcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ0xpc3Qgb2YgVVVJRHMgb2YgcGF0aWVudCBpZGVudGlmaWVyIHR5cGVzIHRvIGV4Y2x1ZGUgZnJvbSByZW5kZXJpbmcgaW4gdGhlIHBhdGllbnQgYmFubmVyJyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiBbXSxcbiAgICAgICAgICAgIF9lbGVtZW50czoge1xuICAgICAgICAgICAgICAgIF90eXBlOiBUeXBlLlVVSURcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgaW1wbGVtZW50YXRpb25OYW1lOiB7XG4gICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiAnQSBuYW1lIG9mIHRoZSBwbGFjZSAob3IgYXV0aG9yaXR5KSB3aGVyZSBhbGwgcG9zc2libGUgbG9jYXRpb25zIGEgdXNlciBjYW4gY2hvb3NlIGFyZSBsb2NhdGVkLicsXG4gICAgICAgIF9kZWZhdWx0OiAnQ2xpbmljJ1xuICAgIH0sXG4gICAgbG9nbzoge1xuICAgICAgICBzcmM6IHtcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiAnJyxcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBwYXRoIG9yIFVSTCB0byB0aGUgbG9nbyBzaG93biBvbiB0aGUgbG9naW4gcGFnZSBhbmQgd2hpbGUgdGhlIHNlcnZlciBpcyBzdGFydGluZyB1cC4gSWYgc2V0IHRvIGFuIGVtcHR5IHN0cmluZywgdGhlIGRlZmF1bHQgT3Blbk1SUyBsb2dvIGlzIHVzZWQuJyxcbiAgICAgICAgICAgIF92YWxpZGF0b3JzOiBbXG4gICAgICAgICAgICAgICAgdmFsaWRhdG9ycy5pc1VybFxuICAgICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICBhbHQ6IHtcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiAnTG9nbycsXG4gICAgICAgICAgICBfZGVzY3JpcHRpb246ICdUaGUgYWx0ZXJuYXRpdmUgdGV4dCBmb3IgdGhlIGxvZ28gaW1hZ2UsIGRpc3BsYXllZCB3aGVuIHRoZSBpbWFnZSBjYW5ub3QgYmUgbG9hZGVkIG9yIG9uIGhvdmVyLidcbiAgICAgICAgfVxuICAgIH0sXG4gICAgcGF0aWVudFBob3RvQ29uY2VwdFV1aWQ6IHtcbiAgICAgICAgX3R5cGU6IFR5cGUuQ29uY2VwdFV1aWQsXG4gICAgICAgIF9kZWZhdWx0OiAnNzM2ZTg3NzEtZTUwMS00NjE1LWJmYTctNTcwYzAzZjRiZWY1JyxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiBcIlVzZWQgdG8gbG9vayB1cCB0aGUgcGF0aWVudCBwaG90bywgd2hpY2ggaXMgc3RvcmVkIGFzIGFuIGF0dGFjaG1lbnQgb2JzLiBTZXQgdG8gYG51bGxgIGluIG9yZGVyIHRvIGRpc2FibGUgdGhlIGZlYXR1cmUgYW5kIHVzZSBvbmx5IGdlbmVyYXRlZCBhdmF0YXJzLiBUbyByZW1vdmUgdGhlIGF2YXRhcnMgZW50aXJlbHksIHVzZSBleHRlbnNpb24gY29uZmlndXJhdGlvbidzIGByZW1vdmVgIGZlYXR1cmUuXCJcbiAgICB9LFxuICAgIHByZWZlcnJlZENhbGVuZGFyOiB7XG4gICAgICAgIF90eXBlOiBUeXBlLk9iamVjdCxcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiBcIktleXMgc2hvdWxkIGJlIGxvY2FsZSBjb2RlcywgYW5kIHZhbHVlcyBzaG91bGQgYmUgdGhlIHByZWZlcnJlZCBjYWxlbmRhciBmb3IgdGhhdCBsb2NhbGUuIEZvciBleGFtcGxlLCB7J2FtJzogJ2V0aGlvcGljJ30uXCIsXG4gICAgICAgIF9kZWZhdWx0OiB7XG4gICAgICAgICAgICBhbTogJ2V0aGlvcGljJ1xuICAgICAgICB9LFxuICAgICAgICBfZWxlbWVudHM6IHtcbiAgICAgICAgICAgIF92YWxpZGF0b3JzOiBbXG4gICAgICAgICAgICAgICAgdmFsaWRhdG9ycy5vbmVPZihbXG4gICAgICAgICAgICAgICAgICAgICdidWRkaGlzdCcsXG4gICAgICAgICAgICAgICAgICAgICdjaGluZXNlJyxcbiAgICAgICAgICAgICAgICAgICAgJ2NvcHRpYycsXG4gICAgICAgICAgICAgICAgICAgICdkYW5naScsXG4gICAgICAgICAgICAgICAgICAgICdldGhpb2FhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2V0aGlvcGljJyxcbiAgICAgICAgICAgICAgICAgICAgJ2dyZWdvcnknLFxuICAgICAgICAgICAgICAgICAgICAnaGVicmV3JyxcbiAgICAgICAgICAgICAgICAgICAgJ2luZGlhbicsXG4gICAgICAgICAgICAgICAgICAgICdpc2xhbWljJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbGFtaWMtdW1hbHF1cmEnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pYy10YmxhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbGFtaWMtY2l2aWwnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pYy1yZ3NhJyxcbiAgICAgICAgICAgICAgICAgICAgJ2lzbzg2MDEnLFxuICAgICAgICAgICAgICAgICAgICAnamFwYW5lc2UnLFxuICAgICAgICAgICAgICAgICAgICAncGVyc2lhbicsXG4gICAgICAgICAgICAgICAgICAgICdyb2MnLFxuICAgICAgICAgICAgICAgICAgICAnaXNsYW1pY2MnXG4gICAgICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgfVxuICAgIH0sXG4gICAgcHJlZmVycmVkRGF0ZUxvY2FsZToge1xuICAgICAgICBfdHlwZTogVHlwZS5PYmplY3QsXG4gICAgICAgIF9kZXNjcmlwdGlvbjogXCJBbGxvd3Mgc2V0dGluZyB0aGUgbG9jYWxlIHVzZWQgZm9yIGRhdGUgZm9ybWF0dGluZyBmb3IgYW55IGJyb3dzZXIgbG9jYWxlLiBEb2VzIG5vdCBhZmZlY3QgdGltZSBmb3JtYXR0aW5nLiBLZXlzIHNob3VsZCBiZSBsb2NhbGUgY29kZXMsIGFuZCB2YWx1ZXMgc2hvdWxkIGJlIHRoZSBwcmVmZXJyZWQgbG9jYWxlIGZvciBmb3JtYXR0aW5nIGRhdGVzLiBGb3IgZXhhbXBsZSwgeydlbic6ICdlbi1VUycsICdmci1DQSc6ICdlbi1DQSd9LlwiLFxuICAgICAgICBfZGVmYXVsdDoge1xuICAgICAgICAgICAgZW46ICdlbi1HQidcbiAgICAgICAgfSxcbiAgICAgICAgX2VsZW1lbnRzOiB7XG4gICAgICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmdcbiAgICAgICAgfVxuICAgIH0sXG4gICAgZGlhZ25vc2lzVGFnczogZGlhZ25vc2lzVGFnQ29uZmlnU2NoZW1hXG59O1xuIl0sIm5hbWVzIjpbIlR5cGUiLCJ2YWxpZGF0b3JzIiwiY2FyYm9uVGFnQ29sb3JzIiwiZGlhZ25vc2lzVGFnQ29uZmlnU2NoZW1hIiwiZXNtU3R5bGVHdWlkZVNjaGVtYSJdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQXVEO0FBQ1Y7QUFDN0MsTUFBTUcsMkJBQTJCO0lBQzdCLGNBQWM7UUFDVixPQUFPSCxnREFBVztRQUNsQixjQUFjO1FBQ2QsVUFBVTtRQUNWLGFBQWE7WUFDVEMscURBQWdCLENBQUNDLDBDQUFlQTtTQUNuQztJQUNMO0lBQ0EsZ0JBQWdCO1FBQ1osT0FBT0YsZ0RBQVc7UUFDbEIsY0FBYztRQUNkLFVBQVU7UUFDVixhQUFhO1lBQ1RDLHFEQUFnQixDQUFDQywwQ0FBZUE7U0FDbkM7SUFDTDtBQUNKO0FBQ08sTUFBTUUsc0JBQXNCO0lBQy9CLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPSixnREFBVztJQUN0QjtJQUNBLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPQSxnREFBVztJQUN0QjtJQUNBLGtCQUFrQjtRQUNkLFVBQVU7UUFDVixPQUFPQSxnREFBVztJQUN0QjtJQUNBLG1DQUFtQztRQUMvQixPQUFPO1lBQ0gsT0FBT0EsK0NBQVU7WUFDakIsY0FBYztZQUNkLFVBQVUsRUFBRTtZQUNaLFdBQVc7Z0JBQ1AsT0FBT0EsOENBQVM7WUFDcEI7UUFDSjtJQUNKO0lBQ0Esb0JBQW9CO1FBQ2hCLE9BQU9BLGdEQUFXO1FBQ2xCLGNBQWM7UUFDZCxVQUFVO0lBQ2Q7SUFDQSxNQUFNO1FBQ0YsS0FBSztZQUNELE9BQU9BLGdEQUFXO1lBQ2xCLFVBQVU7WUFDVixjQUFjO1lBQ2QsYUFBYTtnQkFDVEMscURBQWdCO2FBQ25CO1FBQ0w7UUFDQSxLQUFLO1lBQ0QsT0FBT0QsZ0RBQVc7WUFDbEIsVUFBVTtZQUNWLGNBQWM7UUFDbEI7SUFDSjtJQUNBLHlCQUF5QjtRQUNyQixPQUFPQSxxREFBZ0I7UUFDdkIsVUFBVTtRQUNWLGNBQWM7SUFDbEI7SUFDQSxtQkFBbUI7UUFDZixPQUFPQSxnREFBVztRQUNsQixjQUFjO1FBQ2QsVUFBVTtZQUNOLElBQUk7UUFDUjtRQUNBLFdBQVc7WUFDUCxhQUFhO2dCQUNUQyxxREFBZ0IsQ0FBQztvQkFDYjtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtvQkFDQTtpQkFDSDthQUNKO1FBQ0w7SUFDSjtJQUNBLHFCQUFxQjtRQUNqQixPQUFPRCxnREFBVztRQUNsQixjQUFjO1FBQ2QsVUFBVTtZQUNOLElBQUk7UUFDUjtRQUNBLFdBQVc7WUFDUCxPQUFPQSxnREFBVztRQUN0QjtJQUNKO0lBQ0EsZUFBZUc7QUFDbkIsRUFBRSJ9\n//# sourceURL=webpack-internal:///../../framework/esm-styleguide/dist/config-schema.js\n\n}");
495
495
 
496
496
  },
497
497
  "../../framework/esm-styleguide/dist/custom-overflow-menu/custom-overflow-menu.component.js"(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
@@ -4456,7 +4456,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
4456
4456
  },
4457
4457
  "../../framework/esm-api/dist/current-user.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
4458
4458
  "use strict";
4459
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n clearCurrentUser: () => (clearCurrentUser),\n getCurrentUser: () => (getCurrentUser),\n getLoggedInUser: () => (getLoggedInUser),\n getSessionLocation: () => (getSessionLocation),\n getSessionStore: () => (getSessionStore),\n logout: () => (logout),\n refetchCurrentUser: () => (refetchCurrentUser),\n sessionStore: () => (sessionStore),\n setSessionLocale: () => (setSessionLocale),\n setSessionLocation: () => (setSessionLocation),\n setUserLanguage: () => (setUserLanguage),\n setUserProperties: () => (setUserProperties),\n userHasAccess: () => (userHasAccess),\n verifyTotpCode: () => (verifyTotpCode)\n});\n/* import */ var _openmrs_esm_error_handling__rspack_import_0 = __webpack_require__(\"../../framework/esm-error-handling/dist/index.js\");\n/* import */ var _openmrs_esm_state__rspack_import_1 = __webpack_require__(\"../../framework/esm-state/dist/index.js\");\n/* import */ var lodash_es__rspack_import_3 = __webpack_require__(\"../../../node_modules/lodash-es/isUndefined.js\");\n/* import */ var _openmrs_fetch_js__rspack_import_2 = __webpack_require__(\"../../framework/esm-api/dist/openmrs-fetch.js\");\n/** @module @category API */ \n\n\n\n/** @internal */ const sessionStore = (0,_openmrs_esm_state__rspack_import_1.createGlobalStore)('session', {\n loaded: false,\n session: null\n});\n/**\n * The upper bound on how old the session handed to a reader may be. It is measured from the moment a\n * fetch is *started*, not from the moment its response lands, so the session a reader sees is always\n * strictly newer than this.\n */ const sessionMaxAgeMillis = 60 * 1000;\nlet lastFetchTimeMillis = 0;\nlet inFlightRefresh = null;\n/**\n * Fetches the session if the store is unloaded or its session is older than `sessionMaxAgeMillis`.\n * Returns `null` only when the store already holds a session fresh enough to be read as-is, so a\n * caller that gets a promise back must wait for it rather than read the store.\n *\n * A fetch already in flight is joined rather than duplicated. This is what keeps `sessionMaxAgeMillis`\n * an upper bound: while a fetch is running, the store still holds the previous session, and returning\n * that would hand back data older than the bound allows.\n *\n * The returned promise rejects if the fetch fails, but the rejection is already handled and reported,\n * so a caller that only needs the fetch started can ignore it.\n */ function refreshSessionIfStale() {\n if (inFlightRefresh) {\n return inFlightRefresh;\n }\n if (sessionStore.getState().loaded && lastFetchTimeMillis >= Date.now() - sessionMaxAgeMillis) {\n return null;\n }\n return refetchCurrentUser();\n}\nfunction getCurrentUser(opts) {\n const includeAuthStatus = opts?.includeAuthStatus ?? true;\n const select = (session)=>includeAuthStatus ? session : session.user;\n const refresh = refreshSessionIfStale();\n if (!refresh) {\n return Promise.resolve(select(sessionStore.getState().session));\n }\n return new Promise((resolve)=>{\n const resolveIfLoaded = ()=>{\n const state = sessionStore.getState();\n if (state.loaded) {\n unsubscribe();\n resolve(select(state.session));\n }\n };\n const unsubscribe = sessionStore.subscribe(resolveIfLoaded);\n // A failed refresh keeps an already-loaded session without updating the store, so the\n // subscription alone would never fire.\n refresh.then(resolveIfLoaded, resolveIfLoaded);\n });\n}\n\n/**\n * Returns the global session store containing the current user's session information.\n * If the session data is stale (older than 1 minute) or not yet loaded, this function\n * will trigger a refetch of the current user's session.\n *\n * @returns The global session store that can be subscribed to for session updates.\n *\n * @example\n * ```ts\n * import { getSessionStore } from '@openmrs/esm-api';\n * const store = getSessionStore();\n * const unsubscribe = store.subscribe((state) => {\n * if (state.loaded) {\n * console.log('Session:', state.session);\n * }\n * });\n * ```\n */ function getSessionStore() {\n refreshSessionIfStale();\n return sessionStore;\n}\n// NB locale is string only if this returns true\nfunction isValidLocale(locale) {\n if (locale === undefined || typeof locale !== 'string') {\n return false;\n }\n try {\n new Intl.Locale(locale);\n } catch (e) {\n return false;\n }\n return true;\n}\n/**\n * Sets the document's language attribute based on the user's locale preference\n * from the session data. This affects the HTML `lang` attribute which is used\n * for accessibility and internationalization.\n *\n * The locale is determined from either the session's locale or the user's\n * default locale property. Underscores in the locale are converted to hyphens\n * to match BCP 47 language tag format.\n *\n * @param data The session object containing locale information.\n */ function setUserLanguage(data) {\n let locale = data.locale ?? data.user?.userProperties?.defaultLocale;\n // Only underscores are converted here, deliberately, rather than reusing `toLanguageTag`. i18next\n // reads this value back off `document.lang` and uses it as the translation bundle key, and those\n // bundles are named with the POSIX form (`uz@Latn.json`), so converting `@` would send the loader\n // after a bundle that does not exist.\n if (locale && locale.includes('_')) {\n locale = locale.replaceAll('_', '-');\n }\n if (isValidLocale(locale) && locale !== document.documentElement.getAttribute('lang')) {\n document.documentElement.setAttribute('lang', locale);\n }\n}\nsessionStore.subscribe((state)=>{\n if (state.loaded && state.session) {\n setUserLanguage(state.session);\n }\n});\nfunction userHasPrivilege(requiredPrivilege, user) {\n if (typeof requiredPrivilege === 'string') {\n return !(0,lodash_es__rspack_import_3[\"default\"])(user.privileges.find((p)=>requiredPrivilege === p.display));\n } else if (Array.isArray(requiredPrivilege)) {\n return requiredPrivilege.every((rp)=>!(0,lodash_es__rspack_import_3[\"default\"])(user.privileges.find((p)=>rp === p.display)));\n } else if (!(0,lodash_es__rspack_import_3[\"default\"])(requiredPrivilege)) {\n console.error(`Could not understand privileges \"${requiredPrivilege}\"`);\n }\n return true;\n}\nfunction isSuperUser(user) {\n return !(0,lodash_es__rspack_import_3[\"default\"])(user.roles.find((role)=>role.display === 'System Developer'));\n}\n/**\n * The `refetchCurrentUser` function causes a network request to redownload\n * the user. All subscribers to the session store will be notified of the\n * new user once the new version of the user object is downloaded.\n *\n * If the server rejects the request as unauthenticated (401 or 403), the store records a\n * logged-out session. If the request fails for any other reason, a session that has already\n * loaded is kept; otherwise the store records the error.\n *\n * @returns A Promise resolving to the updated session store state. It rejects with the\n * store state if the request fails for a reason other than authentication.\n *\n * @example\n * ```js\n * import { refetchCurrentUser } from '@openmrs/esm-api'\n * refetchCurrentUser()\n * ```\n */ function refetchCurrentUser(username, password) {\n lastFetchTimeMillis = Date.now();\n let headers = {};\n if (username && password) {\n headers['Authorization'] = `Basic ${window.btoa(`${username}:${password}`)}`;\n }\n const refresh = handleSessionResponse((0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n headers,\n rejectAuthFailure: true\n }));\n // Publish the request so that readers can wait on it instead of reading the session it is about to\n // replace. Each call still issues its own request; this only tracks the most recent one.\n const clear = ()=>{\n if (inFlightRefresh === refresh) {\n inFlightRefresh = null;\n }\n };\n refresh.then(clear, clear);\n inFlightRefresh = refresh;\n return refresh;\n}\n/**\n * Clears the current user session from the session store, setting the session\n * to an unauthenticated state. This is typically called during logout to reset\n * the application's authentication state.\n *\n * @example\n * ```ts\n * import { clearCurrentUser } from '@openmrs/esm-api';\n * // During logout\n * clearCurrentUser();\n * ```\n */ function clearCurrentUser() {\n sessionStore.setState({\n loaded: true,\n session: {\n authenticated: false,\n sessionId: ''\n }\n }, true);\n}\n/**\n * Checks whether the given user has access based on the required privilege(s).\n * A user has access if they have the required privilege(s) or if they are a\n * \"System Developer\" (super user). If no privilege is required, access is granted.\n *\n * @param requiredPrivilege A single privilege string or an array of privilege strings\n * that the user must have. If an array is provided, the user must have ALL privileges.\n * @param user The user object containing their privileges and roles.\n * @returns `true` if the user has access, `false` otherwise. Returns `true` if no\n * privilege is required, and `false` if the user is undefined but a privilege is required.\n *\n * @example\n * ```ts\n * import { userHasAccess } from '@openmrs/esm-api';\n * const hasAccess = userHasAccess('View Patients', currentUser);\n * const hasMultipleAccess = userHasAccess(['View Patients', 'Edit Patients'], currentUser);\n * ```\n */ function userHasAccess(requiredPrivilege, user) {\n if (user === undefined) {\n // if the user hasn't been loaded, then return false iff there is a required privilege\n return !Boolean(requiredPrivilege);\n }\n if (!Boolean(requiredPrivilege)) {\n // if user exists but no requiredPrivilege is defined\n return true;\n }\n return userHasPrivilege(requiredPrivilege, user) || isSuperUser(user);\n}\n/**\n * Returns a Promise that resolves with the currently logged-in user object.\n * If the user is already loaded in the session store, the Promise resolves immediately.\n * Otherwise, it subscribes to the session store and resolves when a logged-in user\n * becomes available.\n *\n * @returns A Promise that resolves with the LoggedInUser object once available.\n *\n * @example\n * ```ts\n * import { getLoggedInUser } from '@openmrs/esm-api';\n * const user = await getLoggedInUser();\n * console.log('Logged in as:', user.display);\n * ```\n */ function getLoggedInUser() {\n let user;\n let unsubscribe;\n return new Promise((res)=>{\n const handler = (state)=>{\n if (state.loaded && state.session.user) {\n user = state.session.user;\n res(state.session.user);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n };\n handler(sessionStore.getState());\n if (!user) {\n unsubscribe = sessionStore.subscribe(handler);\n }\n });\n}\n/**\n * Returns a Promise that resolves with the current session location, if one is set.\n * The session location represents the physical location where the user is currently\n * working (e.g., a clinic or ward).\n *\n * @returns A Promise that resolves with the SessionLocation object, or `undefined`\n * if no session location is set.\n *\n * @example\n * ```ts\n * import { getSessionLocation } from '@openmrs/esm-api';\n * const location = await getSessionLocation();\n * if (location) {\n * console.log('Current location:', location.display);\n * }\n * ```\n */ async function getSessionLocation() {\n const session = await getCurrentUser();\n return session.sessionLocation;\n}\n/**\n * Sets the session location for the current user. The session location represents\n * the physical location where the user is working (e.g., a clinic or ward).\n * This triggers a server request to update the session and refreshes the local\n * session store.\n *\n * @param locationUuid The UUID of the location to set as the session location.\n * @param abortController An AbortController to allow cancellation of the request.\n * @returns A Promise that resolves with the updated SessionStore.\n *\n * @example\n * ```ts\n * import { setSessionLocation } from '@openmrs/esm-api';\n * const abortController = new AbortController();\n * await setSessionLocation('location-uuid-here', abortController);\n * ```\n */ async function setSessionLocation(locationUuid, abortController) {\n return handleSessionResponse((0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'POST',\n body: {\n sessionLocation: locationUuid\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n rejectAuthFailure: true,\n signal: abortController?.signal\n }));\n}\n/**\n * Sets the locale for the current session only, leaving the user's default locale unchanged.\n * Use {@link setUserProperties} with a `defaultLocale` property to change the default instead.\n *\n * @param locale The locale in Java's `Locale#toString()` form, e.g. `en_GB`.\n * @param abortController Optional AbortController to allow cancellation of the request.\n * @returns A Promise that resolves with the updated SessionStore after refetching the current user.\n * It rejects with an {@link OpenmrsFetchError} if the server does not accept the locale.\n *\n * @example\n * ```ts\n * import { setSessionLocale } from '@openmrs/esm-api';\n * await setSessionLocale('fr');\n * ```\n *\n * @internal\n */ async function setSessionLocale(locale, abortController) {\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'POST',\n body: {\n locale\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: abortController?.signal\n });\n return refetchCurrentUser();\n}\n/**\n * Updates the user properties for a specific user. User properties are key-value\n * pairs that store user-specific settings and preferences. After updating the\n * properties on the server, the current user session is refetched to reflect\n * the changes.\n *\n * @param userUuid The UUID of the user whose properties should be updated.\n * @param userProperties An object containing the properties to set or update.\n * @param abortController Optional AbortController to allow cancellation of the request.\n * If not provided, a new AbortController is created.\n * @returns A Promise that resolves with the updated SessionStore after refetching\n * the current user.\n *\n * @example\n * ```ts\n * import { getLoggedInUser, setUserProperties } from '@openmrs/esm-api';\n * const user = await getLoggedInUser();\n * await setUserProperties(user.uuid, {\n * defaultLocale: 'en_GB',\n * customSetting: 'value'\n * });\n * ```\n */ async function setUserProperties(userUuid, userProperties, abortController) {\n if (!abortController) {\n abortController = new AbortController();\n }\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(`${_openmrs_fetch_js__rspack_import_2.restBaseUrl}/user/${userUuid}`, {\n method: 'POST',\n body: {\n userProperties\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: abortController.signal\n });\n return refetchCurrentUser();\n}\n/**\n * Submits a TOTP code to complete a two-factor login challenge. When the code is accepted, the\n * session store is refreshed with the now-authenticated session.\n *\n * @param code The code from the user's authenticator app.\n * @param rememberDevice Whether the server should skip the challenge on this device in future.\n * @returns A Promise resolving to the session. Its `authenticated` property is `false` if the\n * code was not accepted. It rejects with an {@link OpenmrsFetchError} if the server rejects the\n * request, in which case `responseBody` may explain why.\n *\n * @example\n * ```ts\n * import { verifyTotpCode } from '@openmrs/esm-api';\n * const session = await verifyTotpCode('123456', true);\n * ```\n *\n * @internal\n */ async function verifyTotpCode(code, rememberDevice = false) {\n const response = await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(rememberDevice ? `${_openmrs_fetch_js__rspack_import_2.sessionEndpoint}?rememberMe=true` : _openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n headers: {\n 'X-Totp-Code': code\n }\n });\n if (response.data?.authenticated) {\n // `refetchCurrentUser` only resolves once the store holds a session.\n const store = await refetchCurrentUser();\n return store.session;\n }\n return response.data;\n}\n/**\n * Ends the current session on the server and records a logged-out session in the session store.\n * A server that has already ended the session (401 or 403) counts as a successful logout.\n *\n * Other data cached for the logged-in user, such as SWR caches, is the caller's to clear.\n *\n * @returns A Promise that resolves once the session store holds a logged-out session.\n *\n * @example\n * ```ts\n * import { logout } from '@openmrs/esm-api';\n * await logout();\n * ```\n *\n * @internal\n */ async function logout() {\n try {\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'DELETE',\n rejectAuthFailure: true\n });\n } catch (err) {\n if (!isAuthFailure(err)) {\n throw err;\n }\n }\n clearCurrentUser();\n // The session just cleared is already correct, so a failed refresh loses nothing.\n await refetchCurrentUser().catch(()=>{});\n}\nfunction handleSessionResponse(result) {\n return new Promise((resolve, reject)=>{\n result.then((res)=>{\n if (typeof res?.data === 'object') {\n const nextState = {\n loaded: true,\n session: res.data\n };\n sessionStore.setState(nextState, true);\n resolve(nextState);\n } else {\n reject(recordSessionFailure(Error('The session endpoint did not respond with a session')));\n }\n }).catch((err)=>{\n // An auth failure is the session endpoint's answer for \"not logged in\", not a failed lookup.\n if (isAuthFailure(err)) {\n if (isUnauthenticatedSession(err.responseBody)) {\n sessionStore.setState({\n loaded: true,\n session: err.responseBody\n }, true);\n } else {\n clearCurrentUser();\n }\n resolve(sessionStore.getState());\n return;\n }\n (0,_openmrs_esm_error_handling__rspack_import_0.reportError)(`Failed to fetch new session information: ${err}`);\n reject(recordSessionFailure(err));\n });\n });\n}\nfunction isAuthFailure(err) {\n return err instanceof _openmrs_fetch_js__rspack_import_2.OpenmrsFetchError && (err.response.status === 401 || err.response.status === 403);\n}\nfunction isUnauthenticatedSession(body) {\n return typeof body === 'object' && body !== null && body.authenticated === false;\n}\n/**\n * A session that has already loaded is kept when a later fetch fails, since it is still the best answer\n * available. With nothing to fall back on, the error is recorded so the app shell can show an error page.\n */ function recordSessionFailure(err) {\n if (!sessionStore.getState().loaded) {\n sessionStore.setState({\n loaded: false,\n session: null,\n error: err instanceof Error ? err : Error(String(err))\n }, true);\n }\n return sessionStore.getState();\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1hcGkvZGlzdC9jdXJyZW50LXVzZXIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tYXBpL2Rpc3QvY3VycmVudC11c2VyLmpzPzcxMjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBtb2R1bGUgQGNhdGVnb3J5IEFQSSAqLyBpbXBvcnQgeyByZXBvcnRFcnJvciB9IGZyb20gXCJAb3Blbm1ycy9lc20tZXJyb3ItaGFuZGxpbmdcIjtcbmltcG9ydCB7IGNyZWF0ZUdsb2JhbFN0b3JlIH0gZnJvbSBcIkBvcGVubXJzL2VzbS1zdGF0ZVwiO1xuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tIFwibG9kYXNoLWVzXCI7XG5pbXBvcnQgeyBPcGVubXJzRmV0Y2hFcnJvciwgb3Blbm1yc0ZldGNoLCByZXN0QmFzZVVybCwgc2Vzc2lvbkVuZHBvaW50IH0gZnJvbSBcIi4vb3Blbm1ycy1mZXRjaC5qc1wiO1xuLyoqIEBpbnRlcm5hbCAqLyBleHBvcnQgY29uc3Qgc2Vzc2lvblN0b3JlID0gY3JlYXRlR2xvYmFsU3RvcmUoJ3Nlc3Npb24nLCB7XG4gICAgbG9hZGVkOiBmYWxzZSxcbiAgICBzZXNzaW9uOiBudWxsXG59KTtcbi8qKlxuICogVGhlIHVwcGVyIGJvdW5kIG9uIGhvdyBvbGQgdGhlIHNlc3Npb24gaGFuZGVkIHRvIGEgcmVhZGVyIG1heSBiZS4gSXQgaXMgbWVhc3VyZWQgZnJvbSB0aGUgbW9tZW50IGFcbiAqIGZldGNoIGlzICpzdGFydGVkKiwgbm90IGZyb20gdGhlIG1vbWVudCBpdHMgcmVzcG9uc2UgbGFuZHMsIHNvIHRoZSBzZXNzaW9uIGEgcmVhZGVyIHNlZXMgaXMgYWx3YXlzXG4gKiBzdHJpY3RseSBuZXdlciB0aGFuIHRoaXMuXG4gKi8gY29uc3Qgc2Vzc2lvbk1heEFnZU1pbGxpcyA9IDYwICogMTAwMDtcbmxldCBsYXN0RmV0Y2hUaW1lTWlsbGlzID0gMDtcbmxldCBpbkZsaWdodFJlZnJlc2ggPSBudWxsO1xuLyoqXG4gKiBGZXRjaGVzIHRoZSBzZXNzaW9uIGlmIHRoZSBzdG9yZSBpcyB1bmxvYWRlZCBvciBpdHMgc2Vzc2lvbiBpcyBvbGRlciB0aGFuIGBzZXNzaW9uTWF4QWdlTWlsbGlzYC5cbiAqIFJldHVybnMgYG51bGxgIG9ubHkgd2hlbiB0aGUgc3RvcmUgYWxyZWFkeSBob2xkcyBhIHNlc3Npb24gZnJlc2ggZW5vdWdoIHRvIGJlIHJlYWQgYXMtaXMsIHNvIGFcbiAqIGNhbGxlciB0aGF0IGdldHMgYSBwcm9taXNlIGJhY2sgbXVzdCB3YWl0IGZvciBpdCByYXRoZXIgdGhhbiByZWFkIHRoZSBzdG9yZS5cbiAqXG4gKiBBIGZldGNoIGFscmVhZHkgaW4gZmxpZ2h0IGlzIGpvaW5lZCByYXRoZXIgdGhhbiBkdXBsaWNhdGVkLiBUaGlzIGlzIHdoYXQga2VlcHMgYHNlc3Npb25NYXhBZ2VNaWxsaXNgXG4gKiBhbiB1cHBlciBib3VuZDogd2hpbGUgYSBmZXRjaCBpcyBydW5uaW5nLCB0aGUgc3RvcmUgc3RpbGwgaG9sZHMgdGhlIHByZXZpb3VzIHNlc3Npb24sIGFuZCByZXR1cm5pbmdcbiAqIHRoYXQgd291bGQgaGFuZCBiYWNrIGRhdGEgb2xkZXIgdGhhbiB0aGUgYm91bmQgYWxsb3dzLlxuICpcbiAqIFRoZSByZXR1cm5lZCBwcm9taXNlIHJlamVjdHMgaWYgdGhlIGZldGNoIGZhaWxzLCBidXQgdGhlIHJlamVjdGlvbiBpcyBhbHJlYWR5IGhhbmRsZWQgYW5kIHJlcG9ydGVkLFxuICogc28gYSBjYWxsZXIgdGhhdCBvbmx5IG5lZWRzIHRoZSBmZXRjaCBzdGFydGVkIGNhbiBpZ25vcmUgaXQuXG4gKi8gZnVuY3Rpb24gcmVmcmVzaFNlc3Npb25JZlN0YWxlKCkge1xuICAgIGlmIChpbkZsaWdodFJlZnJlc2gpIHtcbiAgICAgICAgcmV0dXJuIGluRmxpZ2h0UmVmcmVzaDtcbiAgICB9XG4gICAgaWYgKHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLmxvYWRlZCAmJiBsYXN0RmV0Y2hUaW1lTWlsbGlzID49IERhdGUubm93KCkgLSBzZXNzaW9uTWF4QWdlTWlsbGlzKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICByZXR1cm4gcmVmZXRjaEN1cnJlbnRVc2VyKCk7XG59XG5mdW5jdGlvbiBnZXRDdXJyZW50VXNlcihvcHRzKSB7XG4gICAgY29uc3QgaW5jbHVkZUF1dGhTdGF0dXMgPSBvcHRzPy5pbmNsdWRlQXV0aFN0YXR1cyA/PyB0cnVlO1xuICAgIGNvbnN0IHNlbGVjdCA9IChzZXNzaW9uKT0+aW5jbHVkZUF1dGhTdGF0dXMgPyBzZXNzaW9uIDogc2Vzc2lvbi51c2VyO1xuICAgIGNvbnN0IHJlZnJlc2ggPSByZWZyZXNoU2Vzc2lvbklmU3RhbGUoKTtcbiAgICBpZiAoIXJlZnJlc2gpIHtcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShzZWxlY3Qoc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkuc2Vzc2lvbikpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpPT57XG4gICAgICAgIGNvbnN0IHJlc29sdmVJZkxvYWRlZCA9ICgpPT57XG4gICAgICAgICAgICBjb25zdCBzdGF0ZSA9IHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpO1xuICAgICAgICAgICAgaWYgKHN0YXRlLmxvYWRlZCkge1xuICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlKCk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShzZWxlY3Qoc3RhdGUuc2Vzc2lvbikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBjb25zdCB1bnN1YnNjcmliZSA9IHNlc3Npb25TdG9yZS5zdWJzY3JpYmUocmVzb2x2ZUlmTG9hZGVkKTtcbiAgICAgICAgLy8gQSBmYWlsZWQgcmVmcmVzaCBrZWVwcyBhbiBhbHJlYWR5LWxvYWRlZCBzZXNzaW9uIHdpdGhvdXQgdXBkYXRpbmcgdGhlIHN0b3JlLCBzbyB0aGVcbiAgICAgICAgLy8gc3Vic2NyaXB0aW9uIGFsb25lIHdvdWxkIG5ldmVyIGZpcmUuXG4gICAgICAgIHJlZnJlc2gudGhlbihyZXNvbHZlSWZMb2FkZWQsIHJlc29sdmVJZkxvYWRlZCk7XG4gICAgfSk7XG59XG5leHBvcnQgeyBnZXRDdXJyZW50VXNlciB9O1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBnbG9iYWwgc2Vzc2lvbiBzdG9yZSBjb250YWluaW5nIHRoZSBjdXJyZW50IHVzZXIncyBzZXNzaW9uIGluZm9ybWF0aW9uLlxuICogSWYgdGhlIHNlc3Npb24gZGF0YSBpcyBzdGFsZSAob2xkZXIgdGhhbiAxIG1pbnV0ZSkgb3Igbm90IHlldCBsb2FkZWQsIHRoaXMgZnVuY3Rpb25cbiAqIHdpbGwgdHJpZ2dlciBhIHJlZmV0Y2ggb2YgdGhlIGN1cnJlbnQgdXNlcidzIHNlc3Npb24uXG4gKlxuICogQHJldHVybnMgVGhlIGdsb2JhbCBzZXNzaW9uIHN0b3JlIHRoYXQgY2FuIGJlIHN1YnNjcmliZWQgdG8gZm9yIHNlc3Npb24gdXBkYXRlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGdldFNlc3Npb25TdG9yZSB9IGZyb20gJ0BvcGVubXJzL2VzbS1hcGknO1xuICogY29uc3Qgc3RvcmUgPSBnZXRTZXNzaW9uU3RvcmUoKTtcbiAqIGNvbnN0IHVuc3Vic2NyaWJlID0gc3RvcmUuc3Vic2NyaWJlKChzdGF0ZSkgPT4ge1xuICogICBpZiAoc3RhdGUubG9hZGVkKSB7XG4gKiAgICAgY29uc29sZS5sb2coJ1Nlc3Npb246Jywgc3RhdGUuc2Vzc2lvbik7XG4gKiAgIH1cbiAqIH0pO1xuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGdldFNlc3Npb25TdG9yZSgpIHtcbiAgICByZWZyZXNoU2Vzc2lvbklmU3RhbGUoKTtcbiAgICByZXR1cm4gc2Vzc2lvblN0b3JlO1xufVxuLy8gTkIgbG9jYWxlIGlzIHN0cmluZyBvbmx5IGlmIHRoaXMgcmV0dXJucyB0cnVlXG5mdW5jdGlvbiBpc1ZhbGlkTG9jYWxlKGxvY2FsZSkge1xuICAgIGlmIChsb2NhbGUgPT09IHVuZGVmaW5lZCB8fCB0eXBlb2YgbG9jYWxlICE9PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIG5ldyBJbnRsLkxvY2FsZShsb2NhbGUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cbi8qKlxuICogU2V0cyB0aGUgZG9jdW1lbnQncyBsYW5ndWFnZSBhdHRyaWJ1dGUgYmFzZWQgb24gdGhlIHVzZXIncyBsb2NhbGUgcHJlZmVyZW5jZVxuICogZnJvbSB0aGUgc2Vzc2lvbiBkYXRhLiBUaGlzIGFmZmVjdHMgdGhlIEhUTUwgYGxhbmdgIGF0dHJpYnV0ZSB3aGljaCBpcyB1c2VkXG4gKiBmb3IgYWNjZXNzaWJpbGl0eSBhbmQgaW50ZXJuYXRpb25hbGl6YXRpb24uXG4gKlxuICogVGhlIGxvY2FsZSBpcyBkZXRlcm1pbmVkIGZyb20gZWl0aGVyIHRoZSBzZXNzaW9uJ3MgbG9jYWxlIG9yIHRoZSB1c2VyJ3NcbiAqIGRlZmF1bHQgbG9jYWxlIHByb3BlcnR5LiBVbmRlcnNjb3JlcyBpbiB0aGUgbG9jYWxlIGFyZSBjb252ZXJ0ZWQgdG8gaHlwaGVuc1xuICogdG8gbWF0Y2ggQkNQIDQ3IGxhbmd1YWdlIHRhZyBmb3JtYXQuXG4gKlxuICogQHBhcmFtIGRhdGEgVGhlIHNlc3Npb24gb2JqZWN0IGNvbnRhaW5pbmcgbG9jYWxlIGluZm9ybWF0aW9uLlxuICovIGV4cG9ydCBmdW5jdGlvbiBzZXRVc2VyTGFuZ3VhZ2UoZGF0YSkge1xuICAgIGxldCBsb2NhbGUgPSBkYXRhLmxvY2FsZSA/PyBkYXRhLnVzZXI/LnVzZXJQcm9wZXJ0aWVzPy5kZWZhdWx0TG9jYWxlO1xuICAgIC8vIE9ubHkgdW5kZXJzY29yZXMgYXJlIGNvbnZlcnRlZCBoZXJlLCBkZWxpYmVyYXRlbHksIHJhdGhlciB0aGFuIHJldXNpbmcgYHRvTGFuZ3VhZ2VUYWdgLiBpMThuZXh0XG4gICAgLy8gcmVhZHMgdGhpcyB2YWx1ZSBiYWNrIG9mZiBgZG9jdW1lbnQubGFuZ2AgYW5kIHVzZXMgaXQgYXMgdGhlIHRyYW5zbGF0aW9uIGJ1bmRsZSBrZXksIGFuZCB0aG9zZVxuICAgIC8vIGJ1bmRsZXMgYXJlIG5hbWVkIHdpdGggdGhlIFBPU0lYIGZvcm0gKGB1ekBMYXRuLmpzb25gKSwgc28gY29udmVydGluZyBgQGAgd291bGQgc2VuZCB0aGUgbG9hZGVyXG4gICAgLy8gYWZ0ZXIgYSBidW5kbGUgdGhhdCBkb2VzIG5vdCBleGlzdC5cbiAgICBpZiAobG9jYWxlICYmIGxvY2FsZS5pbmNsdWRlcygnXycpKSB7XG4gICAgICAgIGxvY2FsZSA9IGxvY2FsZS5yZXBsYWNlQWxsKCdfJywgJy0nKTtcbiAgICB9XG4gICAgaWYgKGlzVmFsaWRMb2NhbGUobG9jYWxlKSAmJiBsb2NhbGUgIT09IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5nZXRBdHRyaWJ1dGUoJ2xhbmcnKSkge1xuICAgICAgICBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2V0QXR0cmlidXRlKCdsYW5nJywgbG9jYWxlKTtcbiAgICB9XG59XG5zZXNzaW9uU3RvcmUuc3Vic2NyaWJlKChzdGF0ZSk9PntcbiAgICBpZiAoc3RhdGUubG9hZGVkICYmIHN0YXRlLnNlc3Npb24pIHtcbiAgICAgICAgc2V0VXNlckxhbmd1YWdlKHN0YXRlLnNlc3Npb24pO1xuICAgIH1cbn0pO1xuZnVuY3Rpb24gdXNlckhhc1ByaXZpbGVnZShyZXF1aXJlZFByaXZpbGVnZSwgdXNlcikge1xuICAgIGlmICh0eXBlb2YgcmVxdWlyZWRQcml2aWxlZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiAhaXNVbmRlZmluZWQodXNlci5wcml2aWxlZ2VzLmZpbmQoKHApPT5yZXF1aXJlZFByaXZpbGVnZSA9PT0gcC5kaXNwbGF5KSk7XG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJlcXVpcmVkUHJpdmlsZWdlKSkge1xuICAgICAgICByZXR1cm4gcmVxdWlyZWRQcml2aWxlZ2UuZXZlcnkoKHJwKT0+IWlzVW5kZWZpbmVkKHVzZXIucHJpdmlsZWdlcy5maW5kKChwKT0+cnAgPT09IHAuZGlzcGxheSkpKTtcbiAgICB9IGVsc2UgaWYgKCFpc1VuZGVmaW5lZChyZXF1aXJlZFByaXZpbGVnZSkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgQ291bGQgbm90IHVuZGVyc3RhbmQgcHJpdmlsZWdlcyBcIiR7cmVxdWlyZWRQcml2aWxlZ2V9XCJgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG5mdW5jdGlvbiBpc1N1cGVyVXNlcih1c2VyKSB7XG4gICAgcmV0dXJuICFpc1VuZGVmaW5lZCh1c2VyLnJvbGVzLmZpbmQoKHJvbGUpPT5yb2xlLmRpc3BsYXkgPT09ICdTeXN0ZW0gRGV2ZWxvcGVyJykpO1xufVxuLyoqXG4gKiBUaGUgYHJlZmV0Y2hDdXJyZW50VXNlcmAgZnVuY3Rpb24gY2F1c2VzIGEgbmV0d29yayByZXF1ZXN0IHRvIHJlZG93bmxvYWRcbiAqIHRoZSB1c2VyLiBBbGwgc3Vic2NyaWJlcnMgdG8gdGhlIHNlc3Npb24gc3RvcmUgd2lsbCBiZSBub3RpZmllZCBvZiB0aGVcbiAqIG5ldyB1c2VyIG9uY2UgdGhlIG5ldyB2ZXJzaW9uIG9mIHRoZSB1c2VyIG9iamVjdCBpcyBkb3dubG9hZGVkLlxuICpcbiAqIElmIHRoZSBzZXJ2ZXIgcmVqZWN0cyB0aGUgcmVxdWVzdCBhcyB1bmF1dGhlbnRpY2F0ZWQgKDQwMSBvciA0MDMpLCB0aGUgc3RvcmUgcmVjb3JkcyBhXG4gKiBsb2dnZWQtb3V0IHNlc3Npb24uIElmIHRoZSByZXF1ZXN0IGZhaWxzIGZvciBhbnkgb3RoZXIgcmVhc29uLCBhIHNlc3Npb24gdGhhdCBoYXMgYWxyZWFkeVxuICogbG9hZGVkIGlzIGtlcHQ7IG90aGVyd2lzZSB0aGUgc3RvcmUgcmVjb3JkcyB0aGUgZXJyb3IuXG4gKlxuICogQHJldHVybnMgQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgdXBkYXRlZCBzZXNzaW9uIHN0b3JlIHN0YXRlLiBJdCByZWplY3RzIHdpdGggdGhlXG4gKiAgIHN0b3JlIHN0YXRlIGlmIHRoZSByZXF1ZXN0IGZhaWxzIGZvciBhIHJlYXNvbiBvdGhlciB0aGFuIGF1dGhlbnRpY2F0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGBqc1xuICogaW1wb3J0IHsgcmVmZXRjaEN1cnJlbnRVc2VyIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSdcbiAqIHJlZmV0Y2hDdXJyZW50VXNlcigpXG4gKiBgYGBcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVmZXRjaEN1cnJlbnRVc2VyKHVzZXJuYW1lLCBwYXNzd29yZCkge1xuICAgIGxhc3RGZXRjaFRpbWVNaWxsaXMgPSBEYXRlLm5vdygpO1xuICAgIGxldCBoZWFkZXJzID0ge307XG4gICAgaWYgKHVzZXJuYW1lICYmIHBhc3N3b3JkKSB7XG4gICAgICAgIGhlYWRlcnNbJ0F1dGhvcml6YXRpb24nXSA9IGBCYXNpYyAke3dpbmRvdy5idG9hKGAke3VzZXJuYW1lfToke3Bhc3N3b3JkfWApfWA7XG4gICAgfVxuICAgIGNvbnN0IHJlZnJlc2ggPSBoYW5kbGVTZXNzaW9uUmVzcG9uc2Uob3Blbm1yc0ZldGNoKHNlc3Npb25FbmRwb2ludCwge1xuICAgICAgICBoZWFkZXJzLFxuICAgICAgICByZWplY3RBdXRoRmFpbHVyZTogdHJ1ZVxuICAgIH0pKTtcbiAgICAvLyBQdWJsaXNoIHRoZSByZXF1ZXN0IHNvIHRoYXQgcmVhZGVycyBjYW4gd2FpdCBvbiBpdCBpbnN0ZWFkIG9mIHJlYWRpbmcgdGhlIHNlc3Npb24gaXQgaXMgYWJvdXQgdG9cbiAgICAvLyByZXBsYWNlLiBFYWNoIGNhbGwgc3RpbGwgaXNzdWVzIGl0cyBvd24gcmVxdWVzdDsgdGhpcyBvbmx5IHRyYWNrcyB0aGUgbW9zdCByZWNlbnQgb25lLlxuICAgIGNvbnN0IGNsZWFyID0gKCk9PntcbiAgICAgICAgaWYgKGluRmxpZ2h0UmVmcmVzaCA9PT0gcmVmcmVzaCkge1xuICAgICAgICAgICAgaW5GbGlnaHRSZWZyZXNoID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmVmcmVzaC50aGVuKGNsZWFyLCBjbGVhcik7XG4gICAgaW5GbGlnaHRSZWZyZXNoID0gcmVmcmVzaDtcbiAgICByZXR1cm4gcmVmcmVzaDtcbn1cbi8qKlxuICogQ2xlYXJzIHRoZSBjdXJyZW50IHVzZXIgc2Vzc2lvbiBmcm9tIHRoZSBzZXNzaW9uIHN0b3JlLCBzZXR0aW5nIHRoZSBzZXNzaW9uXG4gKiB0byBhbiB1bmF1dGhlbnRpY2F0ZWQgc3RhdGUuIFRoaXMgaXMgdHlwaWNhbGx5IGNhbGxlZCBkdXJpbmcgbG9nb3V0IHRvIHJlc2V0XG4gKiB0aGUgYXBwbGljYXRpb24ncyBhdXRoZW50aWNhdGlvbiBzdGF0ZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGNsZWFyQ3VycmVudFVzZXIgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIC8vIER1cmluZyBsb2dvdXRcbiAqIGNsZWFyQ3VycmVudFVzZXIoKTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBjbGVhckN1cnJlbnRVc2VyKCkge1xuICAgIHNlc3Npb25TdG9yZS5zZXRTdGF0ZSh7XG4gICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgICAgc2Vzc2lvbjoge1xuICAgICAgICAgICAgYXV0aGVudGljYXRlZDogZmFsc2UsXG4gICAgICAgICAgICBzZXNzaW9uSWQ6ICcnXG4gICAgICAgIH1cbiAgICB9LCB0cnVlKTtcbn1cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIHVzZXIgaGFzIGFjY2VzcyBiYXNlZCBvbiB0aGUgcmVxdWlyZWQgcHJpdmlsZWdlKHMpLlxuICogQSB1c2VyIGhhcyBhY2Nlc3MgaWYgdGhleSBoYXZlIHRoZSByZXF1aXJlZCBwcml2aWxlZ2Uocykgb3IgaWYgdGhleSBhcmUgYVxuICogXCJTeXN0ZW0gRGV2ZWxvcGVyXCIgKHN1cGVyIHVzZXIpLiBJZiBubyBwcml2aWxlZ2UgaXMgcmVxdWlyZWQsIGFjY2VzcyBpcyBncmFudGVkLlxuICpcbiAqIEBwYXJhbSByZXF1aXJlZFByaXZpbGVnZSBBIHNpbmdsZSBwcml2aWxlZ2Ugc3RyaW5nIG9yIGFuIGFycmF5IG9mIHByaXZpbGVnZSBzdHJpbmdzXG4gKiAgIHRoYXQgdGhlIHVzZXIgbXVzdCBoYXZlLiBJZiBhbiBhcnJheSBpcyBwcm92aWRlZCwgdGhlIHVzZXIgbXVzdCBoYXZlIEFMTCBwcml2aWxlZ2VzLlxuICogQHBhcmFtIHVzZXIgVGhlIHVzZXIgb2JqZWN0IGNvbnRhaW5pbmcgdGhlaXIgcHJpdmlsZWdlcyBhbmQgcm9sZXMuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgaWYgdGhlIHVzZXIgaGFzIGFjY2VzcywgYGZhbHNlYCBvdGhlcndpc2UuIFJldHVybnMgYHRydWVgIGlmIG5vXG4gKiAgIHByaXZpbGVnZSBpcyByZXF1aXJlZCwgYW5kIGBmYWxzZWAgaWYgdGhlIHVzZXIgaXMgdW5kZWZpbmVkIGJ1dCBhIHByaXZpbGVnZSBpcyByZXF1aXJlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IHVzZXJIYXNBY2Nlc3MgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGNvbnN0IGhhc0FjY2VzcyA9IHVzZXJIYXNBY2Nlc3MoJ1ZpZXcgUGF0aWVudHMnLCBjdXJyZW50VXNlcik7XG4gKiBjb25zdCBoYXNNdWx0aXBsZUFjY2VzcyA9IHVzZXJIYXNBY2Nlc3MoWydWaWV3IFBhdGllbnRzJywgJ0VkaXQgUGF0aWVudHMnXSwgY3VycmVudFVzZXIpO1xuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHVzZXJIYXNBY2Nlc3MocmVxdWlyZWRQcml2aWxlZ2UsIHVzZXIpIHtcbiAgICBpZiAodXNlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGlmIHRoZSB1c2VyIGhhc24ndCBiZWVuIGxvYWRlZCwgdGhlbiByZXR1cm4gZmFsc2UgaWZmIHRoZXJlIGlzIGEgcmVxdWlyZWQgcHJpdmlsZWdlXG4gICAgICAgIHJldHVybiAhQm9vbGVhbihyZXF1aXJlZFByaXZpbGVnZSk7XG4gICAgfVxuICAgIGlmICghQm9vbGVhbihyZXF1aXJlZFByaXZpbGVnZSkpIHtcbiAgICAgICAgLy8gaWYgdXNlciBleGlzdHMgYnV0IG5vIHJlcXVpcmVkUHJpdmlsZWdlIGlzIGRlZmluZWRcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiB1c2VySGFzUHJpdmlsZWdlKHJlcXVpcmVkUHJpdmlsZWdlLCB1c2VyKSB8fCBpc1N1cGVyVXNlcih1c2VyKTtcbn1cbi8qKlxuICogUmV0dXJucyBhIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBjdXJyZW50bHkgbG9nZ2VkLWluIHVzZXIgb2JqZWN0LlxuICogSWYgdGhlIHVzZXIgaXMgYWxyZWFkeSBsb2FkZWQgaW4gdGhlIHNlc3Npb24gc3RvcmUsIHRoZSBQcm9taXNlIHJlc29sdmVzIGltbWVkaWF0ZWx5LlxuICogT3RoZXJ3aXNlLCBpdCBzdWJzY3JpYmVzIHRvIHRoZSBzZXNzaW9uIHN0b3JlIGFuZCByZXNvbHZlcyB3aGVuIGEgbG9nZ2VkLWluIHVzZXJcbiAqIGJlY29tZXMgYXZhaWxhYmxlLlxuICpcbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIExvZ2dlZEluVXNlciBvYmplY3Qgb25jZSBhdmFpbGFibGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBnZXRMb2dnZWRJblVzZXIgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGNvbnN0IHVzZXIgPSBhd2FpdCBnZXRMb2dnZWRJblVzZXIoKTtcbiAqIGNvbnNvbGUubG9nKCdMb2dnZWQgaW4gYXM6JywgdXNlci5kaXNwbGF5KTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRMb2dnZWRJblVzZXIoKSB7XG4gICAgbGV0IHVzZXI7XG4gICAgbGV0IHVuc3Vic2NyaWJlO1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzKT0+e1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gKHN0YXRlKT0+e1xuICAgICAgICAgICAgaWYgKHN0YXRlLmxvYWRlZCAmJiBzdGF0ZS5zZXNzaW9uLnVzZXIpIHtcbiAgICAgICAgICAgICAgICB1c2VyID0gc3RhdGUuc2Vzc2lvbi51c2VyO1xuICAgICAgICAgICAgICAgIHJlcyhzdGF0ZS5zZXNzaW9uLnVzZXIpO1xuICAgICAgICAgICAgICAgIGlmICh1bnN1YnNjcmliZSkge1xuICAgICAgICAgICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgaGFuZGxlcihzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKSk7XG4gICAgICAgIGlmICghdXNlcikge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmUgPSBzZXNzaW9uU3RvcmUuc3Vic2NyaWJlKGhhbmRsZXIpO1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIFJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgY3VycmVudCBzZXNzaW9uIGxvY2F0aW9uLCBpZiBvbmUgaXMgc2V0LlxuICogVGhlIHNlc3Npb24gbG9jYXRpb24gcmVwcmVzZW50cyB0aGUgcGh5c2ljYWwgbG9jYXRpb24gd2hlcmUgdGhlIHVzZXIgaXMgY3VycmVudGx5XG4gKiB3b3JraW5nIChlLmcuLCBhIGNsaW5pYyBvciB3YXJkKS5cbiAqXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBTZXNzaW9uTG9jYXRpb24gb2JqZWN0LCBvciBgdW5kZWZpbmVkYFxuICogICBpZiBubyBzZXNzaW9uIGxvY2F0aW9uIGlzIHNldC5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGdldFNlc3Npb25Mb2NhdGlvbiB9IGZyb20gJ0BvcGVubXJzL2VzbS1hcGknO1xuICogY29uc3QgbG9jYXRpb24gPSBhd2FpdCBnZXRTZXNzaW9uTG9jYXRpb24oKTtcbiAqIGlmIChsb2NhdGlvbikge1xuICogICBjb25zb2xlLmxvZygnQ3VycmVudCBsb2NhdGlvbjonLCBsb2NhdGlvbi5kaXNwbGF5KTtcbiAqIH1cbiAqIGBgYFxuICovIGV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRTZXNzaW9uTG9jYXRpb24oKSB7XG4gICAgY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IGdldEN1cnJlbnRVc2VyKCk7XG4gICAgcmV0dXJuIHNlc3Npb24uc2Vzc2lvbkxvY2F0aW9uO1xufVxuLyoqXG4gKiBTZXRzIHRoZSBzZXNzaW9uIGxvY2F0aW9uIGZvciB0aGUgY3VycmVudCB1c2VyLiBUaGUgc2Vzc2lvbiBsb2NhdGlvbiByZXByZXNlbnRzXG4gKiB0aGUgcGh5c2ljYWwgbG9jYXRpb24gd2hlcmUgdGhlIHVzZXIgaXMgd29ya2luZyAoZS5nLiwgYSBjbGluaWMgb3Igd2FyZCkuXG4gKiBUaGlzIHRyaWdnZXJzIGEgc2VydmVyIHJlcXVlc3QgdG8gdXBkYXRlIHRoZSBzZXNzaW9uIGFuZCByZWZyZXNoZXMgdGhlIGxvY2FsXG4gKiBzZXNzaW9uIHN0b3JlLlxuICpcbiAqIEBwYXJhbSBsb2NhdGlvblV1aWQgVGhlIFVVSUQgb2YgdGhlIGxvY2F0aW9uIHRvIHNldCBhcyB0aGUgc2Vzc2lvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSBhYm9ydENvbnRyb2xsZXIgQW4gQWJvcnRDb250cm9sbGVyIHRvIGFsbG93IGNhbmNlbGxhdGlvbiBvZiB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHVwZGF0ZWQgU2Vzc2lvblN0b3JlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgc2V0U2Vzc2lvbkxvY2F0aW9uIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBjb25zdCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gKiBhd2FpdCBzZXRTZXNzaW9uTG9jYXRpb24oJ2xvY2F0aW9uLXV1aWQtaGVyZScsIGFib3J0Q29udHJvbGxlcik7XG4gKiBgYGBcbiAqLyBleHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0U2Vzc2lvbkxvY2F0aW9uKGxvY2F0aW9uVXVpZCwgYWJvcnRDb250cm9sbGVyKSB7XG4gICAgcmV0dXJuIGhhbmRsZVNlc3Npb25SZXNwb25zZShvcGVubXJzRmV0Y2goc2Vzc2lvbkVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICBzZXNzaW9uTG9jYXRpb246IGxvY2F0aW9uVXVpZFxuICAgICAgICB9LFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgIH0sXG4gICAgICAgIHJlamVjdEF1dGhGYWlsdXJlOiB0cnVlLFxuICAgICAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlcj8uc2lnbmFsXG4gICAgfSkpO1xufVxuLyoqXG4gKiBTZXRzIHRoZSBsb2NhbGUgZm9yIHRoZSBjdXJyZW50IHNlc3Npb24gb25seSwgbGVhdmluZyB0aGUgdXNlcidzIGRlZmF1bHQgbG9jYWxlIHVuY2hhbmdlZC5cbiAqIFVzZSB7QGxpbmsgc2V0VXNlclByb3BlcnRpZXN9IHdpdGggYSBgZGVmYXVsdExvY2FsZWAgcHJvcGVydHkgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGluc3RlYWQuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBUaGUgbG9jYWxlIGluIEphdmEncyBgTG9jYWxlI3RvU3RyaW5nKClgIGZvcm0sIGUuZy4gYGVuX0dCYC5cbiAqIEBwYXJhbSBhYm9ydENvbnRyb2xsZXIgT3B0aW9uYWwgQWJvcnRDb250cm9sbGVyIHRvIGFsbG93IGNhbmNlbGxhdGlvbiBvZiB0aGUgcmVxdWVzdC5cbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHVwZGF0ZWQgU2Vzc2lvblN0b3JlIGFmdGVyIHJlZmV0Y2hpbmcgdGhlIGN1cnJlbnQgdXNlci5cbiAqICAgSXQgcmVqZWN0cyB3aXRoIGFuIHtAbGluayBPcGVubXJzRmV0Y2hFcnJvcn0gaWYgdGhlIHNlcnZlciBkb2VzIG5vdCBhY2NlcHQgdGhlIGxvY2FsZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IHNldFNlc3Npb25Mb2NhbGUgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGF3YWl0IHNldFNlc3Npb25Mb2NhbGUoJ2ZyJyk7XG4gKiBgYGBcbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0U2Vzc2lvbkxvY2FsZShsb2NhbGUsIGFib3J0Q29udHJvbGxlcikge1xuICAgIGF3YWl0IG9wZW5tcnNGZXRjaChzZXNzaW9uRW5kcG9pbnQsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICAgIGxvY2FsZVxuICAgICAgICB9LFxuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXG4gICAgICAgIH0sXG4gICAgICAgIHNpZ25hbDogYWJvcnRDb250cm9sbGVyPy5zaWduYWxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVmZXRjaEN1cnJlbnRVc2VyKCk7XG59XG4vKipcbiAqIFVwZGF0ZXMgdGhlIHVzZXIgcHJvcGVydGllcyBmb3IgYSBzcGVjaWZpYyB1c2VyLiBVc2VyIHByb3BlcnRpZXMgYXJlIGtleS12YWx1ZVxuICogcGFpcnMgdGhhdCBzdG9yZSB1c2VyLXNwZWNpZmljIHNldHRpbmdzIGFuZCBwcmVmZXJlbmNlcy4gQWZ0ZXIgdXBkYXRpbmcgdGhlXG4gKiBwcm9wZXJ0aWVzIG9uIHRoZSBzZXJ2ZXIsIHRoZSBjdXJyZW50IHVzZXIgc2Vzc2lvbiBpcyByZWZldGNoZWQgdG8gcmVmbGVjdFxuICogdGhlIGNoYW5nZXMuXG4gKlxuICogQHBhcmFtIHVzZXJVdWlkIFRoZSBVVUlEIG9mIHRoZSB1c2VyIHdob3NlIHByb3BlcnRpZXMgc2hvdWxkIGJlIHVwZGF0ZWQuXG4gKiBAcGFyYW0gdXNlclByb3BlcnRpZXMgQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHByb3BlcnRpZXMgdG8gc2V0IG9yIHVwZGF0ZS5cbiAqIEBwYXJhbSBhYm9ydENvbnRyb2xsZXIgT3B0aW9uYWwgQWJvcnRDb250cm9sbGVyIHRvIGFsbG93IGNhbmNlbGxhdGlvbiBvZiB0aGUgcmVxdWVzdC5cbiAqICAgSWYgbm90IHByb3ZpZGVkLCBhIG5ldyBBYm9ydENvbnRyb2xsZXIgaXMgY3JlYXRlZC5cbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIHVwZGF0ZWQgU2Vzc2lvblN0b3JlIGFmdGVyIHJlZmV0Y2hpbmdcbiAqICAgdGhlIGN1cnJlbnQgdXNlci5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IGdldExvZ2dlZEluVXNlciwgc2V0VXNlclByb3BlcnRpZXMgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGNvbnN0IHVzZXIgPSBhd2FpdCBnZXRMb2dnZWRJblVzZXIoKTtcbiAqIGF3YWl0IHNldFVzZXJQcm9wZXJ0aWVzKHVzZXIudXVpZCwge1xuICogICBkZWZhdWx0TG9jYWxlOiAnZW5fR0InLFxuICogICBjdXN0b21TZXR0aW5nOiAndmFsdWUnXG4gKiB9KTtcbiAqIGBgYFxuICovIGV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXRVc2VyUHJvcGVydGllcyh1c2VyVXVpZCwgdXNlclByb3BlcnRpZXMsIGFib3J0Q29udHJvbGxlcikge1xuICAgIGlmICghYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAgIGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICB9XG4gICAgYXdhaXQgb3Blbm1yc0ZldGNoKGAke3Jlc3RCYXNlVXJsfS91c2VyLyR7dXNlclV1aWR9YCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgICAgdXNlclByb3BlcnRpZXNcbiAgICAgICAgfSxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9LFxuICAgICAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlci5zaWduYWxcbiAgICB9KTtcbiAgICByZXR1cm4gcmVmZXRjaEN1cnJlbnRVc2VyKCk7XG59XG4vKipcbiAqIFN1Ym1pdHMgYSBUT1RQIGNvZGUgdG8gY29tcGxldGUgYSB0d28tZmFjdG9yIGxvZ2luIGNoYWxsZW5nZS4gV2hlbiB0aGUgY29kZSBpcyBhY2NlcHRlZCwgdGhlXG4gKiBzZXNzaW9uIHN0b3JlIGlzIHJlZnJlc2hlZCB3aXRoIHRoZSBub3ctYXV0aGVudGljYXRlZCBzZXNzaW9uLlxuICpcbiAqIEBwYXJhbSBjb2RlIFRoZSBjb2RlIGZyb20gdGhlIHVzZXIncyBhdXRoZW50aWNhdG9yIGFwcC5cbiAqIEBwYXJhbSByZW1lbWJlckRldmljZSBXaGV0aGVyIHRoZSBzZXJ2ZXIgc2hvdWxkIHNraXAgdGhlIGNoYWxsZW5nZSBvbiB0aGlzIGRldmljZSBpbiBmdXR1cmUuXG4gKiBAcmV0dXJucyBBIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBzZXNzaW9uLiBJdHMgYGF1dGhlbnRpY2F0ZWRgIHByb3BlcnR5IGlzIGBmYWxzZWAgaWYgdGhlXG4gKiAgIGNvZGUgd2FzIG5vdCBhY2NlcHRlZC4gSXQgcmVqZWN0cyB3aXRoIGFuIHtAbGluayBPcGVubXJzRmV0Y2hFcnJvcn0gaWYgdGhlIHNlcnZlciByZWplY3RzIHRoZVxuICogICByZXF1ZXN0LCBpbiB3aGljaCBjYXNlIGByZXNwb25zZUJvZHlgIG1heSBleHBsYWluIHdoeS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IHZlcmlmeVRvdHBDb2RlIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBjb25zdCBzZXNzaW9uID0gYXdhaXQgdmVyaWZ5VG90cENvZGUoJzEyMzQ1NicsIHRydWUpO1xuICogYGBgXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHZlcmlmeVRvdHBDb2RlKGNvZGUsIHJlbWVtYmVyRGV2aWNlID0gZmFsc2UpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IG9wZW5tcnNGZXRjaChyZW1lbWJlckRldmljZSA/IGAke3Nlc3Npb25FbmRwb2ludH0/cmVtZW1iZXJNZT10cnVlYCA6IHNlc3Npb25FbmRwb2ludCwge1xuICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAnWC1Ub3RwLUNvZGUnOiBjb2RlXG4gICAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAocmVzcG9uc2UuZGF0YT8uYXV0aGVudGljYXRlZCkge1xuICAgICAgICAvLyBgcmVmZXRjaEN1cnJlbnRVc2VyYCBvbmx5IHJlc29sdmVzIG9uY2UgdGhlIHN0b3JlIGhvbGRzIGEgc2Vzc2lvbi5cbiAgICAgICAgY29uc3Qgc3RvcmUgPSBhd2FpdCByZWZldGNoQ3VycmVudFVzZXIoKTtcbiAgICAgICAgcmV0dXJuIHN0b3JlLnNlc3Npb247XG4gICAgfVxuICAgIHJldHVybiByZXNwb25zZS5kYXRhO1xufVxuLyoqXG4gKiBFbmRzIHRoZSBjdXJyZW50IHNlc3Npb24gb24gdGhlIHNlcnZlciBhbmQgcmVjb3JkcyBhIGxvZ2dlZC1vdXQgc2Vzc2lvbiBpbiB0aGUgc2Vzc2lvbiBzdG9yZS5cbiAqIEEgc2VydmVyIHRoYXQgaGFzIGFscmVhZHkgZW5kZWQgdGhlIHNlc3Npb24gKDQwMSBvciA0MDMpIGNvdW50cyBhcyBhIHN1Y2Nlc3NmdWwgbG9nb3V0LlxuICpcbiAqIE90aGVyIGRhdGEgY2FjaGVkIGZvciB0aGUgbG9nZ2VkLWluIHVzZXIsIHN1Y2ggYXMgU1dSIGNhY2hlcywgaXMgdGhlIGNhbGxlcidzIHRvIGNsZWFyLlxuICpcbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHNlc3Npb24gc3RvcmUgaG9sZHMgYSBsb2dnZWQtb3V0IHNlc3Npb24uXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBsb2dvdXQgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGF3YWl0IGxvZ291dCgpO1xuICogYGBgXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxvZ291dCgpIHtcbiAgICB0cnkge1xuICAgICAgICBhd2FpdCBvcGVubXJzRmV0Y2goc2Vzc2lvbkVuZHBvaW50LCB7XG4gICAgICAgICAgICBtZXRob2Q6ICdERUxFVEUnLFxuICAgICAgICAgICAgcmVqZWN0QXV0aEZhaWx1cmU6IHRydWVcbiAgICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGlmICghaXNBdXRoRmFpbHVyZShlcnIpKSB7XG4gICAgICAgICAgICB0aHJvdyBlcnI7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY2xlYXJDdXJyZW50VXNlcigpO1xuICAgIC8vIFRoZSBzZXNzaW9uIGp1c3QgY2xlYXJlZCBpcyBhbHJlYWR5IGNvcnJlY3QsIHNvIGEgZmFpbGVkIHJlZnJlc2ggbG9zZXMgbm90aGluZy5cbiAgICBhd2FpdCByZWZldGNoQ3VycmVudFVzZXIoKS5jYXRjaCgoKT0+e30pO1xufVxuZnVuY3Rpb24gaGFuZGxlU2Vzc2lvblJlc3BvbnNlKHJlc3VsdCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KT0+e1xuICAgICAgICByZXN1bHQudGhlbigocmVzKT0+e1xuICAgICAgICAgICAgaWYgKHR5cGVvZiByZXM/LmRhdGEgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgbmV4dFN0YXRlID0ge1xuICAgICAgICAgICAgICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIHNlc3Npb246IHJlcy5kYXRhXG4gICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICBzZXNzaW9uU3RvcmUuc2V0U3RhdGUobmV4dFN0YXRlLCB0cnVlKTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKG5leHRTdGF0ZSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJlamVjdChyZWNvcmRTZXNzaW9uRmFpbHVyZShFcnJvcignVGhlIHNlc3Npb24gZW5kcG9pbnQgZGlkIG5vdCByZXNwb25kIHdpdGggYSBzZXNzaW9uJykpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkuY2F0Y2goKGVycik9PntcbiAgICAgICAgICAgIC8vIEFuIGF1dGggZmFpbHVyZSBpcyB0aGUgc2Vzc2lvbiBlbmRwb2ludCdzIGFuc3dlciBmb3IgXCJub3QgbG9nZ2VkIGluXCIsIG5vdCBhIGZhaWxlZCBsb29rdXAuXG4gICAgICAgICAgICBpZiAoaXNBdXRoRmFpbHVyZShlcnIpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGlzVW5hdXRoZW50aWNhdGVkU2Vzc2lvbihlcnIucmVzcG9uc2VCb2R5KSkge1xuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uU3RvcmUuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbjogZXJyLnJlc3BvbnNlQm9keVxuICAgICAgICAgICAgICAgICAgICB9LCB0cnVlKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjbGVhckN1cnJlbnRVc2VyKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJlc29sdmUoc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlcG9ydEVycm9yKGBGYWlsZWQgdG8gZmV0Y2ggbmV3IHNlc3Npb24gaW5mb3JtYXRpb246ICR7ZXJyfWApO1xuICAgICAgICAgICAgcmVqZWN0KHJlY29yZFNlc3Npb25GYWlsdXJlKGVycikpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbn1cbmZ1bmN0aW9uIGlzQXV0aEZhaWx1cmUoZXJyKSB7XG4gICAgcmV0dXJuIGVyciBpbnN0YW5jZW9mIE9wZW5tcnNGZXRjaEVycm9yICYmIChlcnIucmVzcG9uc2Uuc3RhdHVzID09PSA0MDEgfHwgZXJyLnJlc3BvbnNlLnN0YXR1cyA9PT0gNDAzKTtcbn1cbmZ1bmN0aW9uIGlzVW5hdXRoZW50aWNhdGVkU2Vzc2lvbihib2R5KSB7XG4gICAgcmV0dXJuIHR5cGVvZiBib2R5ID09PSAnb2JqZWN0JyAmJiBib2R5ICE9PSBudWxsICYmIGJvZHkuYXV0aGVudGljYXRlZCA9PT0gZmFsc2U7XG59XG4vKipcbiAqIEEgc2Vzc2lvbiB0aGF0IGhhcyBhbHJlYWR5IGxvYWRlZCBpcyBrZXB0IHdoZW4gYSBsYXRlciBmZXRjaCBmYWlscywgc2luY2UgaXQgaXMgc3RpbGwgdGhlIGJlc3QgYW5zd2VyXG4gKiBhdmFpbGFibGUuIFdpdGggbm90aGluZyB0byBmYWxsIGJhY2sgb24sIHRoZSBlcnJvciBpcyByZWNvcmRlZCBzbyB0aGUgYXBwIHNoZWxsIGNhbiBzaG93IGFuIGVycm9yIHBhZ2UuXG4gKi8gZnVuY3Rpb24gcmVjb3JkU2Vzc2lvbkZhaWx1cmUoZXJyKSB7XG4gICAgaWYgKCFzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKS5sb2FkZWQpIHtcbiAgICAgICAgc2Vzc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIGxvYWRlZDogZmFsc2UsXG4gICAgICAgICAgICBzZXNzaW9uOiBudWxsLFxuICAgICAgICAgICAgZXJyb3I6IGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyIDogRXJyb3IoU3RyaW5nKGVycikpXG4gICAgICAgIH0sIHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gc2Vzc2lvblN0b3JlLmdldFN0YXRlKCk7XG59XG4iXSwibmFtZXMiOlsicmVwb3J0RXJyb3IiLCJjcmVhdGVHbG9iYWxTdG9yZSIsImlzVW5kZWZpbmVkIiwiT3Blbm1yc0ZldGNoRXJyb3IiLCJvcGVubXJzRmV0Y2giLCJyZXN0QmFzZVVybCIsInNlc3Npb25FbmRwb2ludCIsInNlc3Npb25TdG9yZSIsInNlc3Npb25NYXhBZ2VNaWxsaXMiLCJsYXN0RmV0Y2hUaW1lTWlsbGlzIiwiaW5GbGlnaHRSZWZyZXNoIiwicmVmcmVzaFNlc3Npb25JZlN0YWxlIiwiRGF0ZSIsInJlZmV0Y2hDdXJyZW50VXNlciIsImdldEN1cnJlbnRVc2VyIiwib3B0cyIsImluY2x1ZGVBdXRoU3RhdHVzIiwic2VsZWN0Iiwic2Vzc2lvbiIsInJlZnJlc2giLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlc29sdmVJZkxvYWRlZCIsInN0YXRlIiwidW5zdWJzY3JpYmUiLCJnZXRTZXNzaW9uU3RvcmUiLCJpc1ZhbGlkTG9jYWxlIiwibG9jYWxlIiwidW5kZWZpbmVkIiwiSW50bCIsImUiLCJzZXRVc2VyTGFuZ3VhZ2UiLCJkYXRhIiwiZG9jdW1lbnQiLCJ1c2VySGFzUHJpdmlsZWdlIiwicmVxdWlyZWRQcml2aWxlZ2UiLCJ1c2VyIiwicCIsIkFycmF5IiwicnAiLCJjb25zb2xlIiwiaXNTdXBlclVzZXIiLCJyb2xlIiwidXNlcm5hbWUiLCJwYXNzd29yZCIsImhlYWRlcnMiLCJ3aW5kb3ciLCJoYW5kbGVTZXNzaW9uUmVzcG9uc2UiLCJjbGVhciIsImNsZWFyQ3VycmVudFVzZXIiLCJ1c2VySGFzQWNjZXNzIiwiQm9vbGVhbiIsImdldExvZ2dlZEluVXNlciIsInJlcyIsImhhbmRsZXIiLCJnZXRTZXNzaW9uTG9jYXRpb24iLCJzZXRTZXNzaW9uTG9jYXRpb24iLCJsb2NhdGlvblV1aWQiLCJhYm9ydENvbnRyb2xsZXIiLCJzZXRTZXNzaW9uTG9jYWxlIiwic2V0VXNlclByb3BlcnRpZXMiLCJ1c2VyVXVpZCIsInVzZXJQcm9wZXJ0aWVzIiwiQWJvcnRDb250cm9sbGVyIiwidmVyaWZ5VG90cENvZGUiLCJjb2RlIiwicmVtZW1iZXJEZXZpY2UiLCJyZXNwb25zZSIsInN0b3JlIiwibG9nb3V0IiwiZXJyIiwiaXNBdXRoRmFpbHVyZSIsInJlc3VsdCIsInJlamVjdCIsIm5leHRTdGF0ZSIsInJlY29yZFNlc3Npb25GYWlsdXJlIiwiRXJyb3IiLCJpc1VuYXV0aGVudGljYXRlZFNlc3Npb24iLCJib2R5IiwiU3RyaW5nIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwwQkFBMEIsR0FBNkQ7QUFDaEM7QUFDZjtBQUMyRDtBQUNuRyxjQUFjLEdBQVUsTUFBTU8sZUFBZU4seURBQWlCQSxDQUFDLFdBQVc7SUFDdEUsUUFBUTtJQUNSLFNBQVM7QUFDYixHQUFHO0FBQ0g7Ozs7Q0FJQyxHQUFHLE1BQU1PLHNCQUFzQixLQUFLO0FBQ3JDLElBQUlDLHNCQUFzQjtBQUMxQixJQUFJQyxrQkFBa0I7QUFDdEI7Ozs7Ozs7Ozs7O0NBV0MsR0FBRyxTQUFTQztJQUNULElBQUlELGlCQUFpQjtRQUNqQixPQUFPQTtJQUNYO0lBQ0EsSUFBSUgsYUFBYSxRQUFRLEdBQUcsTUFBTSxJQUFJRSx1QkFBdUJHLEtBQUssR0FBRyxLQUFLSixxQkFBcUI7UUFDM0YsT0FBTztJQUNYO0lBQ0EsT0FBT0s7QUFDWDtBQUNBLFNBQVNDLGVBQWVDLElBQUk7SUFDeEIsTUFBTUMsb0JBQW9CRCxNQUFNLHFCQUFxQjtJQUNyRCxNQUFNRSxTQUFT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\n//# sourceURL=webpack-internal:///../../framework/esm-api/dist/current-user.js\n\n}");
4459
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n clearCurrentUser: () => (clearCurrentUser),\n getCurrentUser: () => (getCurrentUser),\n getLoggedInUser: () => (getLoggedInUser),\n getSessionLocation: () => (getSessionLocation),\n getSessionStore: () => (getSessionStore),\n logout: () => (logout),\n refetchCurrentUser: () => (refetchCurrentUser),\n sessionStore: () => (sessionStore),\n setSessionLocale: () => (setSessionLocale),\n setSessionLocation: () => (setSessionLocation),\n setUserLanguage: () => (setUserLanguage),\n setUserProperties: () => (setUserProperties),\n userHasAccess: () => (userHasAccess),\n verifyTotpCode: () => (verifyTotpCode)\n});\n/* import */ var _openmrs_esm_error_handling__rspack_import_0 = __webpack_require__(\"../../framework/esm-error-handling/dist/index.js\");\n/* import */ var _openmrs_esm_state__rspack_import_1 = __webpack_require__(\"../../framework/esm-state/dist/index.js\");\n/* import */ var lodash_es__rspack_import_3 = __webpack_require__(\"../../../node_modules/lodash-es/isUndefined.js\");\n/* import */ var _openmrs_fetch_js__rspack_import_2 = __webpack_require__(\"../../framework/esm-api/dist/openmrs-fetch.js\");\n/** @module @category API */ \n\n\n\n/** @internal */ const sessionStore = (0,_openmrs_esm_state__rspack_import_1.createGlobalStore)('session', {\n loaded: false,\n session: null\n});\n/**\n * The upper bound on how old the session handed to a reader may be. It is measured from the moment a\n * fetch is *started*, not from the moment its response lands, so the session a reader sees is always\n * strictly newer than this.\n */ const sessionMaxAgeMillis = 60 * 1000;\nlet lastFetchTimeMillis = 0;\n/**\n * How long after the first session fetch a 502 is taken to mean that the backend is still starting up. A\n * gateway answers with a 502 until the backend has deployed, which can take a few minutes after a restart.\n */ const startupGracePeriodMillis = 3 * 60 * 1000;\nlet firstFetchTimeMillis;\nlet inFlightRefresh = null;\n/**\n * Fetches the session if the store is unloaded or its session is older than `sessionMaxAgeMillis`.\n * Returns `null` only when the store already holds a session fresh enough to be read as-is, so a\n * caller that gets a promise back must wait for it rather than read the store.\n *\n * A fetch already in flight is joined rather than duplicated. This is what keeps `sessionMaxAgeMillis`\n * an upper bound: while a fetch is running, the store still holds the previous session, and returning\n * that would hand back data older than the bound allows.\n *\n * The returned promise rejects if the fetch fails, but the rejection is already handled and reported,\n * so a caller that only needs the fetch started can ignore it.\n */ function refreshSessionIfStale() {\n if (inFlightRefresh) {\n return inFlightRefresh;\n }\n if (sessionStore.getState().loaded && lastFetchTimeMillis >= Date.now() - sessionMaxAgeMillis) {\n return null;\n }\n return refetchCurrentUser();\n}\nfunction getCurrentUser(opts) {\n const includeAuthStatus = opts?.includeAuthStatus ?? true;\n const select = (session)=>includeAuthStatus ? session : session.user;\n const refresh = refreshSessionIfStale();\n if (!refresh) {\n return Promise.resolve(select(sessionStore.getState().session));\n }\n return new Promise((resolve)=>{\n const resolveIfLoaded = ()=>{\n const state = sessionStore.getState();\n if (state.loaded) {\n unsubscribe();\n resolve(select(state.session));\n }\n };\n const unsubscribe = sessionStore.subscribe(resolveIfLoaded);\n // A failed refresh keeps an already-loaded session without updating the store, so the\n // subscription alone would never fire.\n refresh.then(resolveIfLoaded, resolveIfLoaded);\n });\n}\n\n/**\n * Returns the global session store containing the current user's session information.\n * If the session data is stale (older than 1 minute) or not yet loaded, this function\n * will trigger a refetch of the current user's session.\n *\n * @returns The global session store that can be subscribed to for session updates.\n *\n * @example\n * ```ts\n * import { getSessionStore } from '@openmrs/esm-api';\n * const store = getSessionStore();\n * const unsubscribe = store.subscribe((state) => {\n * if (state.loaded) {\n * console.log('Session:', state.session);\n * }\n * });\n * ```\n */ function getSessionStore() {\n refreshSessionIfStale();\n return sessionStore;\n}\n// NB locale is string only if this returns true\nfunction isValidLocale(locale) {\n if (locale === undefined || typeof locale !== 'string') {\n return false;\n }\n try {\n new Intl.Locale(locale);\n } catch (e) {\n return false;\n }\n return true;\n}\n/**\n * Sets the document's language attribute based on the user's locale preference\n * from the session data. This affects the HTML `lang` attribute which is used\n * for accessibility and internationalization.\n *\n * The locale is determined from either the session's locale or the user's\n * default locale property. Underscores in the locale are converted to hyphens\n * to match BCP 47 language tag format.\n *\n * @param data The session object containing locale information.\n */ function setUserLanguage(data) {\n let locale = data.locale ?? data.user?.userProperties?.defaultLocale;\n // Only underscores are converted here, deliberately, rather than reusing `toLanguageTag`. i18next\n // reads this value back off `document.lang` and uses it as the translation bundle key, and those\n // bundles are named with the POSIX form (`uz@Latn.json`), so converting `@` would send the loader\n // after a bundle that does not exist.\n if (locale && locale.includes('_')) {\n locale = locale.replaceAll('_', '-');\n }\n if (isValidLocale(locale) && locale !== document.documentElement.getAttribute('lang')) {\n document.documentElement.setAttribute('lang', locale);\n }\n}\nsessionStore.subscribe((state)=>{\n if (state.loaded && state.session) {\n setUserLanguage(state.session);\n }\n});\nfunction userHasPrivilege(requiredPrivilege, user) {\n if (typeof requiredPrivilege === 'string') {\n return !(0,lodash_es__rspack_import_3[\"default\"])(user.privileges.find((p)=>requiredPrivilege === p.display));\n } else if (Array.isArray(requiredPrivilege)) {\n return requiredPrivilege.every((rp)=>!(0,lodash_es__rspack_import_3[\"default\"])(user.privileges.find((p)=>rp === p.display)));\n } else if (!(0,lodash_es__rspack_import_3[\"default\"])(requiredPrivilege)) {\n console.error(`Could not understand privileges \"${requiredPrivilege}\"`);\n }\n return true;\n}\nfunction isSuperUser(user) {\n return !(0,lodash_es__rspack_import_3[\"default\"])(user.roles.find((role)=>role.display === 'System Developer'));\n}\n/**\n * The `refetchCurrentUser` function causes a network request to redownload\n * the user. All subscribers to the session store will be notified of the\n * new user once the new version of the user object is downloaded.\n *\n * If the server rejects the request as unauthenticated (401 or 403), the store records a\n * logged-out session. If the request fails for any other reason, a session that has already\n * loaded is kept; otherwise the store records the error.\n *\n * @returns A Promise resolving to the updated session store state. It rejects with the\n * store state if the request fails for a reason other than authentication.\n *\n * @example\n * ```js\n * import { refetchCurrentUser } from '@openmrs/esm-api'\n * refetchCurrentUser()\n * ```\n */ function refetchCurrentUser(username, password) {\n lastFetchTimeMillis = Date.now();\n firstFetchTimeMillis ?? (firstFetchTimeMillis = lastFetchTimeMillis);\n let headers = {};\n if (username && password) {\n headers['Authorization'] = `Basic ${window.btoa(`${username}:${password}`)}`;\n }\n const refresh = handleSessionResponse((0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n headers,\n rejectAuthFailure: true\n }));\n // Publish the request so that readers can wait on it instead of reading the session it is about to\n // replace. Each call still issues its own request; this only tracks the most recent one.\n const clear = ()=>{\n if (inFlightRefresh === refresh) {\n inFlightRefresh = null;\n }\n };\n refresh.then(clear, clear);\n inFlightRefresh = refresh;\n return refresh;\n}\n/**\n * Clears the current user session from the session store, setting the session\n * to an unauthenticated state. This is typically called during logout to reset\n * the application's authentication state.\n *\n * @example\n * ```ts\n * import { clearCurrentUser } from '@openmrs/esm-api';\n * // During logout\n * clearCurrentUser();\n * ```\n */ function clearCurrentUser() {\n sessionStore.setState({\n loaded: true,\n session: {\n authenticated: false,\n sessionId: ''\n }\n }, true);\n}\n/**\n * Checks whether the given user has access based on the required privilege(s).\n * A user has access if they have the required privilege(s) or if they are a\n * \"System Developer\" (super user). If no privilege is required, access is granted.\n *\n * @param requiredPrivilege A single privilege string or an array of privilege strings\n * that the user must have. If an array is provided, the user must have ALL privileges.\n * @param user The user object containing their privileges and roles.\n * @returns `true` if the user has access, `false` otherwise. Returns `true` if no\n * privilege is required, and `false` if the user is undefined but a privilege is required.\n *\n * @example\n * ```ts\n * import { userHasAccess } from '@openmrs/esm-api';\n * const hasAccess = userHasAccess('View Patients', currentUser);\n * const hasMultipleAccess = userHasAccess(['View Patients', 'Edit Patients'], currentUser);\n * ```\n */ function userHasAccess(requiredPrivilege, user) {\n if (user === undefined) {\n // if the user hasn't been loaded, then return false iff there is a required privilege\n return !Boolean(requiredPrivilege);\n }\n if (!Boolean(requiredPrivilege)) {\n // if user exists but no requiredPrivilege is defined\n return true;\n }\n return userHasPrivilege(requiredPrivilege, user) || isSuperUser(user);\n}\n/**\n * Returns a Promise that resolves with the currently logged-in user object.\n * If the user is already loaded in the session store, the Promise resolves immediately.\n * Otherwise, it subscribes to the session store and resolves when a logged-in user\n * becomes available.\n *\n * @returns A Promise that resolves with the LoggedInUser object once available.\n *\n * @example\n * ```ts\n * import { getLoggedInUser } from '@openmrs/esm-api';\n * const user = await getLoggedInUser();\n * console.log('Logged in as:', user.display);\n * ```\n */ function getLoggedInUser() {\n let user;\n let unsubscribe;\n return new Promise((res)=>{\n const handler = (state)=>{\n if (state.loaded && state.session.user) {\n user = state.session.user;\n res(state.session.user);\n if (unsubscribe) {\n unsubscribe();\n }\n }\n };\n handler(sessionStore.getState());\n if (!user) {\n unsubscribe = sessionStore.subscribe(handler);\n }\n });\n}\n/**\n * Returns a Promise that resolves with the current session location, if one is set.\n * The session location represents the physical location where the user is currently\n * working (e.g., a clinic or ward).\n *\n * @returns A Promise that resolves with the SessionLocation object, or `undefined`\n * if no session location is set.\n *\n * @example\n * ```ts\n * import { getSessionLocation } from '@openmrs/esm-api';\n * const location = await getSessionLocation();\n * if (location) {\n * console.log('Current location:', location.display);\n * }\n * ```\n */ async function getSessionLocation() {\n const session = await getCurrentUser();\n return session.sessionLocation;\n}\n/**\n * Sets the session location for the current user. The session location represents\n * the physical location where the user is working (e.g., a clinic or ward).\n * This triggers a server request to update the session and refreshes the local\n * session store.\n *\n * @param locationUuid The UUID of the location to set as the session location.\n * @param abortController An AbortController to allow cancellation of the request.\n * @returns A Promise that resolves with the updated SessionStore.\n *\n * @example\n * ```ts\n * import { setSessionLocation } from '@openmrs/esm-api';\n * const abortController = new AbortController();\n * await setSessionLocation('location-uuid-here', abortController);\n * ```\n */ async function setSessionLocation(locationUuid, abortController) {\n return handleSessionResponse((0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'POST',\n body: {\n sessionLocation: locationUuid\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n rejectAuthFailure: true,\n signal: abortController?.signal\n }));\n}\n/**\n * Sets the locale for the current session only, leaving the user's default locale unchanged.\n * Use {@link setUserProperties} with a `defaultLocale` property to change the default instead.\n *\n * @param locale The locale in Java's `Locale#toString()` form, e.g. `en_GB`.\n * @param abortController Optional AbortController to allow cancellation of the request.\n * @returns A Promise that resolves with the updated SessionStore after refetching the current user.\n * It rejects with an {@link OpenmrsFetchError} if the server does not accept the locale.\n *\n * @example\n * ```ts\n * import { setSessionLocale } from '@openmrs/esm-api';\n * await setSessionLocale('fr');\n * ```\n *\n * @internal\n */ async function setSessionLocale(locale, abortController) {\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'POST',\n body: {\n locale\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: abortController?.signal\n });\n return refetchCurrentUser();\n}\n/**\n * Updates the user properties for a specific user. User properties are key-value\n * pairs that store user-specific settings and preferences. After updating the\n * properties on the server, the current user session is refetched to reflect\n * the changes.\n *\n * @param userUuid The UUID of the user whose properties should be updated.\n * @param userProperties An object containing the properties to set or update.\n * @param abortController Optional AbortController to allow cancellation of the request.\n * If not provided, a new AbortController is created.\n * @returns A Promise that resolves with the updated SessionStore after refetching\n * the current user.\n *\n * @example\n * ```ts\n * import { getLoggedInUser, setUserProperties } from '@openmrs/esm-api';\n * const user = await getLoggedInUser();\n * await setUserProperties(user.uuid, {\n * defaultLocale: 'en_GB',\n * customSetting: 'value'\n * });\n * ```\n */ async function setUserProperties(userUuid, userProperties, abortController) {\n if (!abortController) {\n abortController = new AbortController();\n }\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(`${_openmrs_fetch_js__rspack_import_2.restBaseUrl}/user/${userUuid}`, {\n method: 'POST',\n body: {\n userProperties\n },\n headers: {\n 'Content-Type': 'application/json'\n },\n signal: abortController.signal\n });\n return refetchCurrentUser();\n}\n/**\n * Submits a TOTP code to complete a two-factor login challenge. When the code is accepted, the\n * session store is refreshed with the now-authenticated session.\n *\n * @param code The code from the user's authenticator app.\n * @param rememberDevice Whether the server should skip the challenge on this device in future.\n * @returns A Promise resolving to the session. Its `authenticated` property is `false` if the\n * code was not accepted. It rejects with an {@link OpenmrsFetchError} if the server rejects the\n * request, in which case `responseBody` may explain why.\n *\n * @example\n * ```ts\n * import { verifyTotpCode } from '@openmrs/esm-api';\n * const session = await verifyTotpCode('123456', true);\n * ```\n *\n * @internal\n */ async function verifyTotpCode(code, rememberDevice = false) {\n const response = await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(rememberDevice ? `${_openmrs_fetch_js__rspack_import_2.sessionEndpoint}?rememberMe=true` : _openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n headers: {\n 'X-Totp-Code': code\n }\n });\n if (response.data?.authenticated) {\n // `refetchCurrentUser` only resolves once the store holds a session.\n const store = await refetchCurrentUser();\n return store.session;\n }\n return response.data;\n}\n/**\n * Ends the current session on the server and records a logged-out session in the session store.\n * A server that has already ended the session (401 or 403) counts as a successful logout.\n *\n * Other data cached for the logged-in user, such as SWR caches, is the caller's to clear.\n *\n * @returns A Promise that resolves once the session store holds a logged-out session.\n *\n * @example\n * ```ts\n * import { logout } from '@openmrs/esm-api';\n * await logout();\n * ```\n *\n * @internal\n */ async function logout() {\n try {\n await (0,_openmrs_fetch_js__rspack_import_2.openmrsFetch)(_openmrs_fetch_js__rspack_import_2.sessionEndpoint, {\n method: 'DELETE',\n rejectAuthFailure: true\n });\n } catch (err) {\n if (!isAuthFailure(err)) {\n throw err;\n }\n }\n clearCurrentUser();\n // The session just cleared is already correct, so a failed refresh loses nothing.\n await refetchCurrentUser().catch(()=>{});\n}\nfunction handleSessionResponse(result) {\n return new Promise((resolve, reject)=>{\n result.then((res)=>{\n if (typeof res?.data === 'object') {\n const nextState = {\n loaded: true,\n session: res.data\n };\n sessionStore.setState(nextState, true);\n resolve(nextState);\n } else if (isInitialSetupRedirect(res)) {\n reject(recordSessionFailure(Error('The server is still starting up'), true));\n } else {\n reject(recordSessionFailure(Error('The session endpoint did not respond with a session')));\n }\n }).catch((err)=>{\n // An auth failure is the session endpoint's answer for \"not logged in\", not a failed lookup.\n if (isAuthFailure(err)) {\n if (isUnauthenticatedSession(err.responseBody)) {\n sessionStore.setState({\n loaded: true,\n session: err.responseBody\n }, true);\n } else {\n clearCurrentUser();\n }\n resolve(sessionStore.getState());\n return;\n }\n if (isGatewayErrorDuringStartup(err)) {\n reject(recordSessionFailure(err, true));\n return;\n }\n (0,_openmrs_esm_error_handling__rspack_import_0.reportError)(`Failed to fetch new session information: ${err}`);\n reject(recordSessionFailure(err));\n });\n });\n}\nfunction isAuthFailure(err) {\n return err instanceof _openmrs_fetch_js__rspack_import_2.OpenmrsFetchError && (err.response.status === 401 || err.response.status === 403);\n}\n/**\n * Until the backend has finished its initial setup, it answers every request with a redirect to its\n * setup page, which `fetch()` follows, so the session request resolves with that page's HTML.\n */ function isInitialSetupRedirect(res) {\n if (!res?.redirected || !res.url) {\n return false;\n }\n try {\n return new URL(res.url, window.location.href).pathname.replace(/\\/+$/, '').endsWith('/initialsetup');\n } catch {\n return false;\n }\n}\nfunction isGatewayErrorDuringStartup(err) {\n return err instanceof _openmrs_fetch_js__rspack_import_2.OpenmrsFetchError && err.response.status === 502 && !sessionStore.getState().loaded && firstFetchTimeMillis !== undefined && Date.now() - firstFetchTimeMillis < startupGracePeriodMillis;\n}\nfunction isUnauthenticatedSession(body) {\n return typeof body === 'object' && body !== null && body.authenticated === false;\n}\n/**\n * A session that has already loaded is kept when a later fetch fails, since it is still the best answer\n * available. With nothing to fall back on, the error is recorded so the app shell can show an error page.\n */ function recordSessionFailure(err, initializing = false) {\n if (!sessionStore.getState().loaded) {\n sessionStore.setState({\n loaded: false,\n session: null,\n error: err instanceof Error ? err : Error(String(err)),\n initializing\n }, true);\n }\n return sessionStore.getState();\n}\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1hcGkvZGlzdC9jdXJyZW50LXVzZXIuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tYXBpL2Rpc3QvY3VycmVudC11c2VyLmpzPzcxMjkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBtb2R1bGUgQGNhdGVnb3J5IEFQSSAqLyBpbXBvcnQgeyByZXBvcnRFcnJvciB9IGZyb20gXCJAb3Blbm1ycy9lc20tZXJyb3ItaGFuZGxpbmdcIjtcbmltcG9ydCB7IGNyZWF0ZUdsb2JhbFN0b3JlIH0gZnJvbSBcIkBvcGVubXJzL2VzbS1zdGF0ZVwiO1xuaW1wb3J0IHsgaXNVbmRlZmluZWQgfSBmcm9tIFwibG9kYXNoLWVzXCI7XG5pbXBvcnQgeyBPcGVubXJzRmV0Y2hFcnJvciwgb3Blbm1yc0ZldGNoLCByZXN0QmFzZVVybCwgc2Vzc2lvbkVuZHBvaW50IH0gZnJvbSBcIi4vb3Blbm1ycy1mZXRjaC5qc1wiO1xuLyoqIEBpbnRlcm5hbCAqLyBleHBvcnQgY29uc3Qgc2Vzc2lvblN0b3JlID0gY3JlYXRlR2xvYmFsU3RvcmUoJ3Nlc3Npb24nLCB7XG4gICAgbG9hZGVkOiBmYWxzZSxcbiAgICBzZXNzaW9uOiBudWxsXG59KTtcbi8qKlxuICogVGhlIHVwcGVyIGJvdW5kIG9uIGhvdyBvbGQgdGhlIHNlc3Npb24gaGFuZGVkIHRvIGEgcmVhZGVyIG1heSBiZS4gSXQgaXMgbWVhc3VyZWQgZnJvbSB0aGUgbW9tZW50IGFcbiAqIGZldGNoIGlzICpzdGFydGVkKiwgbm90IGZyb20gdGhlIG1vbWVudCBpdHMgcmVzcG9uc2UgbGFuZHMsIHNvIHRoZSBzZXNzaW9uIGEgcmVhZGVyIHNlZXMgaXMgYWx3YXlzXG4gKiBzdHJpY3RseSBuZXdlciB0aGFuIHRoaXMuXG4gKi8gY29uc3Qgc2Vzc2lvbk1heEFnZU1pbGxpcyA9IDYwICogMTAwMDtcbmxldCBsYXN0RmV0Y2hUaW1lTWlsbGlzID0gMDtcbi8qKlxuICogSG93IGxvbmcgYWZ0ZXIgdGhlIGZpcnN0IHNlc3Npb24gZmV0Y2ggYSA1MDIgaXMgdGFrZW4gdG8gbWVhbiB0aGF0IHRoZSBiYWNrZW5kIGlzIHN0aWxsIHN0YXJ0aW5nIHVwLiBBXG4gKiBnYXRld2F5IGFuc3dlcnMgd2l0aCBhIDUwMiB1bnRpbCB0aGUgYmFja2VuZCBoYXMgZGVwbG95ZWQsIHdoaWNoIGNhbiB0YWtlIGEgZmV3IG1pbnV0ZXMgYWZ0ZXIgYSByZXN0YXJ0LlxuICovIGNvbnN0IHN0YXJ0dXBHcmFjZVBlcmlvZE1pbGxpcyA9IDMgKiA2MCAqIDEwMDA7XG5sZXQgZmlyc3RGZXRjaFRpbWVNaWxsaXM7XG5sZXQgaW5GbGlnaHRSZWZyZXNoID0gbnVsbDtcbi8qKlxuICogRmV0Y2hlcyB0aGUgc2Vzc2lvbiBpZiB0aGUgc3RvcmUgaXMgdW5sb2FkZWQgb3IgaXRzIHNlc3Npb24gaXMgb2xkZXIgdGhhbiBgc2Vzc2lvbk1heEFnZU1pbGxpc2AuXG4gKiBSZXR1cm5zIGBudWxsYCBvbmx5IHdoZW4gdGhlIHN0b3JlIGFscmVhZHkgaG9sZHMgYSBzZXNzaW9uIGZyZXNoIGVub3VnaCB0byBiZSByZWFkIGFzLWlzLCBzbyBhXG4gKiBjYWxsZXIgdGhhdCBnZXRzIGEgcHJvbWlzZSBiYWNrIG11c3Qgd2FpdCBmb3IgaXQgcmF0aGVyIHRoYW4gcmVhZCB0aGUgc3RvcmUuXG4gKlxuICogQSBmZXRjaCBhbHJlYWR5IGluIGZsaWdodCBpcyBqb2luZWQgcmF0aGVyIHRoYW4gZHVwbGljYXRlZC4gVGhpcyBpcyB3aGF0IGtlZXBzIGBzZXNzaW9uTWF4QWdlTWlsbGlzYFxuICogYW4gdXBwZXIgYm91bmQ6IHdoaWxlIGEgZmV0Y2ggaXMgcnVubmluZywgdGhlIHN0b3JlIHN0aWxsIGhvbGRzIHRoZSBwcmV2aW91cyBzZXNzaW9uLCBhbmQgcmV0dXJuaW5nXG4gKiB0aGF0IHdvdWxkIGhhbmQgYmFjayBkYXRhIG9sZGVyIHRoYW4gdGhlIGJvdW5kIGFsbG93cy5cbiAqXG4gKiBUaGUgcmV0dXJuZWQgcHJvbWlzZSByZWplY3RzIGlmIHRoZSBmZXRjaCBmYWlscywgYnV0IHRoZSByZWplY3Rpb24gaXMgYWxyZWFkeSBoYW5kbGVkIGFuZCByZXBvcnRlZCxcbiAqIHNvIGEgY2FsbGVyIHRoYXQgb25seSBuZWVkcyB0aGUgZmV0Y2ggc3RhcnRlZCBjYW4gaWdub3JlIGl0LlxuICovIGZ1bmN0aW9uIHJlZnJlc2hTZXNzaW9uSWZTdGFsZSgpIHtcbiAgICBpZiAoaW5GbGlnaHRSZWZyZXNoKSB7XG4gICAgICAgIHJldHVybiBpbkZsaWdodFJlZnJlc2g7XG4gICAgfVxuICAgIGlmIChzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKS5sb2FkZWQgJiYgbGFzdEZldGNoVGltZU1pbGxpcyA+PSBEYXRlLm5vdygpIC0gc2Vzc2lvbk1heEFnZU1pbGxpcykge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHJlZmV0Y2hDdXJyZW50VXNlcigpO1xufVxuZnVuY3Rpb24gZ2V0Q3VycmVudFVzZXIob3B0cykge1xuICAgIGNvbnN0IGluY2x1ZGVBdXRoU3RhdHVzID0gb3B0cz8uaW5jbHVkZUF1dGhTdGF0dXMgPz8gdHJ1ZTtcbiAgICBjb25zdCBzZWxlY3QgPSAoc2Vzc2lvbik9PmluY2x1ZGVBdXRoU3RhdHVzID8gc2Vzc2lvbiA6IHNlc3Npb24udXNlcjtcbiAgICBjb25zdCByZWZyZXNoID0gcmVmcmVzaFNlc3Npb25JZlN0YWxlKCk7XG4gICAgaWYgKCFyZWZyZXNoKSB7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoc2VsZWN0KHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLnNlc3Npb24pKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICBjb25zdCByZXNvbHZlSWZMb2FkZWQgPSAoKT0+e1xuICAgICAgICAgICAgY29uc3Qgc3RhdGUgPSBzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICAgICAgICAgIGlmIChzdGF0ZS5sb2FkZWQpIHtcbiAgICAgICAgICAgICAgICB1bnN1YnNjcmliZSgpO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoc2VsZWN0KHN0YXRlLnNlc3Npb24pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgICAgY29uc3QgdW5zdWJzY3JpYmUgPSBzZXNzaW9uU3RvcmUuc3Vic2NyaWJlKHJlc29sdmVJZkxvYWRlZCk7XG4gICAgICAgIC8vIEEgZmFpbGVkIHJlZnJlc2gga2VlcHMgYW4gYWxyZWFkeS1sb2FkZWQgc2Vzc2lvbiB3aXRob3V0IHVwZGF0aW5nIHRoZSBzdG9yZSwgc28gdGhlXG4gICAgICAgIC8vIHN1YnNjcmlwdGlvbiBhbG9uZSB3b3VsZCBuZXZlciBmaXJlLlxuICAgICAgICByZWZyZXNoLnRoZW4ocmVzb2x2ZUlmTG9hZGVkLCByZXNvbHZlSWZMb2FkZWQpO1xuICAgIH0pO1xufVxuZXhwb3J0IHsgZ2V0Q3VycmVudFVzZXIgfTtcbi8qKlxuICogUmV0dXJucyB0aGUgZ2xvYmFsIHNlc3Npb24gc3RvcmUgY29udGFpbmluZyB0aGUgY3VycmVudCB1c2VyJ3Mgc2Vzc2lvbiBpbmZvcm1hdGlvbi5cbiAqIElmIHRoZSBzZXNzaW9uIGRhdGEgaXMgc3RhbGUgKG9sZGVyIHRoYW4gMSBtaW51dGUpIG9yIG5vdCB5ZXQgbG9hZGVkLCB0aGlzIGZ1bmN0aW9uXG4gKiB3aWxsIHRyaWdnZXIgYSByZWZldGNoIG9mIHRoZSBjdXJyZW50IHVzZXIncyBzZXNzaW9uLlxuICpcbiAqIEByZXR1cm5zIFRoZSBnbG9iYWwgc2Vzc2lvbiBzdG9yZSB0aGF0IGNhbiBiZSBzdWJzY3JpYmVkIHRvIGZvciBzZXNzaW9uIHVwZGF0ZXMuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBnZXRTZXNzaW9uU3RvcmUgfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGNvbnN0IHN0b3JlID0gZ2V0U2Vzc2lvblN0b3JlKCk7XG4gKiBjb25zdCB1bnN1YnNjcmliZSA9IHN0b3JlLnN1YnNjcmliZSgoc3RhdGUpID0+IHtcbiAqICAgaWYgKHN0YXRlLmxvYWRlZCkge1xuICogICAgIGNvbnNvbGUubG9nKCdTZXNzaW9uOicsIHN0YXRlLnNlc3Npb24pO1xuICogICB9XG4gKiB9KTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRTZXNzaW9uU3RvcmUoKSB7XG4gICAgcmVmcmVzaFNlc3Npb25JZlN0YWxlKCk7XG4gICAgcmV0dXJuIHNlc3Npb25TdG9yZTtcbn1cbi8vIE5CIGxvY2FsZSBpcyBzdHJpbmcgb25seSBpZiB0aGlzIHJldHVybnMgdHJ1ZVxuZnVuY3Rpb24gaXNWYWxpZExvY2FsZShsb2NhbGUpIHtcbiAgICBpZiAobG9jYWxlID09PSB1bmRlZmluZWQgfHwgdHlwZW9mIGxvY2FsZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgICBuZXcgSW50bC5Mb2NhbGUobG9jYWxlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIFNldHMgdGhlIGRvY3VtZW50J3MgbGFuZ3VhZ2UgYXR0cmlidXRlIGJhc2VkIG9uIHRoZSB1c2VyJ3MgbG9jYWxlIHByZWZlcmVuY2VcbiAqIGZyb20gdGhlIHNlc3Npb24gZGF0YS4gVGhpcyBhZmZlY3RzIHRoZSBIVE1MIGBsYW5nYCBhdHRyaWJ1dGUgd2hpY2ggaXMgdXNlZFxuICogZm9yIGFjY2Vzc2liaWxpdHkgYW5kIGludGVybmF0aW9uYWxpemF0aW9uLlxuICpcbiAqIFRoZSBsb2NhbGUgaXMgZGV0ZXJtaW5lZCBmcm9tIGVpdGhlciB0aGUgc2Vzc2lvbidzIGxvY2FsZSBvciB0aGUgdXNlcidzXG4gKiBkZWZhdWx0IGxvY2FsZSBwcm9wZXJ0eS4gVW5kZXJzY29yZXMgaW4gdGhlIGxvY2FsZSBhcmUgY29udmVydGVkIHRvIGh5cGhlbnNcbiAqIHRvIG1hdGNoIEJDUCA0NyBsYW5ndWFnZSB0YWcgZm9ybWF0LlxuICpcbiAqIEBwYXJhbSBkYXRhIFRoZSBzZXNzaW9uIG9iamVjdCBjb250YWluaW5nIGxvY2FsZSBpbmZvcm1hdGlvbi5cbiAqLyBleHBvcnQgZnVuY3Rpb24gc2V0VXNlckxhbmd1YWdlKGRhdGEpIHtcbiAgICBsZXQgbG9jYWxlID0gZGF0YS5sb2NhbGUgPz8gZGF0YS51c2VyPy51c2VyUHJvcGVydGllcz8uZGVmYXVsdExvY2FsZTtcbiAgICAvLyBPbmx5IHVuZGVyc2NvcmVzIGFyZSBjb252ZXJ0ZWQgaGVyZSwgZGVsaWJlcmF0ZWx5LCByYXRoZXIgdGhhbiByZXVzaW5nIGB0b0xhbmd1YWdlVGFnYC4gaTE4bmV4dFxuICAgIC8vIHJlYWRzIHRoaXMgdmFsdWUgYmFjayBvZmYgYGRvY3VtZW50LmxhbmdgIGFuZCB1c2VzIGl0IGFzIHRoZSB0cmFuc2xhdGlvbiBidW5kbGUga2V5LCBhbmQgdGhvc2VcbiAgICAvLyBidW5kbGVzIGFyZSBuYW1lZCB3aXRoIHRoZSBQT1NJWCBmb3JtIChgdXpATGF0bi5qc29uYCksIHNvIGNvbnZlcnRpbmcgYEBgIHdvdWxkIHNlbmQgdGhlIGxvYWRlclxuICAgIC8vIGFmdGVyIGEgYnVuZGxlIHRoYXQgZG9lcyBub3QgZXhpc3QuXG4gICAgaWYgKGxvY2FsZSAmJiBsb2NhbGUuaW5jbHVkZXMoJ18nKSkge1xuICAgICAgICBsb2NhbGUgPSBsb2NhbGUucmVwbGFjZUFsbCgnXycsICctJyk7XG4gICAgfVxuICAgIGlmIChpc1ZhbGlkTG9jYWxlKGxvY2FsZSkgJiYgbG9jYWxlICE9PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZ2V0QXR0cmlidXRlKCdsYW5nJykpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgnbGFuZycsIGxvY2FsZSk7XG4gICAgfVxufVxuc2Vzc2lvblN0b3JlLnN1YnNjcmliZSgoc3RhdGUpPT57XG4gICAgaWYgKHN0YXRlLmxvYWRlZCAmJiBzdGF0ZS5zZXNzaW9uKSB7XG4gICAgICAgIHNldFVzZXJMYW5ndWFnZShzdGF0ZS5zZXNzaW9uKTtcbiAgICB9XG59KTtcbmZ1bmN0aW9uIHVzZXJIYXNQcml2aWxlZ2UocmVxdWlyZWRQcml2aWxlZ2UsIHVzZXIpIHtcbiAgICBpZiAodHlwZW9mIHJlcXVpcmVkUHJpdmlsZWdlID09PSAnc3RyaW5nJykge1xuICAgICAgICByZXR1cm4gIWlzVW5kZWZpbmVkKHVzZXIucHJpdmlsZWdlcy5maW5kKChwKT0+cmVxdWlyZWRQcml2aWxlZ2UgPT09IHAuZGlzcGxheSkpO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShyZXF1aXJlZFByaXZpbGVnZSkpIHtcbiAgICAgICAgcmV0dXJuIHJlcXVpcmVkUHJpdmlsZWdlLmV2ZXJ5KChycCk9PiFpc1VuZGVmaW5lZCh1c2VyLnByaXZpbGVnZXMuZmluZCgocCk9PnJwID09PSBwLmRpc3BsYXkpKSk7XG4gICAgfSBlbHNlIGlmICghaXNVbmRlZmluZWQocmVxdWlyZWRQcml2aWxlZ2UpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENvdWxkIG5vdCB1bmRlcnN0YW5kIHByaXZpbGVnZXMgXCIke3JlcXVpcmVkUHJpdmlsZWdlfVwiYCk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuZnVuY3Rpb24gaXNTdXBlclVzZXIodXNlcikge1xuICAgIHJldHVybiAhaXNVbmRlZmluZWQodXNlci5yb2xlcy5maW5kKChyb2xlKT0+cm9sZS5kaXNwbGF5ID09PSAnU3lzdGVtIERldmVsb3BlcicpKTtcbn1cbi8qKlxuICogVGhlIGByZWZldGNoQ3VycmVudFVzZXJgIGZ1bmN0aW9uIGNhdXNlcyBhIG5ldHdvcmsgcmVxdWVzdCB0byByZWRvd25sb2FkXG4gKiB0aGUgdXNlci4gQWxsIHN1YnNjcmliZXJzIHRvIHRoZSBzZXNzaW9uIHN0b3JlIHdpbGwgYmUgbm90aWZpZWQgb2YgdGhlXG4gKiBuZXcgdXNlciBvbmNlIHRoZSBuZXcgdmVyc2lvbiBvZiB0aGUgdXNlciBvYmplY3QgaXMgZG93bmxvYWRlZC5cbiAqXG4gKiBJZiB0aGUgc2VydmVyIHJlamVjdHMgdGhlIHJlcXVlc3QgYXMgdW5hdXRoZW50aWNhdGVkICg0MDEgb3IgNDAzKSwgdGhlIHN0b3JlIHJlY29yZHMgYVxuICogbG9nZ2VkLW91dCBzZXNzaW9uLiBJZiB0aGUgcmVxdWVzdCBmYWlscyBmb3IgYW55IG90aGVyIHJlYXNvbiwgYSBzZXNzaW9uIHRoYXQgaGFzIGFscmVhZHlcbiAqIGxvYWRlZCBpcyBrZXB0OyBvdGhlcndpc2UgdGhlIHN0b3JlIHJlY29yZHMgdGhlIGVycm9yLlxuICpcbiAqIEByZXR1cm5zIEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIHVwZGF0ZWQgc2Vzc2lvbiBzdG9yZSBzdGF0ZS4gSXQgcmVqZWN0cyB3aXRoIHRoZVxuICogICBzdG9yZSBzdGF0ZSBpZiB0aGUgcmVxdWVzdCBmYWlscyBmb3IgYSByZWFzb24gb3RoZXIgdGhhbiBhdXRoZW50aWNhdGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBganNcbiAqIGltcG9ydCB7IHJlZmV0Y2hDdXJyZW50VXNlciB9IGZyb20gJ0BvcGVubXJzL2VzbS1hcGknXG4gKiByZWZldGNoQ3VycmVudFVzZXIoKVxuICogYGBgXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlZmV0Y2hDdXJyZW50VXNlcih1c2VybmFtZSwgcGFzc3dvcmQpIHtcbiAgICBsYXN0RmV0Y2hUaW1lTWlsbGlzID0gRGF0ZS5ub3coKTtcbiAgICBmaXJzdEZldGNoVGltZU1pbGxpcyA/PyAoZmlyc3RGZXRjaFRpbWVNaWxsaXMgPSBsYXN0RmV0Y2hUaW1lTWlsbGlzKTtcbiAgICBsZXQgaGVhZGVycyA9IHt9O1xuICAgIGlmICh1c2VybmFtZSAmJiBwYXNzd29yZCkge1xuICAgICAgICBoZWFkZXJzWydBdXRob3JpemF0aW9uJ10gPSBgQmFzaWMgJHt3aW5kb3cuYnRvYShgJHt1c2VybmFtZX06JHtwYXNzd29yZH1gKX1gO1xuICAgIH1cbiAgICBjb25zdCByZWZyZXNoID0gaGFuZGxlU2Vzc2lvblJlc3BvbnNlKG9wZW5tcnNGZXRjaChzZXNzaW9uRW5kcG9pbnQsIHtcbiAgICAgICAgaGVhZGVycyxcbiAgICAgICAgcmVqZWN0QXV0aEZhaWx1cmU6IHRydWVcbiAgICB9KSk7XG4gICAgLy8gUHVibGlzaCB0aGUgcmVxdWVzdCBzbyB0aGF0IHJlYWRlcnMgY2FuIHdhaXQgb24gaXQgaW5zdGVhZCBvZiByZWFkaW5nIHRoZSBzZXNzaW9uIGl0IGlzIGFib3V0IHRvXG4gICAgLy8gcmVwbGFjZS4gRWFjaCBjYWxsIHN0aWxsIGlzc3VlcyBpdHMgb3duIHJlcXVlc3Q7IHRoaXMgb25seSB0cmFja3MgdGhlIG1vc3QgcmVjZW50IG9uZS5cbiAgICBjb25zdCBjbGVhciA9ICgpPT57XG4gICAgICAgIGlmIChpbkZsaWdodFJlZnJlc2ggPT09IHJlZnJlc2gpIHtcbiAgICAgICAgICAgIGluRmxpZ2h0UmVmcmVzaCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJlZnJlc2gudGhlbihjbGVhciwgY2xlYXIpO1xuICAgIGluRmxpZ2h0UmVmcmVzaCA9IHJlZnJlc2g7XG4gICAgcmV0dXJuIHJlZnJlc2g7XG59XG4vKipcbiAqIENsZWFycyB0aGUgY3VycmVudCB1c2VyIHNlc3Npb24gZnJvbSB0aGUgc2Vzc2lvbiBzdG9yZSwgc2V0dGluZyB0aGUgc2Vzc2lvblxuICogdG8gYW4gdW5hdXRoZW50aWNhdGVkIHN0YXRlLiBUaGlzIGlzIHR5cGljYWxseSBjYWxsZWQgZHVyaW5nIGxvZ291dCB0byByZXNldFxuICogdGhlIGFwcGxpY2F0aW9uJ3MgYXV0aGVudGljYXRpb24gc3RhdGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBjbGVhckN1cnJlbnRVc2VyIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiAvLyBEdXJpbmcgbG9nb3V0XG4gKiBjbGVhckN1cnJlbnRVc2VyKCk7XG4gKiBgYGBcbiAqLyBleHBvcnQgZnVuY3Rpb24gY2xlYXJDdXJyZW50VXNlcigpIHtcbiAgICBzZXNzaW9uU3RvcmUuc2V0U3RhdGUoe1xuICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgIHNlc3Npb246IHtcbiAgICAgICAgICAgIGF1dGhlbnRpY2F0ZWQ6IGZhbHNlLFxuICAgICAgICAgICAgc2Vzc2lvbklkOiAnJ1xuICAgICAgICB9XG4gICAgfSwgdHJ1ZSk7XG59XG4vKipcbiAqIENoZWNrcyB3aGV0aGVyIHRoZSBnaXZlbiB1c2VyIGhhcyBhY2Nlc3MgYmFzZWQgb24gdGhlIHJlcXVpcmVkIHByaXZpbGVnZShzKS5cbiAqIEEgdXNlciBoYXMgYWNjZXNzIGlmIHRoZXkgaGF2ZSB0aGUgcmVxdWlyZWQgcHJpdmlsZWdlKHMpIG9yIGlmIHRoZXkgYXJlIGFcbiAqIFwiU3lzdGVtIERldmVsb3BlclwiIChzdXBlciB1c2VyKS4gSWYgbm8gcHJpdmlsZWdlIGlzIHJlcXVpcmVkLCBhY2Nlc3MgaXMgZ3JhbnRlZC5cbiAqXG4gKiBAcGFyYW0gcmVxdWlyZWRQcml2aWxlZ2UgQSBzaW5nbGUgcHJpdmlsZWdlIHN0cmluZyBvciBhbiBhcnJheSBvZiBwcml2aWxlZ2Ugc3RyaW5nc1xuICogICB0aGF0IHRoZSB1c2VyIG11c3QgaGF2ZS4gSWYgYW4gYXJyYXkgaXMgcHJvdmlkZWQsIHRoZSB1c2VyIG11c3QgaGF2ZSBBTEwgcHJpdmlsZWdlcy5cbiAqIEBwYXJhbSB1c2VyIFRoZSB1c2VyIG9iamVjdCBjb250YWluaW5nIHRoZWlyIHByaXZpbGVnZXMgYW5kIHJvbGVzLlxuICogQHJldHVybnMgYHRydWVgIGlmIHRoZSB1c2VyIGhhcyBhY2Nlc3MsIGBmYWxzZWAgb3RoZXJ3aXNlLiBSZXR1cm5zIGB0cnVlYCBpZiBub1xuICogICBwcml2aWxlZ2UgaXMgcmVxdWlyZWQsIGFuZCBgZmFsc2VgIGlmIHRoZSB1c2VyIGlzIHVuZGVmaW5lZCBidXQgYSBwcml2aWxlZ2UgaXMgcmVxdWlyZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyB1c2VySGFzQWNjZXNzIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBjb25zdCBoYXNBY2Nlc3MgPSB1c2VySGFzQWNjZXNzKCdWaWV3IFBhdGllbnRzJywgY3VycmVudFVzZXIpO1xuICogY29uc3QgaGFzTXVsdGlwbGVBY2Nlc3MgPSB1c2VySGFzQWNjZXNzKFsnVmlldyBQYXRpZW50cycsICdFZGl0IFBhdGllbnRzJ10sIGN1cnJlbnRVc2VyKTtcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiB1c2VySGFzQWNjZXNzKHJlcXVpcmVkUHJpdmlsZWdlLCB1c2VyKSB7XG4gICAgaWYgKHVzZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAvLyBpZiB0aGUgdXNlciBoYXNuJ3QgYmVlbiBsb2FkZWQsIHRoZW4gcmV0dXJuIGZhbHNlIGlmZiB0aGVyZSBpcyBhIHJlcXVpcmVkIHByaXZpbGVnZVxuICAgICAgICByZXR1cm4gIUJvb2xlYW4ocmVxdWlyZWRQcml2aWxlZ2UpO1xuICAgIH1cbiAgICBpZiAoIUJvb2xlYW4ocmVxdWlyZWRQcml2aWxlZ2UpKSB7XG4gICAgICAgIC8vIGlmIHVzZXIgZXhpc3RzIGJ1dCBubyByZXF1aXJlZFByaXZpbGVnZSBpcyBkZWZpbmVkXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gdXNlckhhc1ByaXZpbGVnZShyZXF1aXJlZFByaXZpbGVnZSwgdXNlcikgfHwgaXNTdXBlclVzZXIodXNlcik7XG59XG4vKipcbiAqIFJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgY3VycmVudGx5IGxvZ2dlZC1pbiB1c2VyIG9iamVjdC5cbiAqIElmIHRoZSB1c2VyIGlzIGFscmVhZHkgbG9hZGVkIGluIHRoZSBzZXNzaW9uIHN0b3JlLCB0aGUgUHJvbWlzZSByZXNvbHZlcyBpbW1lZGlhdGVseS5cbiAqIE90aGVyd2lzZSwgaXQgc3Vic2NyaWJlcyB0byB0aGUgc2Vzc2lvbiBzdG9yZSBhbmQgcmVzb2x2ZXMgd2hlbiBhIGxvZ2dlZC1pbiB1c2VyXG4gKiBiZWNvbWVzIGF2YWlsYWJsZS5cbiAqXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSBMb2dnZWRJblVzZXIgb2JqZWN0IG9uY2UgYXZhaWxhYmxlLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgZ2V0TG9nZ2VkSW5Vc2VyIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBjb25zdCB1c2VyID0gYXdhaXQgZ2V0TG9nZ2VkSW5Vc2VyKCk7XG4gKiBjb25zb2xlLmxvZygnTG9nZ2VkIGluIGFzOicsIHVzZXIuZGlzcGxheSk7XG4gKiBgYGBcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VkSW5Vc2VyKCkge1xuICAgIGxldCB1c2VyO1xuICAgIGxldCB1bnN1YnNjcmliZTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlcyk9PntcbiAgICAgICAgY29uc3QgaGFuZGxlciA9IChzdGF0ZSk9PntcbiAgICAgICAgICAgIGlmIChzdGF0ZS5sb2FkZWQgJiYgc3RhdGUuc2Vzc2lvbi51c2VyKSB7XG4gICAgICAgICAgICAgICAgdXNlciA9IHN0YXRlLnNlc3Npb24udXNlcjtcbiAgICAgICAgICAgICAgICByZXMoc3RhdGUuc2Vzc2lvbi51c2VyKTtcbiAgICAgICAgICAgICAgICBpZiAodW5zdWJzY3JpYmUpIHtcbiAgICAgICAgICAgICAgICAgICAgdW5zdWJzY3JpYmUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICAgIGhhbmRsZXIoc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkpO1xuICAgICAgICBpZiAoIXVzZXIpIHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlID0gc2Vzc2lvblN0b3JlLnN1YnNjcmliZShoYW5kbGVyKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGggdGhlIGN1cnJlbnQgc2Vzc2lvbiBsb2NhdGlvbiwgaWYgb25lIGlzIHNldC5cbiAqIFRoZSBzZXNzaW9uIGxvY2F0aW9uIHJlcHJlc2VudHMgdGhlIHBoeXNpY2FsIGxvY2F0aW9uIHdoZXJlIHRoZSB1c2VyIGlzIGN1cnJlbnRseVxuICogd29ya2luZyAoZS5nLiwgYSBjbGluaWMgb3Igd2FyZCkuXG4gKlxuICogQHJldHVybnMgQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aCB0aGUgU2Vzc2lvbkxvY2F0aW9uIG9iamVjdCwgb3IgYHVuZGVmaW5lZGBcbiAqICAgaWYgbm8gc2Vzc2lvbiBsb2NhdGlvbiBpcyBzZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBnZXRTZXNzaW9uTG9jYXRpb24gfSBmcm9tICdAb3Blbm1ycy9lc20tYXBpJztcbiAqIGNvbnN0IGxvY2F0aW9uID0gYXdhaXQgZ2V0U2Vzc2lvbkxvY2F0aW9uKCk7XG4gKiBpZiAobG9jYXRpb24pIHtcbiAqICAgY29uc29sZS5sb2coJ0N1cnJlbnQgbG9jYXRpb246JywgbG9jYXRpb24uZGlzcGxheSk7XG4gKiB9XG4gKiBgYGBcbiAqLyBleHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2Vzc2lvbkxvY2F0aW9uKCkge1xuICAgIGNvbnN0IHNlc3Npb24gPSBhd2FpdCBnZXRDdXJyZW50VXNlcigpO1xuICAgIHJldHVybiBzZXNzaW9uLnNlc3Npb25Mb2NhdGlvbjtcbn1cbi8qKlxuICogU2V0cyB0aGUgc2Vzc2lvbiBsb2NhdGlvbiBmb3IgdGhlIGN1cnJlbnQgdXNlci4gVGhlIHNlc3Npb24gbG9jYXRpb24gcmVwcmVzZW50c1xuICogdGhlIHBoeXNpY2FsIGxvY2F0aW9uIHdoZXJlIHRoZSB1c2VyIGlzIHdvcmtpbmcgKGUuZy4sIGEgY2xpbmljIG9yIHdhcmQpLlxuICogVGhpcyB0cmlnZ2VycyBhIHNlcnZlciByZXF1ZXN0IHRvIHVwZGF0ZSB0aGUgc2Vzc2lvbiBhbmQgcmVmcmVzaGVzIHRoZSBsb2NhbFxuICogc2Vzc2lvbiBzdG9yZS5cbiAqXG4gKiBAcGFyYW0gbG9jYXRpb25VdWlkIFRoZSBVVUlEIG9mIHRoZSBsb2NhdGlvbiB0byBzZXQgYXMgdGhlIHNlc3Npb24gbG9jYXRpb24uXG4gKiBAcGFyYW0gYWJvcnRDb250cm9sbGVyIEFuIEFib3J0Q29udHJvbGxlciB0byBhbGxvdyBjYW5jZWxsYXRpb24gb2YgdGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSB1cGRhdGVkIFNlc3Npb25TdG9yZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogYGBgdHNcbiAqIGltcG9ydCB7IHNldFNlc3Npb25Mb2NhdGlvbiB9IGZyb20gJ0BvcGVubXJzL2VzbS1hcGknO1xuICogY29uc3QgYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICogYXdhaXQgc2V0U2Vzc2lvbkxvY2F0aW9uKCdsb2NhdGlvbi11dWlkLWhlcmUnLCBhYm9ydENvbnRyb2xsZXIpO1xuICogYGBgXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldFNlc3Npb25Mb2NhdGlvbihsb2NhdGlvblV1aWQsIGFib3J0Q29udHJvbGxlcikge1xuICAgIHJldHVybiBoYW5kbGVTZXNzaW9uUmVzcG9uc2Uob3Blbm1yc0ZldGNoKHNlc3Npb25FbmRwb2ludCwge1xuICAgICAgICBtZXRob2Q6ICdQT1NUJyxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgICAgc2Vzc2lvbkxvY2F0aW9uOiBsb2NhdGlvblV1aWRcbiAgICAgICAgfSxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9LFxuICAgICAgICByZWplY3RBdXRoRmFpbHVyZTogdHJ1ZSxcbiAgICAgICAgc2lnbmFsOiBhYm9ydENvbnRyb2xsZXI/LnNpZ25hbFxuICAgIH0pKTtcbn1cbi8qKlxuICogU2V0cyB0aGUgbG9jYWxlIGZvciB0aGUgY3VycmVudCBzZXNzaW9uIG9ubHksIGxlYXZpbmcgdGhlIHVzZXIncyBkZWZhdWx0IGxvY2FsZSB1bmNoYW5nZWQuXG4gKiBVc2Uge0BsaW5rIHNldFVzZXJQcm9wZXJ0aWVzfSB3aXRoIGEgYGRlZmF1bHRMb2NhbGVgIHByb3BlcnR5IHRvIGNoYW5nZSB0aGUgZGVmYXVsdCBpbnN0ZWFkLlxuICpcbiAqIEBwYXJhbSBsb2NhbGUgVGhlIGxvY2FsZSBpbiBKYXZhJ3MgYExvY2FsZSN0b1N0cmluZygpYCBmb3JtLCBlLmcuIGBlbl9HQmAuXG4gKiBAcGFyYW0gYWJvcnRDb250cm9sbGVyIE9wdGlvbmFsIEFib3J0Q29udHJvbGxlciB0byBhbGxvdyBjYW5jZWxsYXRpb24gb2YgdGhlIHJlcXVlc3QuXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSB1cGRhdGVkIFNlc3Npb25TdG9yZSBhZnRlciByZWZldGNoaW5nIHRoZSBjdXJyZW50IHVzZXIuXG4gKiAgIEl0IHJlamVjdHMgd2l0aCBhbiB7QGxpbmsgT3Blbm1yc0ZldGNoRXJyb3J9IGlmIHRoZSBzZXJ2ZXIgZG9lcyBub3QgYWNjZXB0IHRoZSBsb2NhbGUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBzZXRTZXNzaW9uTG9jYWxlIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBhd2FpdCBzZXRTZXNzaW9uTG9jYWxlKCdmcicpO1xuICogYGBgXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNldFNlc3Npb25Mb2NhbGUobG9jYWxlLCBhYm9ydENvbnRyb2xsZXIpIHtcbiAgICBhd2FpdCBvcGVubXJzRmV0Y2goc2Vzc2lvbkVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICBsb2NhbGVcbiAgICAgICAgfSxcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJ1xuICAgICAgICB9LFxuICAgICAgICBzaWduYWw6IGFib3J0Q29udHJvbGxlcj8uc2lnbmFsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlZmV0Y2hDdXJyZW50VXNlcigpO1xufVxuLyoqXG4gKiBVcGRhdGVzIHRoZSB1c2VyIHByb3BlcnRpZXMgZm9yIGEgc3BlY2lmaWMgdXNlci4gVXNlciBwcm9wZXJ0aWVzIGFyZSBrZXktdmFsdWVcbiAqIHBhaXJzIHRoYXQgc3RvcmUgdXNlci1zcGVjaWZpYyBzZXR0aW5ncyBhbmQgcHJlZmVyZW5jZXMuIEFmdGVyIHVwZGF0aW5nIHRoZVxuICogcHJvcGVydGllcyBvbiB0aGUgc2VydmVyLCB0aGUgY3VycmVudCB1c2VyIHNlc3Npb24gaXMgcmVmZXRjaGVkIHRvIHJlZmxlY3RcbiAqIHRoZSBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB1c2VyVXVpZCBUaGUgVVVJRCBvZiB0aGUgdXNlciB3aG9zZSBwcm9wZXJ0aWVzIHNob3VsZCBiZSB1cGRhdGVkLlxuICogQHBhcmFtIHVzZXJQcm9wZXJ0aWVzIEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBwcm9wZXJ0aWVzIHRvIHNldCBvciB1cGRhdGUuXG4gKiBAcGFyYW0gYWJvcnRDb250cm9sbGVyIE9wdGlvbmFsIEFib3J0Q29udHJvbGxlciB0byBhbGxvdyBjYW5jZWxsYXRpb24gb2YgdGhlIHJlcXVlc3QuXG4gKiAgIElmIG5vdCBwcm92aWRlZCwgYSBuZXcgQWJvcnRDb250cm9sbGVyIGlzIGNyZWF0ZWQuXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRoIHRoZSB1cGRhdGVkIFNlc3Npb25TdG9yZSBhZnRlciByZWZldGNoaW5nXG4gKiAgIHRoZSBjdXJyZW50IHVzZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyBnZXRMb2dnZWRJblVzZXIsIHNldFVzZXJQcm9wZXJ0aWVzIH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBjb25zdCB1c2VyID0gYXdhaXQgZ2V0TG9nZ2VkSW5Vc2VyKCk7XG4gKiBhd2FpdCBzZXRVc2VyUHJvcGVydGllcyh1c2VyLnV1aWQsIHtcbiAqICAgZGVmYXVsdExvY2FsZTogJ2VuX0dCJyxcbiAqICAgY3VzdG9tU2V0dGluZzogJ3ZhbHVlJ1xuICogfSk7XG4gKiBgYGBcbiAqLyBleHBvcnQgYXN5bmMgZnVuY3Rpb24gc2V0VXNlclByb3BlcnRpZXModXNlclV1aWQsIHVzZXJQcm9wZXJ0aWVzLCBhYm9ydENvbnRyb2xsZXIpIHtcbiAgICBpZiAoIWFib3J0Q29udHJvbGxlcikge1xuICAgICAgICBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgfVxuICAgIGF3YWl0IG9wZW5tcnNGZXRjaChgJHtyZXN0QmFzZVVybH0vdXNlci8ke3VzZXJVdWlkfWAsIHtcbiAgICAgICAgbWV0aG9kOiAnUE9TVCcsXG4gICAgICAgIGJvZHk6IHtcbiAgICAgICAgICAgIHVzZXJQcm9wZXJ0aWVzXG4gICAgICAgIH0sXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbidcbiAgICAgICAgfSxcbiAgICAgICAgc2lnbmFsOiBhYm9ydENvbnRyb2xsZXIuc2lnbmFsXG4gICAgfSk7XG4gICAgcmV0dXJuIHJlZmV0Y2hDdXJyZW50VXNlcigpO1xufVxuLyoqXG4gKiBTdWJtaXRzIGEgVE9UUCBjb2RlIHRvIGNvbXBsZXRlIGEgdHdvLWZhY3RvciBsb2dpbiBjaGFsbGVuZ2UuIFdoZW4gdGhlIGNvZGUgaXMgYWNjZXB0ZWQsIHRoZVxuICogc2Vzc2lvbiBzdG9yZSBpcyByZWZyZXNoZWQgd2l0aCB0aGUgbm93LWF1dGhlbnRpY2F0ZWQgc2Vzc2lvbi5cbiAqXG4gKiBAcGFyYW0gY29kZSBUaGUgY29kZSBmcm9tIHRoZSB1c2VyJ3MgYXV0aGVudGljYXRvciBhcHAuXG4gKiBAcGFyYW0gcmVtZW1iZXJEZXZpY2UgV2hldGhlciB0aGUgc2VydmVyIHNob3VsZCBza2lwIHRoZSBjaGFsbGVuZ2Ugb24gdGhpcyBkZXZpY2UgaW4gZnV0dXJlLlxuICogQHJldHVybnMgQSBQcm9taXNlIHJlc29sdmluZyB0byB0aGUgc2Vzc2lvbi4gSXRzIGBhdXRoZW50aWNhdGVkYCBwcm9wZXJ0eSBpcyBgZmFsc2VgIGlmIHRoZVxuICogICBjb2RlIHdhcyBub3QgYWNjZXB0ZWQuIEl0IHJlamVjdHMgd2l0aCBhbiB7QGxpbmsgT3Blbm1yc0ZldGNoRXJyb3J9IGlmIHRoZSBzZXJ2ZXIgcmVqZWN0cyB0aGVcbiAqICAgcmVxdWVzdCwgaW4gd2hpY2ggY2FzZSBgcmVzcG9uc2VCb2R5YCBtYXkgZXhwbGFpbiB3aHkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHRzXG4gKiBpbXBvcnQgeyB2ZXJpZnlUb3RwQ29kZSB9IGZyb20gJ0BvcGVubXJzL2VzbS1hcGknO1xuICogY29uc3Qgc2Vzc2lvbiA9IGF3YWl0IHZlcmlmeVRvdHBDb2RlKCcxMjM0NTYnLCB0cnVlKTtcbiAqIGBgYFxuICpcbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBhc3luYyBmdW5jdGlvbiB2ZXJpZnlUb3RwQ29kZShjb2RlLCByZW1lbWJlckRldmljZSA9IGZhbHNlKSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBvcGVubXJzRmV0Y2gocmVtZW1iZXJEZXZpY2UgPyBgJHtzZXNzaW9uRW5kcG9pbnR9P3JlbWVtYmVyTWU9dHJ1ZWAgOiBzZXNzaW9uRW5kcG9pbnQsIHtcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgJ1gtVG90cC1Db2RlJzogY29kZVxuICAgICAgICB9XG4gICAgfSk7XG4gICAgaWYgKHJlc3BvbnNlLmRhdGE/LmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgICAgLy8gYHJlZmV0Y2hDdXJyZW50VXNlcmAgb25seSByZXNvbHZlcyBvbmNlIHRoZSBzdG9yZSBob2xkcyBhIHNlc3Npb24uXG4gICAgICAgIGNvbnN0IHN0b3JlID0gYXdhaXQgcmVmZXRjaEN1cnJlbnRVc2VyKCk7XG4gICAgICAgIHJldHVybiBzdG9yZS5zZXNzaW9uO1xuICAgIH1cbiAgICByZXR1cm4gcmVzcG9uc2UuZGF0YTtcbn1cbi8qKlxuICogRW5kcyB0aGUgY3VycmVudCBzZXNzaW9uIG9uIHRoZSBzZXJ2ZXIgYW5kIHJlY29yZHMgYSBsb2dnZWQtb3V0IHNlc3Npb24gaW4gdGhlIHNlc3Npb24gc3RvcmUuXG4gKiBBIHNlcnZlciB0aGF0IGhhcyBhbHJlYWR5IGVuZGVkIHRoZSBzZXNzaW9uICg0MDEgb3IgNDAzKSBjb3VudHMgYXMgYSBzdWNjZXNzZnVsIGxvZ291dC5cbiAqXG4gKiBPdGhlciBkYXRhIGNhY2hlZCBmb3IgdGhlIGxvZ2dlZC1pbiB1c2VyLCBzdWNoIGFzIFNXUiBjYWNoZXMsIGlzIHRoZSBjYWxsZXIncyB0byBjbGVhci5cbiAqXG4gKiBAcmV0dXJucyBBIFByb21pc2UgdGhhdCByZXNvbHZlcyBvbmNlIHRoZSBzZXNzaW9uIHN0b3JlIGhvbGRzIGEgbG9nZ2VkLW91dCBzZXNzaW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgbG9nb3V0IH0gZnJvbSAnQG9wZW5tcnMvZXNtLWFwaSc7XG4gKiBhd2FpdCBsb2dvdXQoKTtcbiAqIGBgYFxuICpcbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBhc3luYyBmdW5jdGlvbiBsb2dvdXQoKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgb3Blbm1yc0ZldGNoKHNlc3Npb25FbmRwb2ludCwge1xuICAgICAgICAgICAgbWV0aG9kOiAnREVMRVRFJyxcbiAgICAgICAgICAgIHJlamVjdEF1dGhGYWlsdXJlOiB0cnVlXG4gICAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoIWlzQXV0aEZhaWx1cmUoZXJyKSkge1xuICAgICAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgICB9XG4gICAgfVxuICAgIGNsZWFyQ3VycmVudFVzZXIoKTtcbiAgICAvLyBUaGUgc2Vzc2lvbiBqdXN0IGNsZWFyZWQgaXMgYWxyZWFkeSBjb3JyZWN0LCBzbyBhIGZhaWxlZCByZWZyZXNoIGxvc2VzIG5vdGhpbmcuXG4gICAgYXdhaXQgcmVmZXRjaEN1cnJlbnRVc2VyKCkuY2F0Y2goKCk9Pnt9KTtcbn1cbmZ1bmN0aW9uIGhhbmRsZVNlc3Npb25SZXNwb25zZShyZXN1bHQpIHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCk9PntcbiAgICAgICAgcmVzdWx0LnRoZW4oKHJlcyk9PntcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmVzPy5kYXRhID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5leHRTdGF0ZSA9IHtcbiAgICAgICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBzZXNzaW9uOiByZXMuZGF0YVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JlLnNldFN0YXRlKG5leHRTdGF0ZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZShuZXh0U3RhdGUpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpc0luaXRpYWxTZXR1cFJlZGlyZWN0KHJlcykpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVjb3JkU2Vzc2lvbkZhaWx1cmUoRXJyb3IoJ1RoZSBzZXJ2ZXIgaXMgc3RpbGwgc3RhcnRpbmcgdXAnKSwgdHJ1ZSkpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVjb3JkU2Vzc2lvbkZhaWx1cmUoRXJyb3IoJ1RoZSBzZXNzaW9uIGVuZHBvaW50IGRpZCBub3QgcmVzcG9uZCB3aXRoIGEgc2Vzc2lvbicpKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pLmNhdGNoKChlcnIpPT57XG4gICAgICAgICAgICAvLyBBbiBhdXRoIGZhaWx1cmUgaXMgdGhlIHNlc3Npb24gZW5kcG9pbnQncyBhbnN3ZXIgZm9yIFwibm90IGxvZ2dlZCBpblwiLCBub3QgYSBmYWlsZWQgbG9va3VwLlxuICAgICAgICAgICAgaWYgKGlzQXV0aEZhaWx1cmUoZXJyKSkge1xuICAgICAgICAgICAgICAgIGlmIChpc1VuYXV0aGVudGljYXRlZFNlc3Npb24oZXJyLnJlc3BvbnNlQm9keSkpIHtcbiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvYWRlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb246IGVyci5yZXNwb25zZUJvZHlcbiAgICAgICAgICAgICAgICAgICAgfSwgdHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY2xlYXJDdXJyZW50VXNlcigpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXNvbHZlKHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoaXNHYXRld2F5RXJyb3JEdXJpbmdTdGFydHVwKGVycikpIHtcbiAgICAgICAgICAgICAgICByZWplY3QocmVjb3JkU2Vzc2lvbkZhaWx1cmUoZXJyLCB0cnVlKSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmVwb3J0RXJyb3IoYEZhaWxlZCB0byBmZXRjaCBuZXcgc2Vzc2lvbiBpbmZvcm1hdGlvbjogJHtlcnJ9YCk7XG4gICAgICAgICAgICByZWplY3QocmVjb3JkU2Vzc2lvbkZhaWx1cmUoZXJyKSk7XG4gICAgICAgIH0pO1xuICAgIH0pO1xufVxuZnVuY3Rpb24gaXNBdXRoRmFpbHVyZShlcnIpIHtcbiAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgT3Blbm1yc0ZldGNoRXJyb3IgJiYgKGVyci5yZXNwb25zZS5zdGF0dXMgPT09IDQwMSB8fCBlcnIucmVzcG9uc2Uuc3RhdHVzID09PSA0MDMpO1xufVxuLyoqXG4gKiBVbnRpbCB0aGUgYmFja2VuZCBoYXMgZmluaXNoZWQgaXRzIGluaXRpYWwgc2V0dXAsIGl0IGFuc3dlcnMgZXZlcnkgcmVxdWVzdCB3aXRoIGEgcmVkaXJlY3QgdG8gaXRzXG4gKiBzZXR1cCBwYWdlLCB3aGljaCBgZmV0Y2goKWAgZm9sbG93cywgc28gdGhlIHNlc3Npb24gcmVxdWVzdCByZXNvbHZlcyB3aXRoIHRoYXQgcGFnZSdzIEhUTUwuXG4gKi8gZnVuY3Rpb24gaXNJbml0aWFsU2V0dXBSZWRpcmVjdChyZXMpIHtcbiAgICBpZiAoIXJlcz8ucmVkaXJlY3RlZCB8fCAhcmVzLnVybCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBuZXcgVVJMKHJlcy51cmwsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKS5wYXRobmFtZS5yZXBsYWNlKC9cXC8rJC8sICcnKS5lbmRzV2l0aCgnL2luaXRpYWxzZXR1cCcpO1xuICAgIH0gY2F0Y2ggIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGlzR2F0ZXdheUVycm9yRHVyaW5nU3RhcnR1cChlcnIpIHtcbiAgICByZXR1cm4gZXJyIGluc3RhbmNlb2YgT3Blbm1yc0ZldGNoRXJyb3IgJiYgZXJyLnJlc3BvbnNlLnN0YXR1cyA9PT0gNTAyICYmICFzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKS5sb2FkZWQgJiYgZmlyc3RGZXRjaFRpbWVNaWxsaXMgIT09IHVuZGVmaW5lZCAmJiBEYXRlLm5vdygpIC0gZmlyc3RGZXRjaFRpbWVNaWxsaXMgPCBzdGFydHVwR3JhY2VQZXJpb2RNaWxsaXM7XG59XG5mdW5jdGlvbiBpc1VuYXV0aGVudGljYXRlZFNlc3Npb24oYm9keSkge1xuICAgIHJldHVybiB0eXBlb2YgYm9keSA9PT0gJ29iamVjdCcgJiYgYm9keSAhPT0gbnVsbCAmJiBib2R5LmF1dGhlbnRpY2F0ZWQgPT09IGZhbHNlO1xufVxuLyoqXG4gKiBBIHNlc3Npb24gdGhhdCBoYXMgYWxyZWFkeSBsb2FkZWQgaXMga2VwdCB3aGVuIGEgbGF0ZXIgZmV0Y2ggZmFpbHMsIHNpbmNlIGl0IGlzIHN0aWxsIHRoZSBiZXN0IGFuc3dlclxuICogYXZhaWxhYmxlLiBXaXRoIG5vdGhpbmcgdG8gZmFsbCBiYWNrIG9uLCB0aGUgZXJyb3IgaXMgcmVjb3JkZWQgc28gdGhlIGFwcCBzaGVsbCBjYW4gc2hvdyBhbiBlcnJvciBwYWdlLlxuICovIGZ1bmN0aW9uIHJlY29yZFNlc3Npb25GYWlsdXJlKGVyciwgaW5pdGlhbGl6aW5nID0gZmFsc2UpIHtcbiAgICBpZiAoIXNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLmxvYWRlZCkge1xuICAgICAgICBzZXNzaW9uU3RvcmUuc2V0U3RhdGUoe1xuICAgICAgICAgICAgbG9hZGVkOiBmYWxzZSxcbiAgICAgICAgICAgIHNlc3Npb246IG51bGwsXG4gICAgICAgICAgICBlcnJvcjogZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIgOiBFcnJvcihTdHJpbmcoZXJyKSksXG4gICAgICAgICAgICBpbml0aWFsaXppbmdcbiAgICAgICAgfSwgdHJ1ZSk7XG4gICAgfVxuICAgIHJldHVybiBzZXNzaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbn1cbiJdLCJuYW1lcyI6WyJyZXBvcnRFcnJvciIsImNyZWF0ZUdsb2JhbFN0b3JlIiwiaXNVbmRlZmluZWQiLCJPcGVubXJzRmV0Y2hFcnJvciIsIm9wZW5tcnNGZXRjaCIsInJlc3RCYXNlVXJsIiwic2Vzc2lvbkVuZHBvaW50Iiwic2Vzc2lvblN0b3JlIiwic2Vzc2lvbk1heEFnZU1pbGxpcyIsImxhc3RGZXRjaFRpbWVNaWxsaXMiLCJzdGFydHVwR3JhY2VQZXJpb2RNaWxsaXMiLCJmaXJzdEZldGNoVGltZU1pbGxpcyIsImluRmxpZ2h0UmVmcmVzaCIsInJlZnJlc2hTZXNzaW9uSWZTdGFsZSIsIkRhdGUiLCJyZWZldGNoQ3VycmVudFVzZXIiLCJnZXRDdXJyZW50VXNlciIsIm9wdHMiLCJpbmNsdWRlQXV0aFN0YXR1cyIsInNlbGVjdCIsInNlc3Npb24iLCJyZWZyZXNoIiwiUHJvbWlzZSIsInJlc29sdmUiLCJyZXNvbHZlSWZMb2FkZWQiLCJzdGF0ZSIsInVuc3Vic2NyaWJlIiwiZ2V0U2Vzc2lvblN0b3JlIiwiaXNWYWxpZExvY2FsZSIsImxvY2FsZSIsInVuZGVmaW5lZCIsIkludGwiLCJlIiwic2V0VXNlckxhbmd1YWdlIiwiZGF0YSIsImRvY3VtZW50IiwidXNlckhhc1ByaXZpbGVnZSIsInJlcXVpcmVkUHJpdmlsZWdlIiwidXNlciIsInAiLCJBcnJheSIsInJwIiwiY29uc29sZSIsImlzU3VwZXJVc2VyIiwicm9sZSIsInVzZXJuYW1lIiwicGFzc3dvcmQiLCJoZWFkZXJzIiwid2luZG93IiwiaGFuZGxlU2Vzc2lvblJlc3BvbnNlIiwiY2xlYXIiLCJjbGVhckN1cnJlbnRVc2VyIiwidXNlckhhc0FjY2VzcyIsIkJvb2xlYW4iLCJnZXRMb2dnZWRJblVzZXIiLCJyZXMiLCJoYW5kbGVyIiwiZ2V0U2Vzc2lvbkxvY2F0aW9uIiwic2V0U2Vzc2lvbkxvY2F0aW9uIiwibG9jYXRpb25VdWlkIiwiYWJvcnRDb250cm9sbGVyIiwic2V0U2Vzc2lvbkxvY2FsZSIsInNldFVzZXJQcm9wZXJ0aWVzIiwidXNlclV1aWQiLCJ1c2VyUHJvcGVydGllcyIsIkFib3J0Q29udHJvbGxlciIsInZlcmlmeVRvdHBDb2RlIiwiY29kZSIsInJlbWVtYmVyRGV2aWNlIiwicmVzcG9uc2UiLCJzdG9yZSIsImxvZ291dCIsImVyciIsImlzQXV0aEZhaWx1cmUiLCJyZXN1bHQiLCJyZWplY3QiLCJuZXh0U3RhdGUiLCJpc0luaXRpYWxTZXR1cFJlZGlyZWN0IiwicmVjb3JkU2Vzc2lvbkZhaWx1cmUiLCJFcnJvciIsImlzVW5hdXRoZW50aWNhdGVkU2Vzc2lvbiIsImlzR2F0ZXdheUVycm9yRHVyaW5nU3RhcnR1cCIsIlVSTCIsImJvZHkiLCJpbml0aWFsaXppbmciLCJTdHJpbmciXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLDBCQUEwQixHQUE2RDtBQUNoQztBQUNmO0FBQzJEO0FBQ25HLGNBQWMsR0FBVSxNQUFNTyxlQUFlTix5REFBaUJBLENBQUMsV0FBVztJQUN0RSxRQUFRO0lBQ1IsU0FBUztBQUNiLEdBQUc7QUFDSDs7OztDQUlDLEdBQUcsTUFBTU8sc0JBQXNCLEtBQUs7QUFDckMsSUFBSUMsc0JBQXNCO0FBQzFCOzs7Q0FHQyxHQUFHLE1BQU1DLDJCQUEyQixJQUFJLEtBQUs7QUFDOUMsSUFBSUM7QUFDSixJQUFJQyxrQkFBa0I7QUFDdEI7Ozs7Ozs7Ozs7O0NBV0MsR0FBRyxTQUFTQztJQUNULElBQUlELGlCQUFpQjtRQUNqQixPQUFPQTtJQUNYO0lBQ0EsSUFBSUwsYUFBYSxRQUFRLEdBQUcsTUFBTSxJQUFJRSx1QkFBdUJLLEtBQUssR0FBRyxLQUFLTixxQkFBcUI7UUFDM0YsT0FBTztJQUNYO0lBQ0EsT0FBT087QUFDWDtBQUNBLFNBQVNDLGVBQWVDLElBQUk7SUFDeEIsTUFBTUMsb0JBQW9CRCxNQUFNLHFCQUFxQjtJQUNyRCxNQUFNRSxTQUFTLENBQUNDLFVBQVVGLG9CQUFvQkUsVUFBVUEsUUFBUSxJQUFJO0lBQ3BFLE1BQU1DLFVBQVVSO0lBQ2hCLElBQUksQ0FBQ1EsU0FBUztRQUNWLE9BQU9DLFFBQVEsT0FBTyxDQUFDSCxPQUFPWixhQUFhLFFBQVEsR0FBRyxPQUFPO0lBQ2pFO0lBQ0EsT0FB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\n//# sourceURL=webpack-internal:///../../framework/esm-api/dist/current-user.js\n\n}");
4460
4460
 
4461
4461
  },
4462
4462
  "../../framework/esm-api/dist/environment.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -4521,7 +4521,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
4521
4521
  },
4522
4522
  "../../framework/esm-config/dist/module-config/module-config.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
4523
4523
  "use strict";
4524
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n clearConfigErrors: () => (clearConfigErrors),\n defineConfigSchema: () => (defineConfigSchema),\n defineExtensionConfigSchema: () => (defineExtensionConfigSchema),\n getConfig: () => (getConfig),\n getTranslationOverrides: () => (getTranslationOverrides),\n processConfig: () => (processConfig),\n provide: () => (provide),\n registerModuleLoad: () => (registerModuleLoad),\n registerModuleWithConfigSystem: () => (registerModuleWithConfigSystem),\n registerTranslationNamespace: () => (registerTranslationNamespace),\n resetConfigSystem: () => (resetConfigSystem)\n});\n/* import */ var lodash_es__rspack_import_4 = __webpack_require__(\"../../../node_modules/lodash-es/mergeWith.js\");\n/* import */ var lodash_es__rspack_import_5 = __webpack_require__(\"../../../node_modules/lodash-es/isEqual.js\");\n/* import */ var lodash_es__rspack_import_6 = __webpack_require__(\"../../../node_modules/lodash-es/omit.js\");\n/* import */ var lodash_es__rspack_import_7 = __webpack_require__(\"../../../node_modules/lodash-es/cloneDeep.js\");\n/* import */ var _types_js__rspack_import_0 = __webpack_require__(\"../../framework/esm-config/dist/types.js\");\n/* import */ var _validators_type_validators_js__rspack_import_1 = __webpack_require__(\"../../framework/esm-config/dist/validators/type-validators.js\");\n/* import */ var _validators_validator_js__rspack_import_2 = __webpack_require__(\"../../framework/esm-config/dist/validators/validator.js\");\n/* import */ var _state_js__rspack_import_3 = __webpack_require__(\"../../framework/esm-config/dist/module-config/state.js\");\n/** @module @category Config */ \n\n\n\n\n/**\n * Deep merge two objects, with right-side values taking precedence.\n * Arrays are replaced entirely (not merged by index), matching the\n * behavior of ramda's mergeDeepRight.\n */ function replaceArrays(_objValue, srcValue) {\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n}\nfunction mergeDeepReplace(left, right) {\n return (0,lodash_es__rspack_import_4[\"default\"])({}, left, right, replaceArrays);\n}\n/**\n * Store setup\n *\n *\n * Set up stores and subscriptions so that inputs get processed appropriately.\n *\n * There are *input* stores and *output* stores. The *input* stores\n * are configInternalStore, temporaryConfigStore, and configExtensionStore. The\n * output stores are set in the `compute...` functions. They are the module\n * config stores, the extension slot config stores (by module), the extension\n * config stores, and the implementer tools config store.\n *\n * This code sets up the subscriptions so that when an input store changes,\n * the correct set of output stores are updated.\n *\n * All `compute...` functions except `computeExtensionConfigs` are pure\n * (or are supposed to be), other than the fact that they all `setState`\n * store values at the end. `computeExtensionConfigs` calls `getGlobalStore`,\n * which creates stores.\n */ // Store unsubscribe functions to allow cleanup (e.g., in tests or hot module reloading)\nconst configSubscriptions = [];\n/**\n * Recomputes all configuration derived stores based on current state of input stores.\n * Called whenever any input store (configInternalStore, temporaryConfigStore, configExtensionStore) changes.\n */ function recomputeAllConfigs() {\n const configState = _state_js__rspack_import_3.configInternalStore.getState();\n const tempConfigState = _state_js__rspack_import_3.temporaryConfigStore.getState();\n const extensionState = _state_js__rspack_import_3.configExtensionStore.getState();\n computeModuleConfig(configState, tempConfigState);\n const slotConfigs = getExtensionSlotConfigs(configState, tempConfigState);\n computeExtensionSlotConfigs(slotConfigs);\n computeExtensionConfigs(configState, extensionState, tempConfigState, slotConfigs);\n // Last, because a failure here must not skip the outputs above. Only kept current while the\n // implementer tools are watching it; otherwise derived on read.\n (0,_state_js__rspack_import_3.invalidateImplementerToolsConfig)();\n}\nfunction setupConfigSubscriptions() {\n // Registered here rather than at module load so that `resetConfigSystem` restores it.\n (0,_state_js__rspack_import_3.setImplementerToolsConfigRecomputer)(()=>computeImplementerToolsConfig(_state_js__rspack_import_3.configInternalStore.getState(), _state_js__rspack_import_3.temporaryConfigStore.getState()));\n // Initial computation\n recomputeAllConfigs();\n // Subscribe to all input stores with a single handler\n // This ensures we only recompute once even if multiple stores change simultaneously\n configSubscriptions.push(_state_js__rspack_import_3.configInternalStore.subscribe(recomputeAllConfigsSafely), _state_js__rspack_import_3.temporaryConfigStore.subscribe(recomputeAllConfigsSafely), _state_js__rspack_import_3.configExtensionStore.subscribe(recomputeAllConfigsSafely));\n}\n/** Ensure that we do not throw during a store subscription */ function recomputeAllConfigsSafely() {\n (0,_state_js__rspack_import_3.clearConfigDerivationError)();\n try {\n recomputeAllConfigs();\n } catch (e) {\n (0,_state_js__rspack_import_3.recordConfigDerivationError)(e);\n console.error('Failed to recompute the configuration', e);\n }\n}\n// Set up subscriptions at module load time\nsetupConfigSubscriptions();\nconst moduleConfigCache = new Map();\nfunction computeModuleConfig(state, tempState) {\n for (let moduleName of Object.keys(state.schemas)){\n // At this point the schema could be either just the implicit schema or the actually\n // defined schema. We run with just the implicit schema because we want to populate\n // the config store with the translation overrides as soon as possible. In fact, the\n // translation system will throw for Suspense until the translation overrides are\n // available, which as of this writing blocks the schema definition from occurring\n // for modules loaded based on their extensions.\n const moduleStore = (0,_state_js__rspack_import_3.getConfigStore)(moduleName);\n const schema = state.schemas[moduleName];\n const moduleLoaded = Boolean(state.moduleLoaded[moduleName]);\n const cached = moduleConfigCache.get(moduleName);\n let newState;\n if (cached && cached.schema === schema && cached.moduleLoaded === moduleLoaded && cached.providedConfigs === state.providedConfigs && cached.temporaryConfig === tempState.config) {\n newState = cached.state;\n } else {\n const config = moduleLoaded ? getConfigForModule(moduleName, state, tempState) : getConfigForModuleImplicitSchema(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: moduleLoaded,\n config\n };\n moduleConfigCache.set(moduleName, {\n schema,\n moduleLoaded,\n providedConfigs: state.providedConfigs,\n temporaryConfig: tempState.config,\n state: newState\n });\n }\n // Writing unconditionally would hand every `useConfig` consumer in the application a new\n // object — and a re-render — whenever any module or extension anywhere is loaded.\n const oldState = moduleStore.getState();\n if (oldState.loaded !== newState.loaded || oldState.translationOverridesLoaded !== newState.translationOverridesLoaded || !(0,lodash_es__rspack_import_5[\"default\"])(oldState.config, newState.config)) {\n moduleStore.setState(newState);\n }\n }\n}\nfunction computeExtensionSlotConfigs(slotConfigs) {\n const slotStore = (0,_state_js__rspack_import_3.getExtensionSlotsConfigStore)();\n const oldSlots = slotStore.getState().slots;\n const slots = {};\n let changed = false;\n for (const [slotName, config] of Object.entries(slotConfigs)){\n const previous = oldSlots[slotName];\n // Entries keep their identity when the configuration behind them hasn't changed, so that\n // changing one slot's configuration doesn't invalidate every other configured slot.\n if (previous?.loaded && (0,lodash_es__rspack_import_5[\"default\"])(previous.config, config)) {\n slots[slotName] = previous;\n } else {\n slots[slotName] = {\n loaded: true,\n config\n };\n changed = true;\n }\n }\n // Built from scratch rather than merged over the previous state: a slot whose configuration\n // has been removed — clearing the temporary config, say — has to lose its entry, or the old\n // configuration stays in force until the page is reloaded.\n if (changed || Object.keys(oldSlots).length !== Object.keys(slots).length) {\n slotStore.setState({\n slots\n });\n }\n}\nfunction computeImplementerToolsConfig(state, tempConfigState) {\n const oldState = _state_js__rspack_import_3.implementerToolsConfigStore.getState();\n const config = getImplementerToolsConfig(state, tempConfigState);\n const newState = {\n config\n };\n // Use deep equality on the actual config content, not the wrapper object\n if (!(0,lodash_es__rspack_import_5[\"default\"])(oldState.config, newState.config)) {\n _state_js__rspack_import_3.implementerToolsConfigStore.setState(newState);\n }\n}\nfunction computeExtensionConfigs(configState, extensionState, tempConfigState, slotConfigs) {\n const extensionsConfigStore = (0,_state_js__rspack_import_3.getExtensionsConfigStore)();\n const oldConfigs = extensionsConfigStore.getState().configs;\n const configs = {};\n let changed = false;\n let entryCount = 0;\n // We assume that the module schema has already been defined, since the extension\n // it contains is mounted.\n for (let extension of extensionState.mountedExtensions){\n const config = computeExtensionConfig(extension.slotModuleName, extension.extensionModuleName, extension.slotName, extension.extensionId, configState, tempConfigState, slotConfigs[extension.slotName]);\n const previous = oldConfigs[extension.slotName]?.[extension.extensionId];\n // Entries keep their identity when the configuration behind them hasn't changed, so that\n // mounting one extension doesn't hand every other mounted extension a new config object.\n const entry = previous?.loaded && (0,lodash_es__rspack_import_5[\"default\"])(previous.config, config) ? previous : {\n config,\n loaded: true\n };\n if (entry !== previous) {\n changed = true;\n }\n if (!configs[extension.slotName]) {\n configs[extension.slotName] = {};\n }\n configs[extension.slotName][extension.extensionId] = entry;\n entryCount++;\n }\n // Slots keep their identity too when none of their entries changed. Subscribers compare these\n // per-slot objects to work out which slots to re-derive, so handing out a fresh one for every\n // slot on every write would mark every slot with a mounted extension dirty.\n for (const [slotName, slotConfigs] of Object.entries(configs)){\n const previousSlot = oldConfigs[slotName];\n if (previousSlot && Object.keys(previousSlot).length === Object.keys(slotConfigs).length && Object.entries(slotConfigs).every(([extensionId, entry])=>previousSlot[extensionId] === entry)) {\n configs[slotName] = previousSlot;\n }\n }\n if (!changed) {\n // Nothing was added or altered, but an extension may have unmounted, which only shows up as a\n // missing entry.\n changed = Object.keys(oldConfigs).length !== Object.keys(configs).length || Object.values(oldConfigs).reduce((total, slot)=>total + Object.keys(slot).length, 0) !== entryCount;\n }\n if (changed) {\n extensionsConfigStore.setState({\n configs\n });\n }\n}\n/*\n * API\n *\n */ /**\n * This defines a configuration schema for a module. The schema tells the\n * configuration system how the module can be configured. It specifies\n * what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/en-US/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param moduleName Name of the module the schema is being defined for. Generally\n * should be the one in which the `defineConfigSchema` call takes place.\n * @param schema The config schema for the module\n */ function defineConfigSchema(moduleName, schema) {\n validateConfigSchema(moduleName, schema);\n const enhancedSchema = mergeDeepReplace(schema, implicitConfigSchema);\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: enhancedSchema\n },\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This alerts the configuration system that a module exists. This allows config to be\n * processed, while still allowing the extension system to know whether the module has\n * actually had its front bundle executed yet.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleWithConfigSystem(moduleName) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: implicitConfigSchema\n }\n }));\n}\n/**\n * This alerts the configuration system that a module has been loaded.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleLoad(moduleName) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This allows the config system to support translation overrides for namespaces that\n * do not correspond to modules.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param namespace\n */ function registerTranslationNamespace(namespace) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [namespace]: translationOverridesSchema\n }\n }));\n}\n/**\n * This defines a configuration schema for an extension. When a schema is defined\n * for an extension, that extension will receive the configuration corresponding\n * to that schema, rather than the configuration corresponding to the module\n * in which it is defined.\n *\n * The schema tells the configuration system how the module can be configured.\n * It specifies what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/en-US/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param extensionName Name of the extension the schema is being defined for.\n * Should match the `name` of one of the `extensions` entries defined in\n * the app's `routes.json` file.\n * @param schema The config schema for the extension\n */ function defineExtensionConfigSchema(extensionName, schema) {\n validateConfigSchema(extensionName, schema);\n const enhancedSchema = mergeDeepReplace(schema, implicitConfigSchema);\n const state = _state_js__rspack_import_3.configInternalStore.getState();\n if (state.schemas[extensionName]) {\n console.error(`Config schema for extension ${extensionName} already exists. If there are multiple extensions with this same name, one will probably crash.`);\n }\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [extensionName]: enhancedSchema\n }\n }));\n}\n/**\n * Provides configuration values programmatically. This is an alternative to\n * providing configuration through the config-file. Configuration provided this\n * way will be merged with configuration from other sources.\n *\n * @param config A configuration object to merge into the existing configuration.\n * @param sourceName An optional name to identify the source of this configuration,\n * used for debugging purposes. Defaults to 'provided'.\n */ function provide(config, sourceName = 'provided') {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n providedConfigs: [\n ...state.providedConfigs,\n {\n source: sourceName,\n config\n }\n ]\n }));\n}\n/**\n * Resolves with `select(state)` as soon as the store's state satisfies `ready`, leaving no\n * subscription behind: nothing subscribes at all when the store is already ready. That matters\n * because `getConfig` runs on every HTTP request, and a subscription that outlives its promise\n * both retains its closure forever and slows down every later write to that store.\n */ function whenStoreReady(store, ready, select) {\n return new Promise((resolve)=>{\n let unsubscribe;\n let resolved = false;\n function update(state) {\n if (!resolved && ready(state)) {\n resolved = true;\n resolve(select(state));\n unsubscribe?.();\n }\n }\n update(store.getState());\n if (!resolved) {\n unsubscribe = store.subscribe(update);\n }\n });\n}\n/**\n * A promise-based way to access the config as soon as it is fully loaded.\n * If it is already loaded, resolves the config in its present state.\n *\n * This is a useful function if you need to get the config in the course\n * of the execution of a function.\n *\n * @param moduleName The name of the module for which to look up the config\n */ function getConfig(moduleName) {\n return whenStoreReady((0,_state_js__rspack_import_3.getConfigStore)(moduleName), (state)=>Boolean(state.loaded && state.config), (state)=>(0,lodash_es__rspack_import_6[\"default\"])(state.config, [\n 'Display conditions',\n 'Translation overrides'\n ]));\n}\n/**\n * Retrieves translation overrides for an extension, optionally scoped to a specific\n * extension slot. When called with only a module name, retrieves module-level overrides.\n * Translation overrides allow customizing translated strings without modifying the\n * original translation files.\n *\n * @param moduleName The name of the module providing the translation context.\n * @param slotName Optional extension slot name to include slot-specific overrides.\n * @param extensionId Optional extension ID to include extension-specific overrides.\n * @returns A Promise resolving to an array of translation override objects.\n *\n * @internal\n */ function getTranslationOverrides(moduleName, slotName, extensionId) {\n const promises = [\n whenStoreReady((0,_state_js__rspack_import_3.getConfigStore)(moduleName), (state)=>Boolean(state.translationOverridesLoaded && state.config), (state)=>state.config['Translation overrides'] ?? {})\n ];\n if (slotName && extensionId) {\n promises.push(whenStoreReady((0,_state_js__rspack_import_3.getExtensionConfig)(slotName, extensionId), (state)=>Boolean(state.loaded && state.config), (state)=>state.config['Translation overrides'] ?? {}));\n }\n return Promise.all(promises);\n}\n/**\n * Validate and interpolate defaults for `providedConfig` according to `schema`\n *\n * @param schema a configuration schema\n * @param providedConfig an object of config values (without the top-level module name)\n * @param keyPathContext a dot-separated string which helps the user figure out where\n * the provided config came from\n * @returns The validated and processed configuration object with defaults applied.\n * @internal\n */ function processConfig(schema, providedConfig, keyPathContext) {\n validateStructure(schema, providedConfig, keyPathContext);\n const config = setDefaults(schema, providedConfig);\n runAllValidatorsInConfigTree(schema, config, keyPathContext);\n return config;\n}\nconst extensionConfigCache = new Map();\n/**\n * Returns the configuration for an extension. This configuration is specific\n * to the slot in which it is mounted, and its ID within that slot.\n *\n * The schema for that configuration is the extension schema. If no extension\n * schema has been provided, the schema used is the schema of the module in\n * which the extension is defined.\n *\n * @param slotModuleName The name of the module which defines the extension slot\n * @param extensionModuleName The name of the module which defines the extension (and therefore the config schema)\n * @param slotName The name of the extension slot where the extension is mounted\n * @param extensionId The ID of the extension in its slot\n * @param slotConfig The slot's configuration, gathered from every module that configures it\n */ function computeExtensionConfig(slotModuleName, extensionModuleName, slotName, extensionId, configState, tempConfigState, slotConfig) {\n const extensionName = getExtensionNameFromId(extensionId);\n const extensionConfigSchema = configState.schemas[extensionName];\n // JSON string of these elements should be unique-per-extension\n const cacheKey = JSON.stringify([\n slotName,\n extensionId,\n slotModuleName,\n extensionModuleName\n ]);\n const cached = extensionConfigCache.get(cacheKey);\n if (cached && cached.extensionSchema === extensionConfigSchema && cached.extensionModuleSchema === configState.schemas[extensionModuleName] && cached.providedConfigs === configState.providedConfigs && cached.temporaryConfig === tempConfigState.config) {\n return cached.config;\n }\n const nameOfSchemaSource = extensionConfigSchema ? extensionName : extensionModuleName;\n const providedConfigs = getProvidedConfigs(configState, tempConfigState);\n const sharedOverride = slotConfig?.configure?.[extensionId] ?? {};\n const slotModuleConfig = mergeConfigsFor(slotModuleName, providedConfigs);\n const configOverride = slotModuleConfig?.extensionSlots?.[slotName]?.configure?.[extensionId] ?? {};\n const extensionConfig = mergeConfigsFor(nameOfSchemaSource, providedConfigs);\n const combinedConfig = mergeConfigs([\n extensionConfig,\n sharedOverride,\n configOverride\n ]);\n const schema = extensionConfigSchema ?? configState.schemas[extensionModuleName];\n validateStructure(schema, combinedConfig, nameOfSchemaSource);\n const config = setDefaults(schema, combinedConfig);\n runAllValidatorsInConfigTree(schema, config, nameOfSchemaSource);\n delete config.extensionSlots;\n extensionConfigCache.set(cacheKey, {\n extensionSchema: extensionConfigSchema,\n extensionModuleSchema: configState.schemas[extensionModuleName],\n providedConfigs: configState.providedConfigs,\n temporaryConfig: tempConfigState.config,\n config\n });\n return config;\n}\nconst implementerToolsModuleCache = new Map();\nfunction getImplementerToolsConfig(configState, tempConfigState) {\n const annotatedSchemas = getAllSchemasWithValuesAndSources(configState.schemas);\n const configsAndSources = [\n ...configState.providedConfigs.map((c)=>[\n c.config,\n c.source\n ]),\n [\n tempConfigState.config,\n 'temporary config'\n ]\n ];\n // A module can be configured without having declared a schema, so the module list is the union\n // of both rather than just the schemas.\n const moduleNames = new Set(Object.keys(annotatedSchemas));\n for (const [config] of configsAndSources){\n for (const moduleName of Object.keys(config)){\n moduleNames.add(moduleName);\n }\n }\n const result = {};\n for (const moduleName of moduleNames){\n const annotatedSchema = annotatedSchemas[moduleName];\n const configSlices = configsAndSources.map(([config])=>config[moduleName]);\n const sources = configsAndSources.map(([, source])=>source);\n const cached = implementerToolsModuleCache.get(moduleName);\n if (cached && cached.annotatedSchema === annotatedSchema && cached.configSlices.length === configSlices.length && cached.configSlices.every((slice, i)=>slice === configSlices[i]) && cached.sources.every((source, i)=>source === sources[i])) {\n result[moduleName] = cached.result;\n continue;\n }\n let merged = annotatedSchema ?? {};\n configsAndSources.forEach(([, source], i)=>{\n const slice = configSlices[i];\n if (slice !== undefined) {\n merged = mergeDeepReplace(merged, createValuesAndSourcesTree(slice, source));\n }\n });\n implementerToolsModuleCache.set(moduleName, {\n annotatedSchema,\n configSlices,\n sources,\n result: merged\n });\n result[moduleName] = merged;\n }\n return result;\n}\n/**\n * Caching per module is what stops the walk being quadratic: defining one module's schema\n * recomputes every module.\n *\n * A module with no configuration of its own is published straight from this cache, so nothing may\n * mutate a tree it reads out of the implementer tools config — it is the cache entry.\n */ const schemaValuesAndSourcesCache = new Map();\nfunction getAllSchemasWithValuesAndSources(schemas) {\n const result = {};\n for (const [moduleName, schema] of Object.entries(schemas)){\n const cached = schemaValuesAndSourcesCache.get(moduleName);\n if (cached && cached.schema === schema) {\n result[moduleName] = cached.annotated;\n } else {\n const annotated = getSchemaWithValuesAndSources((0,lodash_es__rspack_import_7[\"default\"])(schema));\n schemaValuesAndSourcesCache.set(moduleName, {\n schema,\n annotated\n });\n result[moduleName] = annotated;\n }\n }\n return result;\n}\nfunction getSchemaWithValuesAndSources(schema) {\n if (schema.hasOwnProperty('_default')) {\n return {\n ...schema,\n _value: schema._default,\n _source: 'default'\n };\n } else if (isOrdinaryObject(schema)) {\n return Object.keys(schema).reduce((obj, key)=>{\n obj[key] = getSchemaWithValuesAndSources(schema[key]);\n return obj;\n }, {});\n } else {\n // at this point, the schema is bad and an error will have been logged during schema validation\n return {};\n }\n}\nfunction createValuesAndSourcesTree(config, source) {\n if (isOrdinaryObject(config)) {\n return Object.keys(config).reduce((obj, key)=>{\n obj[key] = createValuesAndSourcesTree(config[key], source);\n return obj;\n }, {});\n } else {\n return {\n _value: config,\n _source: source\n };\n }\n}\nfunction getExtensionSlotConfigs(configState, tempConfigState) {\n const allConfigs = mergeConfigs(getProvidedConfigs(configState, tempConfigState));\n const slotConfigPerModule = Object.keys(allConfigs).reduce((obj, key)=>{\n if (allConfigs[key]?.extensionSlots) {\n obj[key] = allConfigs[key]?.extensionSlots;\n }\n return obj;\n }, {});\n validateAllExtensionSlotConfigs(slotConfigPerModule);\n const slotConfigs = {};\n const configureBlocks = {};\n for (const configBySlotName of Object.values(slotConfigPerModule)){\n for (const [slotName, config] of Object.entries(configBySlotName)){\n slotConfigs[slotName] = config;\n if (config.configure) {\n var _configureBlocks, _slotName;\n ((_configureBlocks = configureBlocks)[_slotName = slotName] ?? (_configureBlocks[_slotName] = [])).push(config.configure);\n }\n }\n }\n for (const [slotName, blocks] of Object.entries(configureBlocks)){\n const configure = blocks.length === 1 ? blocks[0] : mergeConfigs(blocks);\n if (slotConfigs[slotName].configure !== configure) {\n slotConfigs[slotName] = {\n ...slotConfigs[slotName],\n configure\n };\n }\n }\n return slotConfigs;\n}\nfunction validateAllExtensionSlotConfigs(slotConfigPerModule) {\n for (let [moduleName, configBySlotName] of Object.entries(slotConfigPerModule)){\n for (let [slotName, config] of Object.entries(configBySlotName)){\n validateExtensionSlotConfig(config, moduleName, slotName);\n }\n }\n}\nfunction validateExtensionSlotConfig(config, moduleName, slotName) {\n const keyPath = `${moduleName}.extensionSlots.${slotName}`;\n const errorPrefix = `Extension slot config '${keyPath}'`;\n const invalidKeys = Object.keys(config).filter((k)=>![\n 'add',\n 'remove',\n 'order',\n 'configure'\n ].includes(k));\n if (invalidKeys.length) {\n logError(keyPath, errorPrefix + `' contains invalid keys '${invalidKeys.join(\"', '\")}'`);\n }\n if (config.add) {\n if (!Array.isArray(config.add) || !config.add.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.add' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.remove) {\n if (!Array.isArray(config.remove) || !config.remove.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.remove' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.order) {\n if (!Array.isArray(config.order) || !config.order.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.order' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.configure) {\n if (!isOrdinaryObject(config.configure)) {\n logError(keyPath, errorPrefix + `.configure' is invalid. Must be an object with extension IDs for keys`);\n }\n }\n}\nfunction getProvidedConfigs(configState, tempConfigState) {\n return [\n ...configState.providedConfigs.map((c)=>c.config),\n tempConfigState.config\n ];\n}\n/**\n * Validates the config schema for a module. Since problems identified here are programming errors\n * that hopefully will be caught during development, this function logs errors to the console directly;\n * it's fine if we spam the user with these errors.\n */ function validateConfigSchema(moduleName, schema, keyPath = '') {\n const updateMessage = `Please verify that you are running the latest version and, if so, alert the maintainer.`;\n for (const key of Object.keys(schema).filter((k)=>!k.startsWith('_'))){\n const thisKeyPath = keyPath + (keyPath && '.') + key;\n const schemaPart = schema[key];\n if (thisKeyPath === 'Display conditions') {\n console.error(`${moduleName} declares a configuration option called \"Display conditions\"; the \"Display conditions\" option is a reserved name. ${updateMessage}`);\n }\n if (thisKeyPath === 'Translation overrides') {\n console.error(`${moduleName} declares a configuration option called \"Translation overrides\"; the \"Translation overrides\" option is a reserved name. ${updateMessage}`);\n }\n if (!isOrdinaryObject(schemaPart)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}`);\n continue;\n }\n if (!schemaPart.hasOwnProperty('_default')) {\n // recurse for nested config keys\n validateConfigSchema(moduleName, schemaPart, thisKeyPath);\n }\n const elements = schemaPart._elements;\n if (hasObjectSchema(elements)) {\n validateConfigSchema(moduleName, elements, thisKeyPath + '._elements');\n }\n if (schemaPart._validators) {\n for (let validator of schemaPart._validators){\n if (typeof validator !== 'function') {\n console.error(`${moduleName} has invalid validator for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: validators must be functions that return either ` + `undefined or an error string. Received ${validator}.`);\n }\n }\n }\n const valueType = schemaPart._type;\n if (valueType && !Object.values(_types_js__rspack_import_0.Type).includes(valueType)) {\n console.error(`${moduleName} has invalid type for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: the allowed types are ${Object.values(_types_js__rspack_import_0.Type).join(', ')}. ` + `Received '${valueType}'`);\n }\n if (Object.keys(schemaPart).every((k)=>[\n '_description',\n '_validators',\n '_elements',\n '_type'\n ].includes(k)) && !keyPath.includes('._elements')) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: all config elements must have a default. ` + `Received ${JSON.stringify(schemaPart)}`);\n }\n if (elements && valueType && ![\n _types_js__rspack_import_0.Type.Array,\n _types_js__rspack_import_0.Type.Object\n ].includes(valueType)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: the 'elements' key only works with '_type' equal to 'Array' or 'Object'. ` + `Received ${JSON.stringify(valueType)}`);\n }\n }\n}\nfunction getConfigForModule(moduleName, configState, tempConfigState) {\n const schema = configState.schemas[moduleName];\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n validateStructure(schema, inputConfig, moduleName);\n const config = setDefaults(schema, inputConfig);\n runAllValidatorsInConfigTree(schema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction getConfigForModuleImplicitSchema(moduleName, configState, tempConfigState) {\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n const config = setDefaults(implicitConfigSchema, inputConfig);\n runAllValidatorsInConfigTree(implicitConfigSchema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction mergeConfigsFor(moduleName, allConfigs) {\n const allConfigsForModule = allConfigs.map(({ [moduleName]: c })=>c).filter((c)=>!!c);\n return mergeConfigs(allConfigsForModule);\n}\n/**\n * Merges a whole list at once, accumulating into one destination.\n */ function mergeConfigs(configs) {\n return configs.reduce((acc, config)=>(0,lodash_es__rspack_import_4[\"default\"])(acc, config, replaceArrays), {});\n}\n/**\n * Recursively check the provided config tree to make sure that all\n * of the provided properties exist in the schema, and that types are\n * correct. Does not run validators yet, since those will be run on\n * the config with the defaults filled in.\n */ function validateStructure(schema, config, keyPath = '') {\n // validate each constituent element\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (!schema.hasOwnProperty(key)) {\n if (!(key === 'extensionSlots' && keyPath !== '')) {\n logError(thisKeyPath, `Unknown config key '${thisKeyPath}' provided. Ignoring.`);\n }\n continue;\n }\n validateBranchStructure(schemaPart, value, thisKeyPath);\n }\n}\nfunction validateBranchStructure(schemaPart, value, keyPath) {\n checkType(keyPath, schemaPart._type, value);\n if (isOrdinaryObject(value)) {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Object) {\n // validate as freeform object\n validateFreeformObjectStructure(schemaPart, value, keyPath);\n } else if (!(schemaPart.hasOwnProperty('_default') || schemaPart.hasOwnProperty('_type'))) {\n // validate as normal nested config\n validateStructure(schemaPart, value, keyPath);\n }\n } else {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Array) {\n validateArrayStructure(schemaPart, value, keyPath);\n }\n }\n}\nfunction validateFreeformObjectStructure(freeformObjectSchema, config, keyPath) {\n if (freeformObjectSchema._elements) {\n for (const key of Object.keys(config)){\n const value = config[key];\n validateBranchStructure(freeformObjectSchema._elements, value, `${keyPath}.${key}`);\n }\n }\n}\nfunction validateArrayStructure(arraySchema, value, keyPath) {\n const validatedAsArray = checkType(keyPath, _types_js__rspack_import_0.Type.Array, value);\n if (!validatedAsArray) {\n return;\n }\n // if there is an array element object schema, verify that elements match it\n if (hasObjectSchema(arraySchema._elements)) {\n for(let i = 0; i < value.length; i++){\n validateBranchStructure(arraySchema._elements, value[i], `${keyPath}[${i}]`);\n }\n }\n for(let i = 0; i < value.length; i++){\n checkType(`${keyPath}[${i}]`, arraySchema._elements?._type, value[i]);\n }\n}\n/**\n * Run all the validators in the config tree. This should be run\n * on the config object after it has been filled in with all the defaults, since\n * higher-level validators may refer to default values.\n */ function runAllValidatorsInConfigTree(schema, config, keyPath = '') {\n // If `!schema`, there should have been a structural validation error printed already.\n if (schema) {\n if (config !== schema._default) {\n runValidators(keyPath, schema._validators, config);\n }\n if (isOrdinaryObject(config)) {\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (schema._type === _types_js__rspack_import_0.Type.Object && schema._elements) {\n runAllValidatorsInConfigTree(schema._elements, value, thisKeyPath);\n } else {\n runAllValidatorsInConfigTree(schemaPart, value, thisKeyPath);\n }\n }\n } else if (Array.isArray(config) && schema._elements) {\n for(let i = 0; i < config.length; i++){\n runAllValidatorsInConfigTree(schema._elements, config[i], `${keyPath}[${i}]`);\n }\n }\n }\n}\n/**\n * Run type validation for the value, logging any errors.\n * @returns true if validation passes, false otherwise\n */ function checkType(keyPath, _type, value) {\n if (_type) {\n const validator = {\n Array: _validators_type_validators_js__rspack_import_1.isArray,\n Boolean: _validators_type_validators_js__rspack_import_1.isBoolean,\n ConceptUuid: _validators_type_validators_js__rspack_import_1.isUuid,\n Number: _validators_type_validators_js__rspack_import_1.isNumber,\n Object: _validators_type_validators_js__rspack_import_1.isObject,\n String: _validators_type_validators_js__rspack_import_1.isString,\n UUID: _validators_type_validators_js__rspack_import_1.isUuid,\n PersonAttributeTypeUuid: _validators_type_validators_js__rspack_import_1.isUuid,\n PatientIdentifierTypeUuid: _validators_type_validators_js__rspack_import_1.isUuid\n };\n return runValidators(keyPath, [\n validator[_type]\n ], value);\n }\n return true;\n}\n/**\n * Runs validators, logging errors.\n * @returns true if all pass, false otherwise.\n */ function runValidators(keyPath, validators, value) {\n let returnValue = true;\n if (validators) {\n try {\n for (let validator of validators){\n const validatorResult = validator(value);\n if (typeof validatorResult === 'string') {\n const message = typeof value === 'object' ? `Invalid configuration for ${keyPath}: ${validatorResult}` : `Invalid configuration value ${value} for ${keyPath}: ${validatorResult}`;\n logError(keyPath, message);\n returnValue = false;\n }\n }\n } catch (e) {\n console.error(`Skipping invalid validator at \"${keyPath}\". Encountered error\\n\\t${e}`);\n }\n }\n return returnValue;\n}\n// Recursively fill in the config with values from the schema.\nconst setDefaults = (schema, inputConfig)=>{\n const config = structuredClone(inputConfig);\n if (!schema) {\n return config;\n }\n for (const key of Object.keys(schema)){\n const configPart = config[key];\n const schemaPart = schema[key];\n // The `schemaPart &&` clause of this `if` statement will only fail\n // if the schema is very invalid. It is there to prevent the app from\n // crashing completely, though it will produce unexpected behavior.\n // If this happens, there should be legible errors in the console from\n // the schema validator.\n if (schemaPart && (schemaPart.hasOwnProperty('_type') || schemaPart.hasOwnProperty('_default'))) {\n // We assume that schemaPart defines a config value, since it has\n // a property `_type` or `_default`.\n if (!config.hasOwnProperty(key)) {\n config[key] = schemaPart['_default'];\n }\n // We also check if it is an object or array with object elements, in which case we recurse\n const elements = schemaPart._elements;\n if (configPart && hasObjectSchema(elements)) {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Array && Array.isArray(configPart)) {\n const configWithDefaults = configPart.map((conf)=>setDefaults(elements, conf));\n config[key] = configWithDefaults;\n } else if (schemaPart._type === _types_js__rspack_import_0.Type.Object) {\n for (let objectKey of Object.keys(configPart)){\n configPart[objectKey] = setDefaults(elements, configPart[objectKey]);\n }\n }\n }\n } else if (isOrdinaryObject(schemaPart)) {\n // Since schemaPart has no property \"_type\", if it's an ordinary object\n // (unlike, importantly, the validators array), we assume it is a parent config property.\n // We recurse to config[key] and schema[key]. Default config[key] to {}.\n const selectedConfigPart = configPart ?? {};\n // There will have been a validation error already if configPart is not a plain object.\n if (isOrdinaryObject(selectedConfigPart)) {\n config[key] = setDefaults(schemaPart, selectedConfigPart);\n }\n }\n }\n return config;\n};\nfunction hasObjectSchema(elementsSchema) {\n return !!elementsSchema && Object.keys(elementsSchema).filter((e)=>![\n '_default',\n '_validators'\n ].includes(e)).length > 0;\n}\nfunction isOrdinaryObject(value) {\n return typeof value === 'object' && !Array.isArray(value) && value !== null;\n}\n/** Keep track of which validation errors we have displayed. Each one should only be displayed once. */ let displayedValidationMessages = new Set();\nfunction logError(keyPath, message) {\n const key = `${keyPath}:::${message}`;\n // technically, this should not be possible, but because of how things wind-up transpiled, this isn't impossible\n if (!displayedValidationMessages) {\n displayedValidationMessages = new Set();\n }\n if (!displayedValidationMessages.has(key)) {\n console.error(message);\n displayedValidationMessages.add(key);\n }\n}\n/**\n * Normally, configuration errors are only displayed once. This function clears the list of\n * displayed errors, so that they will be displayed again.\n *\n * @internal\n */ function clearConfigErrors(keyPath) {\n if (keyPath) {\n displayedValidationMessages.forEach((key)=>{\n if (key.startsWith(keyPath)) {\n displayedValidationMessages.delete(key);\n }\n });\n } else {\n displayedValidationMessages.clear();\n }\n}\n/**\n * Cleans up all config store subscriptions and re-establishes them. This is primarily\n * useful for testing, where subscriptions set up at module load time need to be cleared\n * between tests to prevent infinite update loops. After clearing, subscriptions are\n * re-established so the config system continues to work normally.\n *\n * @internal\n */ function resetConfigSystem() {\n configSubscriptions.forEach((unsubscribe)=>unsubscribe());\n configSubscriptions.length = 0;\n // Cached configs are keyed on input identity, so a test that reuses the same schema or config\n // objects across cases would otherwise be served the previous case's result.\n moduleConfigCache.clear();\n extensionConfigCache.clear();\n schemaValuesAndSourcesCache.clear();\n implementerToolsModuleCache.clear();\n setupConfigSubscriptions();\n}\n/**\n * Copied over from esm-extensions. It rightly belongs to that module, but esm-config\n * cannot depend on esm-extensions.\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\n/**\n * The translation overrides schema is used in the implicit schema given to every module;\n * plus any additional translation namespaces (at time of writing, this is just 'core').\n */ const translationOverridesSchema = {\n 'Translation overrides': {\n _description: 'Per-language overrides for frontend translations should be keyed by language code and each language dictionary contains the translation key and the display value',\n _type: _types_js__rspack_import_0.Type.Object,\n _default: {},\n _validators: [\n (0,_validators_validator_js__rspack_import_2.validator)((o)=>Object.keys(o).every((k)=>/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k)), (o)=>{\n const badKeys = Object.keys(o).filter((k)=>!/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k));\n return `The 'Translation overrides' object should have language codes for keys. Language codes must be in the form of a two-to-three letter language code optionally followed by a hyphen and a two-to-three letter country code. The following keys do not conform: ${badKeys.join(', ')}.`;\n })\n ]\n }\n};\n/**\n * The implicitConfigSchema is implicitly included in every configuration schema\n */ const implicitConfigSchema = {\n 'Display conditions': {\n privileges: {\n _description: 'The privilege(s) the user must have to use this extension',\n _type: _types_js__rspack_import_0.Type.Array,\n _default: []\n },\n expression: {\n _description: 'The expression that determines whether the extension is displayed',\n _type: _types_js__rspack_import_0.Type.String,\n _default: undefined\n }\n },\n ...translationOverridesSchema\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tY29uZmlnL2Rpc3QvbW9kdWxlLWNvbmZpZy9tb2R1bGUtY29uZmlnLmpzP2MzYTUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBtb2R1bGUgQGNhdGVnb3J5IENvbmZpZyAqLyBpbXBvcnQgeyBjbG9uZURlZXAsIGlzRXF1YWwsIG1lcmdlV2l0aCwgb21pdCBhcyBsb2Rhc2hPbWl0IH0gZnJvbSBcImxvZGFzaC1lc1wiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCIuLi90eXBlcy5qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNCb29sZWFuLCBpc1V1aWQsIGlzTnVtYmVyLCBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdmFsaWRhdG9ycy90eXBlLXZhbGlkYXRvcnMuanNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuLi92YWxpZGF0b3JzL3ZhbGlkYXRvci5qc1wiO1xuaW1wb3J0IHsgY29uZmlnRXh0ZW5zaW9uU3RvcmUsIGNvbmZpZ0ludGVybmFsU3RvcmUsIGdldENvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25Db25maWcsIGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUsIGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSwgY2xlYXJDb25maWdEZXJpdmF0aW9uRXJyb3IsIGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSwgaW52YWxpZGF0ZUltcGxlbWVudGVyVG9vbHNDb25maWcsIHJlY29yZENvbmZpZ0Rlcml2YXRpb25FcnJvciwgc2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZ1JlY29tcHV0ZXIsIHRlbXBvcmFyeUNvbmZpZ1N0b3JlIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbi8qKlxuICogRGVlcCBtZXJnZSB0d28gb2JqZWN0cywgd2l0aCByaWdodC1zaWRlIHZhbHVlcyB0YWtpbmcgcHJlY2VkZW5jZS5cbiAqIEFycmF5cyBhcmUgcmVwbGFjZWQgZW50aXJlbHkgKG5vdCBtZXJnZWQgYnkgaW5kZXgpLCBtYXRjaGluZyB0aGVcbiAqIGJlaGF2aW9yIG9mIHJhbWRhJ3MgbWVyZ2VEZWVwUmlnaHQuXG4gKi8gZnVuY3Rpb24gcmVwbGFjZUFycmF5cyhfb2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3JjVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBtZXJnZURlZXBSZXBsYWNlKGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIG1lcmdlV2l0aCh7fSwgbGVmdCwgcmlnaHQsIHJlcGxhY2VBcnJheXMpO1xufVxuLyoqXG4gKiBTdG9yZSBzZXR1cFxuICpcbiAqXG4gKiBTZXQgdXAgc3RvcmVzIGFuZCBzdWJzY3JpcHRpb25zIHNvIHRoYXQgaW5wdXRzIGdldCBwcm9jZXNzZWQgYXBwcm9wcmlhdGVseS5cbiAqXG4gKiBUaGVyZSBhcmUgKmlucHV0KiBzdG9yZXMgYW5kICpvdXRwdXQqIHN0b3Jlcy4gVGhlICppbnB1dCogc3RvcmVzXG4gKiBhcmUgY29uZmlnSW50ZXJuYWxTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUsIGFuZCBjb25maWdFeHRlbnNpb25TdG9yZS4gVGhlXG4gKiBvdXRwdXQgc3RvcmVzIGFyZSBzZXQgaW4gdGhlIGBjb21wdXRlLi4uYCBmdW5jdGlvbnMuIFRoZXkgYXJlIHRoZSBtb2R1bGVcbiAqIGNvbmZpZyBzdG9yZXMsIHRoZSBleHRlbnNpb24gc2xvdCBjb25maWcgc3RvcmVzIChieSBtb2R1bGUpLCB0aGUgZXh0ZW5zaW9uXG4gKiBjb25maWcgc3RvcmVzLCBhbmQgdGhlIGltcGxlbWVudGVyIHRvb2xzIGNvbmZpZyBzdG9yZS5cbiAqXG4gKiBUaGlzIGNvZGUgc2V0cyB1cCB0aGUgc3Vic2NyaXB0aW9ucyBzbyB0aGF0IHdoZW4gYW4gaW5wdXQgc3RvcmUgY2hhbmdlcyxcbiAqIHRoZSBjb3JyZWN0IHNldCBvZiBvdXRwdXQgc3RvcmVzIGFyZSB1cGRhdGVkLlxuICpcbiAqIEFsbCBgY29tcHV0ZS4uLmAgZnVuY3Rpb25zIGV4Y2VwdCBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGFyZSBwdXJlXG4gKiAob3IgYXJlIHN1cHBvc2VkIHRvIGJlKSwgb3RoZXIgdGhhbiB0aGUgZmFjdCB0aGF0IHRoZXkgYWxsIGBzZXRTdGF0ZWBcbiAqIHN0b3JlIHZhbHVlcyBhdCB0aGUgZW5kLiBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGNhbGxzIGBnZXRHbG9iYWxTdG9yZWAsXG4gKiB3aGljaCBjcmVhdGVzIHN0b3Jlcy5cbiAqLyAvLyBTdG9yZSB1bnN1YnNjcmliZSBmdW5jdGlvbnMgdG8gYWxsb3cgY2xlYW51cCAoZS5nLiwgaW4gdGVzdHMgb3IgaG90IG1vZHVsZSByZWxvYWRpbmcpXG5jb25zdCBjb25maWdTdWJzY3JpcHRpb25zID0gW107XG4vKipcbiAqIFJlY29tcHV0ZXMgYWxsIGNvbmZpZ3VyYXRpb24gZGVyaXZlZCBzdG9yZXMgYmFzZWQgb24gY3VycmVudCBzdGF0ZSBvZiBpbnB1dCBzdG9yZXMuXG4gKiBDYWxsZWQgd2hlbmV2ZXIgYW55IGlucHV0IHN0b3JlIChjb25maWdJbnRlcm5hbFN0b3JlLCB0ZW1wb3JhcnlDb25maWdTdG9yZSwgY29uZmlnRXh0ZW5zaW9uU3RvcmUpIGNoYW5nZXMuXG4gKi8gZnVuY3Rpb24gcmVjb21wdXRlQWxsQ29uZmlncygpIHtcbiAgICBjb25zdCBjb25maWdTdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCB0ZW1wQ29uZmlnU3RhdGUgPSB0ZW1wb3JhcnlDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGV4dGVuc2lvblN0YXRlID0gY29uZmlnRXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb21wdXRlTW9kdWxlQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbnN0IHNsb3RDb25maWdzID0gZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29tcHV0ZUV4dGVuc2lvblNsb3RDb25maWdzKHNsb3RDb25maWdzKTtcbiAgICBjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyhjb25maWdTdGF0ZSwgZXh0ZW5zaW9uU3RhdGUsIHRlbXBDb25maWdTdGF0ZSwgc2xvdENvbmZpZ3MpO1xuICAgIC8vIExhc3QsIGJlY2F1c2UgYSBmYWlsdXJlIGhlcmUgbXVzdCBub3Qgc2tpcCB0aGUgb3V0cHV0cyBhYm92ZS4gT25seSBrZXB0IGN1cnJlbnQgd2hpbGUgdGhlXG4gICAgLy8gaW1wbGVtZW50ZXIgdG9vbHMgYXJlIHdhdGNoaW5nIGl0OyBvdGhlcndpc2UgZGVyaXZlZCBvbiByZWFkLlxuICAgIGludmFsaWRhdGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKCk7XG59XG5mdW5jdGlvbiBzZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMoKSB7XG4gICAgLy8gUmVnaXN0ZXJlZCBoZXJlIHJhdGhlciB0aGFuIGF0IG1vZHVsZSBsb2FkIHNvIHRoYXQgYHJlc2V0Q29uZmlnU3lzdGVtYCByZXN0b3JlcyBpdC5cbiAgICBzZXRJbXBsZW1lbnRlclRvb2xzQ29uZmlnUmVjb21wdXRlcigoKT0+Y29tcHV0ZUltcGxlbWVudGVyVG9vbHNDb25maWcoY29uZmlnSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpLCB0ZW1wb3JhcnlDb25maWdTdG9yZS5nZXRTdGF0ZSgpKSk7XG4gICAgLy8gSW5pdGlhbCBjb21wdXRhdGlvblxuICAgIHJlY29tcHV0ZUFsbENvbmZpZ3MoKTtcbiAgICAvLyBTdWJzY3JpYmUgdG8gYWxsIGlucHV0IHN0b3JlcyB3aXRoIGEgc2luZ2xlIGhhbmRsZXJcbiAgICAvLyBUaGlzIGVuc3VyZXMgd2Ugb25seSByZWNvbXB1dGUgb25jZSBldmVuIGlmIG11bHRpcGxlIHN0b3JlcyBjaGFuZ2Ugc2ltdWx0YW5lb3VzbHlcbiAgICBjb25maWdTdWJzY3JpcHRpb25zLnB1c2goY29uZmlnSW50ZXJuYWxTdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlnc1NhZmVseSksIHRlbXBvcmFyeUNvbmZpZ1N0b3JlLnN1YnNjcmliZShyZWNvbXB1dGVBbGxDb25maWdzU2FmZWx5KSwgY29uZmlnRXh0ZW5zaW9uU3RvcmUuc3Vic2NyaWJlKHJlY29tcHV0ZUFsbENvbmZpZ3NTYWZlbHkpKTtcbn1cbi8qKiBFbnN1cmUgdGhhdCB3ZSBkbyBub3QgdGhyb3cgZHVyaW5nIGEgc3RvcmUgc3Vic2NyaXB0aW9uICovIGZ1bmN0aW9uIHJlY29tcHV0ZUFsbENvbmZpZ3NTYWZlbHkoKSB7XG4gICAgY2xlYXJDb25maWdEZXJpdmF0aW9uRXJyb3IoKTtcbiAgICB0cnkge1xuICAgICAgICByZWNvbXB1dGVBbGxDb25maWdzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZWNvcmRDb25maWdEZXJpdmF0aW9uRXJyb3IoZSk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0ZhaWxlZCB0byByZWNvbXB1dGUgdGhlIGNvbmZpZ3VyYXRpb24nLCBlKTtcbiAgICB9XG59XG4vLyBTZXQgdXAgc3Vic2NyaXB0aW9ucyBhdCBtb2R1bGUgbG9hZCB0aW1lXG5zZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMoKTtcbmNvbnN0IG1vZHVsZUNvbmZpZ0NhY2hlID0gbmV3IE1hcCgpO1xuZnVuY3Rpb24gY29tcHV0ZU1vZHVsZUNvbmZpZyhzdGF0ZSwgdGVtcFN0YXRlKSB7XG4gICAgZm9yIChsZXQgbW9kdWxlTmFtZSBvZiBPYmplY3Qua2V5cyhzdGF0ZS5zY2hlbWFzKSl7XG4gICAgICAgIC8vIEF0IHRoaXMgcG9pbnQgdGhlIHNjaGVtYSBjb3VsZCBiZSBlaXRoZXIganVzdCB0aGUgaW1wbGljaXQgc2NoZW1hIG9yIHRoZSBhY3R1YWxseVxuICAgICAgICAvLyBkZWZpbmVkIHNjaGVtYS4gV2UgcnVuIHdpdGgganVzdCB0aGUgaW1wbGljaXQgc2NoZW1hIGJlY2F1c2Ugd2Ugd2FudCB0byBwb3B1bGF0ZVxuICAgICAgICAvLyB0aGUgY29uZmlnIHN0b3JlIHdpdGggdGhlIHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBhcyBzb29uIGFzIHBvc3NpYmxlLiBJbiBmYWN0LCB0aGVcbiAgICAgICAgLy8gdHJhbnNsYXRpb24gc3lzdGVtIHdpbGwgdGhyb3cgZm9yIFN1c3BlbnNlIHVudGlsIHRoZSB0cmFuc2xhdGlvbiBvdmVycmlkZXMgYXJlXG4gICAgICAgIC8vIGF2YWlsYWJsZSwgd2hpY2ggYXMgb2YgdGhpcyB3cml0aW5nIGJsb2NrcyB0aGUgc2NoZW1hIGRlZmluaXRpb24gZnJvbSBvY2N1cnJpbmdcbiAgICAgICAgLy8gZm9yIG1vZHVsZXMgbG9hZGVkIGJhc2VkIG9uIHRoZWlyIGV4dGVuc2lvbnMuXG4gICAgICAgIGNvbnN0IG1vZHVsZVN0b3JlID0gZ2V0Q29uZmlnU3RvcmUobW9kdWxlTmFtZSk7XG4gICAgICAgIGNvbnN0IHNjaGVtYSA9IHN0YXRlLnNjaGVtYXNbbW9kdWxlTmFtZV07XG4gICAgICAgIGNvbnN0IG1vZHVsZUxvYWRlZCA9IEJvb2xlYW4oc3RhdGUubW9kdWxlTG9hZGVkW21vZHVsZU5hbWVdKTtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gbW9kdWxlQ29uZmlnQ2FjaGUuZ2V0KG1vZHVsZU5hbWUpO1xuICAgICAgICBsZXQgbmV3U3RhdGU7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgY2FjaGVkLnNjaGVtYSA9PT0gc2NoZW1hICYmIGNhY2hlZC5tb2R1bGVMb2FkZWQgPT09IG1vZHVsZUxvYWRlZCAmJiBjYWNoZWQucHJvdmlkZWRDb25maWdzID09PSBzdGF0ZS5wcm92aWRlZENvbmZpZ3MgJiYgY2FjaGVkLnRlbXBvcmFyeUNvbmZpZyA9PT0gdGVtcFN0YXRlLmNvbmZpZykge1xuICAgICAgICAgICAgbmV3U3RhdGUgPSBjYWNoZWQuc3RhdGU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBjb25maWcgPSBtb2R1bGVMb2FkZWQgPyBnZXRDb25maWdGb3JNb2R1bGUobW9kdWxlTmFtZSwgc3RhdGUsIHRlbXBTdGF0ZSkgOiBnZXRDb25maWdGb3JNb2R1bGVJbXBsaWNpdFNjaGVtYShtb2R1bGVOYW1lLCBzdGF0ZSwgdGVtcFN0YXRlKTtcbiAgICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgICAgIHRyYW5zbGF0aW9uT3ZlcnJpZGVzTG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGxvYWRlZDogbW9kdWxlTG9hZGVkLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIG1vZHVsZUNvbmZpZ0NhY2hlLnNldChtb2R1bGVOYW1lLCB7XG4gICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgIG1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBwcm92aWRlZENvbmZpZ3M6IHN0YXRlLnByb3ZpZGVkQ29uZmlncyxcbiAgICAgICAgICAgICAgICB0ZW1wb3JhcnlDb25maWc6IHRlbXBTdGF0ZS5jb25maWcsXG4gICAgICAgICAgICAgICAgc3RhdGU6IG5ld1N0YXRlXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBXcml0aW5nIHVuY29uZGl0aW9uYWxseSB3b3VsZCBoYW5kIGV2ZXJ5IGB1c2VDb25maWdgIGNvbnN1bWVyIGluIHRoZSBhcHBsaWNhdGlvbiBhIG5ld1xuICAgICAgICAvLyBvYmplY3Qg4oCUIGFuZCBhIHJlLXJlbmRlciDigJQgd2hlbmV2ZXIgYW55IG1vZHVsZSBvciBleHRlbnNpb24gYW55d2hlcmUgaXMgbG9hZGVkLlxuICAgICAgICBjb25zdCBvbGRTdGF0ZSA9IG1vZHVsZVN0b3JlLmdldFN0YXRlKCk7XG4gICAgICAgIGlmIChvbGRTdGF0ZS5sb2FkZWQgIT09IG5ld1N0YXRlLmxvYWRlZCB8fCBvbGRTdGF0ZS50cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZCAhPT0gbmV3U3RhdGUudHJhbnNsYXRpb25PdmVycmlkZXNMb2FkZWQgfHwgIWlzRXF1YWwob2xkU3RhdGUuY29uZmlnLCBuZXdTdGF0ZS5jb25maWcpKSB7XG4gICAgICAgICAgICBtb2R1bGVTdG9yZS5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBjb21wdXRlRXh0ZW5zaW9uU2xvdENvbmZpZ3Moc2xvdENvbmZpZ3MpIHtcbiAgICBjb25zdCBzbG90U3RvcmUgPSBnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlKCk7XG4gICAgY29uc3Qgb2xkU2xvdHMgPSBzbG90U3RvcmUuZ2V0U3RhdGUoKS5zbG90cztcbiAgICBjb25zdCBzbG90cyA9IHt9O1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgZm9yIChjb25zdCBbc2xvdE5hbWUsIGNvbmZpZ10gb2YgT2JqZWN0LmVudHJpZXMoc2xvdENvbmZpZ3MpKXtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBvbGRTbG90c1tzbG90TmFtZV07XG4gICAgICAgIC8vIEVudHJpZXMga2VlcCB0aGVpciBpZGVudGl0eSB3aGVuIHRoZSBjb25maWd1cmF0aW9uIGJlaGluZCB0aGVtIGhhc24ndCBjaGFuZ2VkLCBzbyB0aGF0XG4gICAgICAgIC8vIGNoYW5naW5nIG9uZSBzbG90J3MgY29uZmlndXJhdGlvbiBkb2Vzbid0IGludmFsaWRhdGUgZXZlcnkgb3RoZXIgY29uZmlndXJlZCBzbG90LlxuICAgICAgICBpZiAocHJldmlvdXM/LmxvYWRlZCAmJiBpc0VxdWFsKHByZXZpb3VzLmNvbmZpZywgY29uZmlnKSkge1xuICAgICAgICAgICAgc2xvdHNbc2xvdE5hbWVdID0gcHJldmlvdXM7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzbG90c1tzbG90TmFtZV0gPSB7XG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlLFxuICAgICAgICAgICAgICAgIGNvbmZpZ1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIC8vIEJ1aWx0IGZyb20gc2NyYXRjaCByYXRoZXIgdGhhbiBtZXJnZWQgb3ZlciB0aGUgcHJldmlvdXMgc3RhdGU6IGEgc2xvdCB3aG9zZSBjb25maWd1cmF0aW9uXG4gICAgLy8gaGFzIGJlZW4gcmVtb3ZlZCDigJQgY2xlYXJpbmcgdGhlIHRlbXBvcmFyeSBjb25maWcsIHNheSDigJQgaGFzIHRvIGxvc2UgaXRzIGVudHJ5LCBvciB0aGUgb2xkXG4gICAgLy8gY29uZmlndXJhdGlvbiBzdGF5cyBpbiBmb3JjZSB1bnRpbCB0aGUgcGFnZSBpcyByZWxvYWRlZC5cbiAgICBpZiAoY2hhbmdlZCB8fCBPYmplY3Qua2V5cyhvbGRTbG90cykubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhzbG90cykubGVuZ3RoKSB7XG4gICAgICAgIHNsb3RTdG9yZS5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBzbG90c1xuICAgICAgICB9KTtcbiAgICB9XG59XG5mdW5jdGlvbiBjb21wdXRlSW1wbGVtZW50ZXJUb29sc0NvbmZpZyhzdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3Qgb2xkU3RhdGUgPSBpbXBsZW1lbnRlclRvb2xzQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCBjb25maWcgPSBnZXRJbXBsZW1lbnRlclRvb2xzQ29uZmlnKHN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgICAgICBjb25maWdcbiAgICB9O1xuICAgIC8vIFVzZSBkZWVwIGVxdWFsaXR5IG9uIHRoZSBhY3R1YWwgY29uZmlnIGNvbnRlbnQsIG5vdCB0aGUgd3JhcHBlciBvYmplY3RcbiAgICBpZiAoIWlzRXF1YWwob2xkU3RhdGUuY29uZmlnLCBuZXdTdGF0ZS5jb25maWcpKSB7XG4gICAgICAgIGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZS5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgfVxufVxuZnVuY3Rpb24gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3MoY29uZmlnU3RhdGUsIGV4dGVuc2lvblN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUsIHNsb3RDb25maWdzKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlID0gZ2V0RXh0ZW5zaW9uc0NvbmZpZ1N0b3JlKCk7XG4gICAgY29uc3Qgb2xkQ29uZmlncyA9IGV4dGVuc2lvbnNDb25maWdTdG9yZS5nZXRTdGF0ZSgpLmNvbmZpZ3M7XG4gICAgY29uc3QgY29uZmlncyA9IHt9O1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgbGV0IGVudHJ5Q291bnQgPSAwO1xuICAgIC8vIFdlIGFzc3VtZSB0aGF0IHRoZSBtb2R1bGUgc2NoZW1hIGhhcyBhbHJlYWR5IGJlZW4gZGVmaW5lZCwgc2luY2UgdGhlIGV4dGVuc2lvblxuICAgIC8vIGl0IGNvbnRhaW5zIGlzIG1vdW50ZWQuXG4gICAgZm9yIChsZXQgZXh0ZW5zaW9uIG9mIGV4dGVuc2lvblN0YXRlLm1vdW50ZWRFeHRlbnNpb25zKXtcbiAgICAgICAgY29uc3QgY29uZmlnID0gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZyhleHRlbnNpb24uc2xvdE1vZHVsZU5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25Nb2R1bGVOYW1lLCBleHRlbnNpb24uc2xvdE5hbWUsIGV4dGVuc2lvbi5leHRlbnNpb25JZCwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSwgc2xvdENvbmZpZ3NbZXh0ZW5zaW9uLnNsb3ROYW1lXSk7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gb2xkQ29uZmlnc1tleHRlbnNpb24uc2xvdE5hbWVdPy5bZXh0ZW5zaW9uLmV4dGVuc2lvbklkXTtcbiAgICAgICAgLy8gRW50cmllcyBrZWVwIHRoZWlyIGlkZW50aXR5IHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gYmVoaW5kIHRoZW0gaGFzbid0IGNoYW5nZWQsIHNvIHRoYXRcbiAgICAgICAgLy8gbW91bnRpbmcgb25lIGV4dGVuc2lvbiBkb2Vzbid0IGhhbmQgZXZlcnkgb3RoZXIgbW91bnRlZCBleHRlbnNpb24gYSBuZXcgY29uZmlnIG9iamVjdC5cbiAgICAgICAgY29uc3QgZW50cnkgPSBwcmV2aW91cz8ubG9hZGVkICYmIGlzRXF1YWwocHJldmlvdXMuY29uZmlnLCBjb25maWcpID8gcHJldmlvdXMgOiB7XG4gICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICBsb2FkZWQ6IHRydWVcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKGVudHJ5ICE9PSBwcmV2aW91cykge1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV0pIHtcbiAgICAgICAgICAgIGNvbmZpZ3NbZXh0ZW5zaW9uLnNsb3ROYW1lXSA9IHt9O1xuICAgICAgICB9XG4gICAgICAgIGNvbmZpZ3NbZXh0ZW5zaW9uLnNsb3ROYW1lXVtleHRlbnNpb24uZXh0ZW5zaW9uSWRdID0gZW50cnk7XG4gICAgICAgIGVudHJ5Q291bnQrKztcbiAgICB9XG4gICAgLy8gU2xvdHMga2VlcCB0aGVpciBpZGVudGl0eSB0b28gd2hlbiBub25lIG9mIHRoZWlyIGVudHJpZXMgY2hhbmdlZC4gU3Vic2NyaWJlcnMgY29tcGFyZSB0aGVzZVxuICAgIC8vIHBlci1zbG90IG9iamVjdHMgdG8gd29yayBvdXQgd2hpY2ggc2xvdHMgdG8gcmUtZGVyaXZlLCBzbyBoYW5kaW5nIG91dCBhIGZyZXNoIG9uZSBmb3IgZXZlcnlcbiAgICAvLyBzbG90IG9uIGV2ZXJ5IHdyaXRlIHdvdWxkIG1hcmsgZXZlcnkgc2xvdCB3aXRoIGEgbW91bnRlZCBleHRlbnNpb24gZGlydHkuXG4gICAgZm9yIChjb25zdCBbc2xvdE5hbWUsIHNsb3RDb25maWdzXSBvZiBPYmplY3QuZW50cmllcyhjb25maWdzKSl7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzU2xvdCA9IG9sZENvbmZpZ3Nbc2xvdE5hbWVdO1xuICAgICAgICBpZiAocHJldmlvdXNTbG90ICYmIE9iamVjdC5rZXlzKHByZXZpb3VzU2xvdCkubGVuZ3RoID09PSBPYmplY3Qua2V5cyhzbG90Q29uZmlncykubGVuZ3RoICYmIE9iamVjdC5lbnRyaWVzKHNsb3RDb25maWdzKS5ldmVyeSgoW2V4dGVuc2lvbklkLCBlbnRyeV0pPT5wcmV2aW91c1Nsb3RbZXh0ZW5zaW9uSWRdID09PSBlbnRyeSkpIHtcbiAgICAgICAgICAgIGNvbmZpZ3Nbc2xvdE5hbWVdID0gcHJldmlvdXNTbG90O1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmICghY2hhbmdlZCkge1xuICAgICAgICAvLyBOb3RoaW5nIHdhcyBhZGRlZCBvciBhbHRlcmVkLCBidXQgYW4gZXh0ZW5zaW9uIG1heSBoYXZlIHVubW91bnRlZCwgd2hpY2ggb25seSBzaG93cyB1cCBhcyBhXG4gICAgICAgIC8vIG1pc3NpbmcgZW50cnkuXG4gICAgICAgIGNoYW5nZWQgPSBPYmplY3Qua2V5cyhvbGRDb25maWdzKS5sZW5ndGggIT09IE9iamVjdC5rZXlzKGNvbmZpZ3MpLmxlbmd0aCB8fCBPYmplY3QudmFsdWVzKG9sZENvbmZpZ3MpLnJlZHVjZSgodG90YWwsIHNsb3QpPT50b3RhbCArIE9iamVjdC5rZXlzKHNsb3QpLmxlbmd0aCwgMCkgIT09IGVudHJ5Q291bnQ7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICAgIGV4dGVuc2lvbnNDb25maWdTdG9yZS5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBjb25maWdzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qXG4gKiBBUElcbiAqXG4gKi8gLyoqXG4gKiBUaGlzIGRlZmluZXMgYSBjb25maWd1cmF0aW9uIHNjaGVtYSBmb3IgYSBtb2R1bGUuIFRoZSBzY2hlbWEgdGVsbHMgdGhlXG4gKiBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC4gSXQgc3BlY2lmaWVzXG4gKiB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZW4tVVMvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gbW9kdWxlTmFtZSBOYW1lIG9mIHRoZSBtb2R1bGUgdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci4gR2VuZXJhbGx5XG4gKiAgIHNob3VsZCBiZSB0aGUgb25lIGluIHdoaWNoIHRoZSBgZGVmaW5lQ29uZmlnU2NoZW1hYCBjYWxsIHRha2VzIHBsYWNlLlxuICogQHBhcmFtIHNjaGVtYSBUaGUgY29uZmlnIHNjaGVtYSBmb3IgdGhlIG1vZHVsZVxuICovIGV4cG9ydCBmdW5jdGlvbiBkZWZpbmVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKSB7XG4gICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hKTtcbiAgICBjb25zdCBlbmhhbmNlZFNjaGVtYSA9IG1lcmdlRGVlcFJlcGxhY2Uoc2NoZW1hLCBpbXBsaWNpdENvbmZpZ1NjaGVtYSk7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IGVuaGFuY2VkU2NoZW1hXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgbW9kdWxlTG9hZGVkOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUubW9kdWxlTG9hZGVkLFxuICAgICAgICAgICAgICAgIFttb2R1bGVOYW1lXTogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG59XG4vKipcbiAqIFRoaXMgYWxlcnRzIHRoZSBjb25maWd1cmF0aW9uIHN5c3RlbSB0aGF0IGEgbW9kdWxlIGV4aXN0cy4gVGhpcyBhbGxvd3MgY29uZmlnIHRvIGJlXG4gKiBwcm9jZXNzZWQsIHdoaWxlIHN0aWxsIGFsbG93aW5nIHRoZSBleHRlbnNpb24gc3lzdGVtIHRvIGtub3cgd2hldGhlciB0aGUgbW9kdWxlIGhhc1xuICogYWN0dWFsbHkgaGFkIGl0cyBmcm9udCBidW5kbGUgZXhlY3V0ZWQgeWV0LlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG1vZHVsZU5hbWVcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVXaXRoQ29uZmlnU3lzdGVtKG1vZHVsZU5hbWUpIHtcbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIHNjaGVtYXM6IHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zY2hlbWFzLFxuICAgICAgICAgICAgICAgIFttb2R1bGVOYW1lXTogaW1wbGljaXRDb25maWdTY2hlbWFcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsZXJ0cyB0aGUgY29uZmlndXJhdGlvbiBzeXN0ZW0gdGhhdCBhIG1vZHVsZSBoYXMgYmVlbiBsb2FkZWQuXG4gKlxuICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGluIGVzbS1hcHAtc2hlbGwuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0gbW9kdWxlTmFtZVxuICovIGV4cG9ydCBmdW5jdGlvbiByZWdpc3Rlck1vZHVsZUxvYWQobW9kdWxlTmFtZSkge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgbW9kdWxlTG9hZGVkOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUubW9kdWxlTG9hZGVkLFxuICAgICAgICAgICAgICAgIFttb2R1bGVOYW1lXTogdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG59XG4vKipcbiAqIFRoaXMgYWxsb3dzIHRoZSBjb25maWcgc3lzdGVtIHRvIHN1cHBvcnQgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIGZvciBuYW1lc3BhY2VzIHRoYXRcbiAqIGRvIG5vdCBjb3JyZXNwb25kIHRvIG1vZHVsZXMuXG4gKlxuICogVGhpcyBzaG91bGQgb25seSBiZSB1c2VkIGluIGVzbS1hcHAtc2hlbGwuXG4gKlxuICogQGludGVybmFsXG4gKiBAcGFyYW0gbmFtZXNwYWNlXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyVHJhbnNsYXRpb25OYW1lc3BhY2UobmFtZXNwYWNlKSB7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbbmFtZXNwYWNlXTogdHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWFcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGRlZmluZXMgYSBjb25maWd1cmF0aW9uIHNjaGVtYSBmb3IgYW4gZXh0ZW5zaW9uLiBXaGVuIGEgc2NoZW1hIGlzIGRlZmluZWRcbiAqIGZvciBhbiBleHRlbnNpb24sIHRoYXQgZXh0ZW5zaW9uIHdpbGwgcmVjZWl2ZSB0aGUgY29uZmlndXJhdGlvbiBjb3JyZXNwb25kaW5nXG4gKiB0byB0aGF0IHNjaGVtYSwgcmF0aGVyIHRoYW4gdGhlIGNvbmZpZ3VyYXRpb24gY29ycmVzcG9uZGluZyB0byB0aGUgbW9kdWxlXG4gKiBpbiB3aGljaCBpdCBpcyBkZWZpbmVkLlxuICpcbiAqIFRoZSBzY2hlbWEgdGVsbHMgdGhlIGNvbmZpZ3VyYXRpb24gc3lzdGVtIGhvdyB0aGUgbW9kdWxlIGNhbiBiZSBjb25maWd1cmVkLlxuICogSXQgc3BlY2lmaWVzIHdoYXQgbWFrZXMgY29uZmlndXJhdGlvbiB2YWxpZCBvciBpbnZhbGlkLlxuICpcbiAqIFNlZSBbQ29uZmlndXJhdGlvbiBTeXN0ZW1dKGh0dHBzOi8vbzMtZG9jcy5vcGVubXJzLm9yZy9lbi1VUy9kb2NzL2NvbmZpZ3VyYXRpb24tc3lzdGVtKVxuICogZm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgZGVmaW5pbmcgYSBjb25maWcgc2NoZW1hLlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25OYW1lIE5hbWUgb2YgdGhlIGV4dGVuc2lvbiB0aGUgc2NoZW1hIGlzIGJlaW5nIGRlZmluZWQgZm9yLlxuICogICBTaG91bGQgbWF0Y2ggdGhlIGBuYW1lYCBvZiBvbmUgb2YgdGhlIGBleHRlbnNpb25zYCBlbnRyaWVzIGRlZmluZWQgaW5cbiAqICAgdGhlIGFwcCdzIGByb3V0ZXMuanNvbmAgZmlsZS5cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIGNvbmZpZyBzY2hlbWEgZm9yIHRoZSBleHRlbnNpb25cbiAqLyBleHBvcnQgZnVuY3Rpb24gZGVmaW5lRXh0ZW5zaW9uQ29uZmlnU2NoZW1hKGV4dGVuc2lvbk5hbWUsIHNjaGVtYSkge1xuICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKGV4dGVuc2lvbk5hbWUsIHNjaGVtYSk7XG4gICAgY29uc3QgZW5oYW5jZWRTY2hlbWEgPSBtZXJnZURlZXBSZXBsYWNlKHNjaGVtYSwgaW1wbGljaXRDb25maWdTY2hlbWEpO1xuICAgIGNvbnN0IHN0YXRlID0gY29uZmlnSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGlmIChzdGF0ZS5zY2hlbWFzW2V4dGVuc2lvbk5hbWVdKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoYENvbmZpZyBzY2hlbWEgZm9yIGV4dGVuc2lvbiAke2V4dGVuc2lvbk5hbWV9IGFscmVhZHkgZXhpc3RzLiBJZiB0aGVyZSBhcmUgbXVsdGlwbGUgZXh0ZW5zaW9ucyB3aXRoIHRoaXMgc2FtZSBuYW1lLCBvbmUgd2lsbCBwcm9iYWJseSBjcmFzaC5gKTtcbiAgICB9XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbZXh0ZW5zaW9uTmFtZV06IGVuaGFuY2VkU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogUHJvdmlkZXMgY29uZmlndXJhdGlvbiB2YWx1ZXMgcHJvZ3JhbW1hdGljYWxseS4gVGhpcyBpcyBhbiBhbHRlcm5hdGl2ZSB0b1xuICogcHJvdmlkaW5nIGNvbmZpZ3VyYXRpb24gdGhyb3VnaCB0aGUgY29uZmlnLWZpbGUuIENvbmZpZ3VyYXRpb24gcHJvdmlkZWQgdGhpc1xuICogd2F5IHdpbGwgYmUgbWVyZ2VkIHdpdGggY29uZmlndXJhdGlvbiBmcm9tIG90aGVyIHNvdXJjZXMuXG4gKlxuICogQHBhcmFtIGNvbmZpZyBBIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHRvIG1lcmdlIGludG8gdGhlIGV4aXN0aW5nIGNvbmZpZ3VyYXRpb24uXG4gKiBAcGFyYW0gc291cmNlTmFtZSBBbiBvcHRpb25hbCBuYW1lIHRvIGlkZW50aWZ5IHRoZSBzb3VyY2Ugb2YgdGhpcyBjb25maWd1cmF0aW9uLFxuICogICB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuIERlZmF1bHRzIHRvICdwcm92aWRlZCcuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHByb3ZpZGUoY29uZmlnLCBzb3VyY2VOYW1lID0gJ3Byb3ZpZGVkJykge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgcHJvdmlkZWRDb25maWdzOiBbXG4gICAgICAgICAgICAgICAgLi4uc3RhdGUucHJvdmlkZWRDb25maWdzLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiBzb3VyY2VOYW1lLFxuICAgICAgICAgICAgICAgICAgICBjb25maWdcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogUmVzb2x2ZXMgd2l0aCBgc2VsZWN0KHN0YXRlKWAgYXMgc29vbiBhcyB0aGUgc3RvcmUncyBzdGF0ZSBzYXRpc2ZpZXMgYHJlYWR5YCwgbGVhdmluZyBub1xuICogc3Vic2NyaXB0aW9uIGJlaGluZDogbm90aGluZyBzdWJzY3JpYmVzIGF0IGFsbCB3aGVuIHRoZSBzdG9yZSBpcyBhbHJlYWR5IHJlYWR5LiBUaGF0IG1hdHRlcnNcbiAqIGJlY2F1c2UgYGdldENvbmZpZ2AgcnVucyBvbiBldmVyeSBIVFRQIHJlcXVlc3QsIGFuZCBhIHN1YnNjcmlwdGlvbiB0aGF0IG91dGxpdmVzIGl0cyBwcm9taXNlXG4gKiBib3RoIHJldGFpbnMgaXRzIGNsb3N1cmUgZm9yZXZlciBhbmQgc2xvd3MgZG93biBldmVyeSBsYXRlciB3cml0ZSB0byB0aGF0IHN0b3JlLlxuICovIGZ1bmN0aW9uIHdoZW5TdG9yZVJlYWR5KHN0b3JlLCByZWFkeSwgc2VsZWN0KSB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlKT0+e1xuICAgICAgICBsZXQgdW5zdWJzY3JpYmU7XG4gICAgICAgIGxldCByZXNvbHZlZCA9IGZhbHNlO1xuICAgICAgICBmdW5jdGlvbiB1cGRhdGUoc3RhdGUpIHtcbiAgICAgICAgICAgIGlmICghcmVzb2x2ZWQgJiYgcmVhZHkoc3RhdGUpKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJlc29sdmUoc2VsZWN0KHN0YXRlKSk7XG4gICAgICAgICAgICAgICAgdW5zdWJzY3JpYmU/LigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHVwZGF0ZShzdG9yZS5nZXRTdGF0ZSgpKTtcbiAgICAgICAgaWYgKCFyZXNvbHZlZCkge1xuICAgICAgICAgICAgdW5zdWJzY3JpYmUgPSBzdG9yZS5zdWJzY3JpYmUodXBkYXRlKTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBBIHByb21pc2UtYmFzZWQgd2F5IHRvIGFjY2VzcyB0aGUgY29uZmlnIGFzIHNvb24gYXMgaXQgaXMgZnVsbHkgbG9hZGVkLlxuICogSWYgaXQgaXMgYWxyZWFkeSBsb2FkZWQsIHJlc29sdmVzIHRoZSBjb25maWcgaW4gaXRzIHByZXNlbnQgc3RhdGUuXG4gKlxuICogVGhpcyBpcyBhIHVzZWZ1bCBmdW5jdGlvbiBpZiB5b3UgbmVlZCB0byBnZXQgdGhlIGNvbmZpZyBpbiB0aGUgY291cnNlXG4gKiBvZiB0aGUgZXhlY3V0aW9uIG9mIGEgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSBmb3Igd2hpY2ggdG8gbG9vayB1cCB0aGUgY29uZmlnXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGdldENvbmZpZyhtb2R1bGVOYW1lKSB7XG4gICAgcmV0dXJuIHdoZW5TdG9yZVJlYWR5KGdldENvbmZpZ1N0b3JlKG1vZHVsZU5hbWUpLCAoc3RhdGUpPT5Cb29sZWFuKHN0YXRlLmxvYWRlZCAmJiBzdGF0ZS5jb25maWcpLCAoc3RhdGUpPT5sb2Rhc2hPbWl0KHN0YXRlLmNvbmZpZywgW1xuICAgICAgICAgICAgJ0Rpc3BsYXkgY29uZGl0aW9ucycsXG4gICAgICAgICAgICAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJ1xuICAgICAgICBdKSk7XG59XG4vKipcbiAqIFJldHJpZXZlcyB0cmFuc2xhdGlvbiBvdmVycmlkZXMgZm9yIGFuIGV4dGVuc2lvbiwgb3B0aW9uYWxseSBzY29wZWQgdG8gYSBzcGVjaWZpY1xuICogZXh0ZW5zaW9uIHNsb3QuIFdoZW4gY2FsbGVkIHdpdGggb25seSBhIG1vZHVsZSBuYW1lLCByZXRyaWV2ZXMgbW9kdWxlLWxldmVsIG92ZXJyaWRlcy5cbiAqIFRyYW5zbGF0aW9uIG92ZXJyaWRlcyBhbGxvdyBjdXN0b21pemluZyB0cmFuc2xhdGVkIHN0cmluZ3Mgd2l0aG91dCBtb2RpZnlpbmcgdGhlXG4gKiBvcmlnaW5hbCB0cmFuc2xhdGlvbiBmaWxlcy5cbiAqXG4gKiBAcGFyYW0gbW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHByb3ZpZGluZyB0aGUgdHJhbnNsYXRpb24gY29udGV4dC5cbiAqIEBwYXJhbSBzbG90TmFtZSBPcHRpb25hbCBleHRlbnNpb24gc2xvdCBuYW1lIHRvIGluY2x1ZGUgc2xvdC1zcGVjaWZpYyBvdmVycmlkZXMuXG4gKiBAcGFyYW0gZXh0ZW5zaW9uSWQgT3B0aW9uYWwgZXh0ZW5zaW9uIElEIHRvIGluY2x1ZGUgZXh0ZW5zaW9uLXNwZWNpZmljIG92ZXJyaWRlcy5cbiAqIEByZXR1cm5zIEEgUHJvbWlzZSByZXNvbHZpbmcgdG8gYW4gYXJyYXkgb2YgdHJhbnNsYXRpb24gb3ZlcnJpZGUgb2JqZWN0cy5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0VHJhbnNsYXRpb25PdmVycmlkZXMobW9kdWxlTmFtZSwgc2xvdE5hbWUsIGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3QgcHJvbWlzZXMgPSBbXG4gICAgICAgIHdoZW5TdG9yZVJlYWR5KGdldENvbmZpZ1N0b3JlKG1vZHVsZU5hbWUpLCAoc3RhdGUpPT5Cb29sZWFuKHN0YXRlLnRyYW5zbGF0aW9uT3ZlcnJpZGVzTG9hZGVkICYmIHN0YXRlLmNvbmZpZyksIChzdGF0ZSk9PnN0YXRlLmNvbmZpZ1snVHJhbnNsYXRpb24gb3ZlcnJpZGVzJ10gPz8ge30pXG4gICAgXTtcbiAgICBpZiAoc2xvdE5hbWUgJiYgZXh0ZW5zaW9uSWQpIHtcbiAgICAgICAgcHJvbWlzZXMucHVzaCh3aGVuU3RvcmVSZWFkeShnZXRFeHRlbnNpb25Db25maWcoc2xvdE5hbWUsIGV4dGVuc2lvbklkKSwgKHN0YXRlKT0+Qm9vbGVhbihzdGF0ZS5sb2FkZWQgJiYgc3RhdGUuY29uZmlnKSwgKHN0YXRlKT0+c3RhdGUuY29uZmlnWydUcmFuc2xhdGlvbiBvdmVycmlkZXMnXSA/PyB7fSkpO1xuICAgIH1cbiAgICByZXR1cm4gUHJvbWlzZS5hbGwocHJvbWlzZXMpO1xufVxuLyoqXG4gKiBWYWxpZGF0ZSBhbmQgaW50ZXJwb2xhdGUgZGVmYXVsdHMgZm9yIGBwcm92aWRlZENvbmZpZ2AgYWNjb3JkaW5nIHRvIGBzY2hlbWFgXG4gKlxuICogQHBhcmFtIHNjaGVtYSAgYSBjb25maWd1cmF0aW9uIHNjaGVtYVxuICogQHBhcmFtIHByb3ZpZGVkQ29uZmlnICBhbiBvYmplY3Qgb2YgY29uZmlnIHZhbHVlcyAod2l0aG91dCB0aGUgdG9wLWxldmVsIG1vZHVsZSBuYW1lKVxuICogQHBhcmFtIGtleVBhdGhDb250ZXh0ICBhIGRvdC1zZXBhcmF0ZWQgc3RyaW5nIHdoaWNoIGhlbHBzIHRoZSB1c2VyIGZpZ3VyZSBvdXQgd2hlcmVcbiAqICAgICB0aGUgcHJvdmlkZWQgY29uZmlnIGNhbWUgZnJvbVxuICogQHJldHVybnMgVGhlIHZhbGlkYXRlZCBhbmQgcHJvY2Vzc2VkIGNvbmZpZ3VyYXRpb24gb2JqZWN0IHdpdGggZGVmYXVsdHMgYXBwbGllZC5cbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBmdW5jdGlvbiBwcm9jZXNzQ29uZmlnKHNjaGVtYSwgcHJvdmlkZWRDb25maWcsIGtleVBhdGhDb250ZXh0KSB7XG4gICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBwcm92aWRlZENvbmZpZywga2V5UGF0aENvbnRleHQpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgcHJvdmlkZWRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIGtleVBhdGhDb250ZXh0KTtcbiAgICByZXR1cm4gY29uZmlnO1xufVxuY29uc3QgZXh0ZW5zaW9uQ29uZmlnQ2FjaGUgPSBuZXcgTWFwKCk7XG4vKipcbiAqIFJldHVybnMgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIGFuIGV4dGVuc2lvbi4gVGhpcyBjb25maWd1cmF0aW9uIGlzIHNwZWNpZmljXG4gKiB0byB0aGUgc2xvdCBpbiB3aGljaCBpdCBpcyBtb3VudGVkLCBhbmQgaXRzIElEIHdpdGhpbiB0aGF0IHNsb3QuXG4gKlxuICogVGhlIHNjaGVtYSBmb3IgdGhhdCBjb25maWd1cmF0aW9uIGlzIHRoZSBleHRlbnNpb24gc2NoZW1hLiBJZiBubyBleHRlbnNpb25cbiAqIHNjaGVtYSBoYXMgYmVlbiBwcm92aWRlZCwgdGhlIHNjaGVtYSB1c2VkIGlzIHRoZSBzY2hlbWEgb2YgdGhlIG1vZHVsZSBpblxuICogd2hpY2ggdGhlIGV4dGVuc2lvbiBpcyBkZWZpbmVkLlxuICpcbiAqIEBwYXJhbSBzbG90TW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHdoaWNoIGRlZmluZXMgdGhlIGV4dGVuc2lvbiBzbG90XG4gKiBAcGFyYW0gZXh0ZW5zaW9uTW9kdWxlTmFtZSBUaGUgbmFtZSBvZiB0aGUgbW9kdWxlIHdoaWNoIGRlZmluZXMgdGhlIGV4dGVuc2lvbiAoYW5kIHRoZXJlZm9yZSB0aGUgY29uZmlnIHNjaGVtYSlcbiAqIEBwYXJhbSBzbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3Qgd2hlcmUgdGhlIGV4dGVuc2lvbiBpcyBtb3VudGVkXG4gKiBAcGFyYW0gZXh0ZW5zaW9uSWQgVGhlIElEIG9mIHRoZSBleHRlbnNpb24gaW4gaXRzIHNsb3RcbiAqIEBwYXJhbSBzbG90Q29uZmlnIFRoZSBzbG90J3MgY29uZmlndXJhdGlvbiwgZ2F0aGVyZWQgZnJvbSBldmVyeSBtb2R1bGUgdGhhdCBjb25maWd1cmVzIGl0XG4gKi8gZnVuY3Rpb24gY29tcHV0ZUV4dGVuc2lvbkNvbmZpZyhzbG90TW9kdWxlTmFtZSwgZXh0ZW5zaW9uTW9kdWxlTmFtZSwgc2xvdE5hbWUsIGV4dGVuc2lvbklkLCBjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlLCBzbG90Q29uZmlnKSB7XG4gICAgY29uc3QgZXh0ZW5zaW9uTmFtZSA9IGdldEV4dGVuc2lvbk5hbWVGcm9tSWQoZXh0ZW5zaW9uSWQpO1xuICAgIGNvbnN0IGV4dGVuc2lvbkNvbmZpZ1NjaGVtYSA9IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTmFtZV07XG4gICAgLy8gSlNPTiBzdHJpbmcgb2YgdGhlc2UgZWxlbWVudHMgc2hvdWxkIGJlIHVuaXF1ZS1wZXItZXh0ZW5zaW9uXG4gICAgY29uc3QgY2FjaGVLZXkgPSBKU09OLnN0cmluZ2lmeShbXG4gICAgICAgIHNsb3ROYW1lLFxuICAgICAgICBleHRlbnNpb25JZCxcbiAgICAgICAgc2xvdE1vZHVsZU5hbWUsXG4gICAgICAgIGV4dGVuc2lvbk1vZHVsZU5hbWVcbiAgICBdKTtcbiAgICBjb25zdCBjYWNoZWQgPSBleHRlbnNpb25Db25maWdDYWNoZS5nZXQoY2FjaGVLZXkpO1xuICAgIGlmIChjYWNoZWQgJiYgY2FjaGVkLmV4dGVuc2lvblNjaGVtYSA9PT0gZXh0ZW5zaW9uQ29uZmlnU2NoZW1hICYmIGNhY2hlZC5leHRlbnNpb25Nb2R1bGVTY2hlbWEgPT09IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTW9kdWxlTmFtZV0gJiYgY2FjaGVkLnByb3ZpZGVkQ29uZmlncyA9PT0gY29uZmlnU3RhdGUucHJvdmlkZWRDb25maWdzICYmIGNhY2hlZC50ZW1wb3JhcnlDb25maWcgPT09IHRlbXBDb25maWdTdGF0ZS5jb25maWcpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlZC5jb25maWc7XG4gICAgfVxuICAgIGNvbnN0IG5hbWVPZlNjaGVtYVNvdXJjZSA9IGV4dGVuc2lvbkNvbmZpZ1NjaGVtYSA/IGV4dGVuc2lvbk5hbWUgOiBleHRlbnNpb25Nb2R1bGVOYW1lO1xuICAgIGNvbnN0IHByb3ZpZGVkQ29uZmlncyA9IGdldFByb3ZpZGVkQ29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKTtcbiAgICBjb25zdCBzaGFyZWRPdmVycmlkZSA9IHNsb3RDb25maWc/LmNvbmZpZ3VyZT8uW2V4dGVuc2lvbklkXSA/PyB7fTtcbiAgICBjb25zdCBzbG90TW9kdWxlQ29uZmlnID0gbWVyZ2VDb25maWdzRm9yKHNsb3RNb2R1bGVOYW1lLCBwcm92aWRlZENvbmZpZ3MpO1xuICAgIGNvbnN0IGNvbmZpZ092ZXJyaWRlID0gc2xvdE1vZHVsZUNvbmZpZz8uZXh0ZW5zaW9uU2xvdHM/LltzbG90TmFtZV0/LmNvbmZpZ3VyZT8uW2V4dGVuc2lvbklkXSA/PyB7fTtcbiAgICBjb25zdCBleHRlbnNpb25Db25maWcgPSBtZXJnZUNvbmZpZ3NGb3IobmFtZU9mU2NoZW1hU291cmNlLCBwcm92aWRlZENvbmZpZ3MpO1xuICAgIGNvbnN0IGNvbWJpbmVkQ29uZmlnID0gbWVyZ2VDb25maWdzKFtcbiAgICAgICAgZXh0ZW5zaW9uQ29uZmlnLFxuICAgICAgICBzaGFyZWRPdmVycmlkZSxcbiAgICAgICAgY29uZmlnT3ZlcnJpZGVcbiAgICBdKTtcbiAgICBjb25zdCBzY2hlbWEgPSBleHRlbnNpb25Db25maWdTY2hlbWEgPz8gY29uZmlnU3RhdGUuc2NoZW1hc1tleHRlbnNpb25Nb2R1bGVOYW1lXTtcbiAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWEsIGNvbWJpbmVkQ29uZmlnLCBuYW1lT2ZTY2hlbWFTb3VyY2UpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgY29tYmluZWRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIG5hbWVPZlNjaGVtYVNvdXJjZSk7XG4gICAgZGVsZXRlIGNvbmZpZy5leHRlbnNpb25TbG90cztcbiAgICBleHRlbnNpb25Db25maWdDYWNoZS5zZXQoY2FjaGVLZXksIHtcbiAgICAgICAgZXh0ZW5zaW9uU2NoZW1hOiBleHRlbnNpb25Db25maWdTY2hlbWEsXG4gICAgICAgIGV4dGVuc2lvbk1vZHVsZVNjaGVtYTogY29uZmlnU3RhdGUuc2NoZW1hc1tleHRlbnNpb25Nb2R1bGVOYW1lXSxcbiAgICAgICAgcHJvdmlkZWRDb25maWdzOiBjb25maWdTdGF0ZS5wcm92aWRlZENvbmZpZ3MsXG4gICAgICAgIHRlbXBvcmFyeUNvbmZpZzogdGVtcENvbmZpZ1N0YXRlLmNvbmZpZyxcbiAgICAgICAgY29uZmlnXG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmNvbnN0IGltcGxlbWVudGVyVG9vbHNNb2R1bGVDYWNoZSA9IG5ldyBNYXAoKTtcbmZ1bmN0aW9uIGdldEltcGxlbWVudGVyVG9vbHNDb25maWcoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIGNvbnN0IGFubm90YXRlZFNjaGVtYXMgPSBnZXRBbGxTY2hlbWFzV2l0aFZhbHVlc0FuZFNvdXJjZXMoY29uZmlnU3RhdGUuc2NoZW1hcyk7XG4gICAgY29uc3QgY29uZmlnc0FuZFNvdXJjZXMgPSBbXG4gICAgICAgIC4uLmNvbmZpZ1N0YXRlLnByb3ZpZGVkQ29uZmlncy5tYXAoKGMpPT5bXG4gICAgICAgICAgICAgICAgYy5jb25maWcsXG4gICAgICAgICAgICAgICAgYy5zb3VyY2VcbiAgICAgICAgICAgIF0pLFxuICAgICAgICBbXG4gICAgICAgICAgICB0ZW1wQ29uZmlnU3RhdGUuY29uZmlnLFxuICAgICAgICAgICAgJ3RlbXBvcmFyeSBjb25maWcnXG4gICAgICAgIF1cbiAgICBdO1xuICAgIC8vIEEgbW9kdWxlIGNhbiBiZSBjb25maWd1cmVkIHdpdGhvdXQgaGF2aW5nIGRlY2xhcmVkIGEgc2NoZW1hLCBzbyB0aGUgbW9kdWxlIGxpc3QgaXMgdGhlIHVuaW9uXG4gICAgLy8gb2YgYm90aCByYXRoZXIgdGhhbiBqdXN0IHRoZSBzY2hlbWFzLlxuICAgIGNvbnN0IG1vZHVsZU5hbWVzID0gbmV3IFNldChPYmplY3Qua2V5cyhhbm5vdGF0ZWRTY2hlbWFzKSk7XG4gICAgZm9yIChjb25zdCBbY29uZmlnXSBvZiBjb25maWdzQW5kU291cmNlcyl7XG4gICAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBvZiBPYmplY3Qua2V5cyhjb25maWcpKXtcbiAgICAgICAgICAgIG1vZHVsZU5hbWVzLmFkZChtb2R1bGVOYW1lKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgb2YgbW9kdWxlTmFtZXMpe1xuICAgICAgICBjb25zdCBhbm5vdGF0ZWRTY2hlbWEgPSBhbm5vdGF0ZWRTY2hlbWFzW21vZHVsZU5hbWVdO1xuICAgICAgICBjb25zdCBjb25maWdTbGljZXMgPSBjb25maWdzQW5kU291cmNlcy5tYXAoKFtjb25maWddKT0+Y29uZmlnW21vZHVsZU5hbWVdKTtcbiAgICAgICAgY29uc3Qgc291cmNlcyA9IGNvbmZpZ3NBbmRTb3VyY2VzLm1hcCgoWywgc291cmNlXSk9PnNvdXJjZSk7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IGltcGxlbWVudGVyVG9vbHNNb2R1bGVDYWNoZS5nZXQobW9kdWxlTmFtZSk7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgY2FjaGVkLmFubm90YXRlZFNjaGVtYSA9PT0gYW5ub3RhdGVkU2NoZW1hICYmIGNhY2hlZC5jb25maWdTbGljZXMubGVuZ3RoID09PSBjb25maWdTbGljZXMubGVuZ3RoICYmIGNhY2hlZC5jb25maWdTbGljZXMuZXZlcnkoKHNsaWNlLCBpKT0+c2xpY2UgPT09IGNvbmZpZ1NsaWNlc1tpXSkgJiYgY2FjaGVkLnNvdXJjZXMuZXZlcnkoKHNvdXJjZSwgaSk9PnNvdXJjZSA9PT0gc291cmNlc1tpXSkpIHtcbiAgICAgICAgICAgIHJlc3VsdFttb2R1bGVOYW1lXSA9IGNhY2hlZC5yZXN1bHQ7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbWVyZ2VkID0gYW5ub3RhdGVkU2NoZW1hID8/IHt9O1xuICAgICAgICBjb25maWdzQW5kU291cmNlcy5mb3JFYWNoKChbLCBzb3VyY2VdLCBpKT0+e1xuICAgICAgICAgICAgY29uc3Qgc2xpY2UgPSBjb25maWdTbGljZXNbaV07XG4gICAgICAgICAgICBpZiAoc2xpY2UgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIG1lcmdlZCA9IG1lcmdlRGVlcFJlcGxhY2UobWVyZ2VkLCBjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZShzbGljZSwgc291cmNlKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpbXBsZW1lbnRlclRvb2xzTW9kdWxlQ2FjaGUuc2V0KG1vZHVsZU5hbWUsIHtcbiAgICAgICAgICAgIGFubm90YXRlZFNjaGVtYSxcbiAgICAgICAgICAgIGNvbmZpZ1NsaWNlcyxcbiAgICAgICAgICAgIHNvdXJjZXMsXG4gICAgICAgICAgICByZXN1bHQ6IG1lcmdlZFxuICAgICAgICB9KTtcbiAgICAgICAgcmVzdWx0W21vZHVsZU5hbWVdID0gbWVyZ2VkO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBDYWNoaW5nIHBlciBtb2R1bGUgaXMgd2hhdCBzdG9wcyB0aGUgd2FsayBiZWluZyBxdWFkcmF0aWM6IGRlZmluaW5nIG9uZSBtb2R1bGUncyBzY2hlbWFcbiAqIHJlY29tcHV0ZXMgZXZlcnkgbW9kdWxlLlxuICpcbiAqIEEgbW9kdWxlIHdpdGggbm8gY29uZmlndXJhdGlvbiBvZiBpdHMgb3duIGlzIHB1Ymxpc2hlZCBzdHJhaWdodCBmcm9tIHRoaXMgY2FjaGUsIHNvIG5vdGhpbmcgbWF5XG4gKiBtdXRhdGUgYSB0cmVlIGl0IHJlYWRzIG91dCBvZiB0aGUgaW1wbGVtZW50ZXIgdG9vbHMgY29uZmlnIOKAlCBpdCBpcyB0aGUgY2FjaGUgZW50cnkuXG4gKi8gY29uc3Qgc2NoZW1hVmFsdWVzQW5kU291cmNlc0NhY2hlID0gbmV3IE1hcCgpO1xuZnVuY3Rpb24gZ2V0QWxsU2NoZW1hc1dpdGhWYWx1ZXNBbmRTb3VyY2VzKHNjaGVtYXMpIHtcbiAgICBjb25zdCByZXN1bHQgPSB7fTtcbiAgICBmb3IgKGNvbnN0IFttb2R1bGVOYW1lLCBzY2hlbWFdIG9mIE9iamVjdC5lbnRyaWVzKHNjaGVtYXMpKXtcbiAgICAgICAgY29uc3QgY2FjaGVkID0gc2NoZW1hVmFsdWVzQW5kU291cmNlc0NhY2hlLmdldChtb2R1bGVOYW1lKTtcbiAgICAgICAgaWYgKGNhY2hlZCAmJiBjYWNoZWQuc2NoZW1hID09PSBzY2hlbWEpIHtcbiAgICAgICAgICAgIHJlc3VsdFttb2R1bGVOYW1lXSA9IGNhY2hlZC5hbm5vdGF0ZWQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBhbm5vdGF0ZWQgPSBnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyhjbG9uZURlZXAoc2NoZW1hKSk7XG4gICAgICAgICAgICBzY2hlbWFWYWx1ZXNBbmRTb3VyY2VzQ2FjaGUuc2V0KG1vZHVsZU5hbWUsIHtcbiAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgYW5ub3RhdGVkXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlc3VsdFttb2R1bGVOYW1lXSA9IGFubm90YXRlZDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuZnVuY3Rpb24gZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMoc2NoZW1hKSB7XG4gICAgaWYgKHNjaGVtYS5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uc2NoZW1hLFxuICAgICAgICAgICAgX3ZhbHVlOiBzY2hlbWEuX2RlZmF1bHQsXG4gICAgICAgICAgICBfc291cmNlOiAnZGVmYXVsdCdcbiAgICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKGlzT3JkaW5hcnlPYmplY3Qoc2NoZW1hKSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoc2NoZW1hKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICAgICAgb2JqW2tleV0gPSBnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyhzY2hlbWFba2V5XSk7XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gYXQgdGhpcyBwb2ludCwgdGhlIHNjaGVtYSBpcyBiYWQgYW5kIGFuIGVycm9yIHdpbGwgaGF2ZSBiZWVuIGxvZ2dlZCBkdXJpbmcgc2NoZW1hIHZhbGlkYXRpb25cbiAgICAgICAgcmV0dXJuIHt9O1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNyZWF0ZVZhbHVlc0FuZFNvdXJjZXNUcmVlKGNvbmZpZywgc291cmNlKSB7XG4gICAgaWYgKGlzT3JkaW5hcnlPYmplY3QoY29uZmlnKSkge1xuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXMoY29uZmlnKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICAgICAgb2JqW2tleV0gPSBjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZShjb25maWdba2V5XSwgc291cmNlKTtcbiAgICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH0sIHt9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgX3ZhbHVlOiBjb25maWcsXG4gICAgICAgICAgICBfc291cmNlOiBzb3VyY2VcbiAgICAgICAgfTtcbiAgICB9XG59XG5mdW5jdGlvbiBnZXRFeHRlbnNpb25TbG90Q29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3QgYWxsQ29uZmlncyA9IG1lcmdlQ29uZmlncyhnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIGNvbnN0IHNsb3RDb25maWdQZXJNb2R1bGUgPSBPYmplY3Qua2V5cyhhbGxDb25maWdzKS5yZWR1Y2UoKG9iaiwga2V5KT0+e1xuICAgICAgICBpZiAoYWxsQ29uZmlnc1trZXldPy5leHRlbnNpb25TbG90cykge1xuICAgICAgICAgICAgb2JqW2tleV0gPSBhbGxDb25maWdzW2tleV0/LmV4dGVuc2lvblNsb3RzO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBvYmo7XG4gICAgfSwge30pO1xuICAgIHZhbGlkYXRlQWxsRXh0ZW5zaW9uU2xvdENvbmZpZ3Moc2xvdENvbmZpZ1Blck1vZHVsZSk7XG4gICAgY29uc3Qgc2xvdENvbmZpZ3MgPSB7fTtcbiAgICBjb25zdCBjb25maWd1cmVCbG9ja3MgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGNvbmZpZ0J5U2xvdE5hbWUgb2YgT2JqZWN0LnZhbHVlcyhzbG90Q29uZmlnUGVyTW9kdWxlKSl7XG4gICAgICAgIGZvciAoY29uc3QgW3Nsb3ROYW1lLCBjb25maWddIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZ0J5U2xvdE5hbWUpKXtcbiAgICAgICAgICAgIHNsb3RDb25maWdzW3Nsb3ROYW1lXSA9IGNvbmZpZztcbiAgICAgICAgICAgIGlmIChjb25maWcuY29uZmlndXJlKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9jb25maWd1cmVCbG9ja3MsIF9zbG90TmFtZTtcbiAgICAgICAgICAgICAgICAoKF9jb25maWd1cmVCbG9ja3MgPSBjb25maWd1cmVCbG9ja3MpW19zbG90TmFtZSA9IHNsb3ROYW1lXSA/PyAoX2NvbmZpZ3VyZUJsb2Nrc1tfc2xvdE5hbWVdID0gW10pKS5wdXNoKGNvbmZpZy5jb25maWd1cmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3QgW3Nsb3ROYW1lLCBibG9ja3NdIG9mIE9iamVjdC5lbnRyaWVzKGNvbmZpZ3VyZUJsb2Nrcykpe1xuICAgICAgICBjb25zdCBjb25maWd1cmUgPSBibG9ja3MubGVuZ3RoID09PSAxID8gYmxvY2tzWzBdIDogbWVyZ2VDb25maWdzKGJsb2Nrcyk7XG4gICAgICAgIGlmIChzbG90Q29uZmlnc1tzbG90TmFtZV0uY29uZmlndXJlICE9PSBjb25maWd1cmUpIHtcbiAgICAgICAgICAgIHNsb3RDb25maWdzW3Nsb3ROYW1lXSA9IHtcbiAgICAgICAgICAgICAgICAuLi5zbG90Q29uZmlnc1tzbG90TmFtZV0sXG4gICAgICAgICAgICAgICAgY29uZmlndXJlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzbG90Q29uZmlncztcbn1cbmZ1bmN0aW9uIHZhbGlkYXRlQWxsRXh0ZW5zaW9uU2xvdENvbmZpZ3Moc2xvdENvbmZpZ1Blck1vZHVsZSkge1xuICAgIGZvciAobGV0IFttb2R1bGVOYW1lLCBjb25maWdCeVNsb3ROYW1lXSBvZiBPYmplY3QuZW50cmllcyhzbG90Q29uZmlnUGVyTW9kdWxlKSl7XG4gICAgICAgIGZvciAobGV0IFtzbG90TmFtZSwgY29uZmlnXSBvZiBPYmplY3QuZW50cmllcyhjb25maWdCeVNsb3ROYW1lKSl7XG4gICAgICAgICAgICB2YWxpZGF0ZUV4dGVuc2lvblNsb3RDb25maWcoY29uZmlnLCBtb2R1bGVOYW1lLCBzbG90TmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUV4dGVuc2lvblNsb3RDb25maWcoY29uZmlnLCBtb2R1bGVOYW1lLCBzbG90TmFtZSkge1xuICAgIGNvbnN0IGtleVBhdGggPSBgJHttb2R1bGVOYW1lfS5leHRlbnNpb25TbG90cy4ke3Nsb3ROYW1lfWA7XG4gICAgY29uc3QgZXJyb3JQcmVmaXggPSBgRXh0ZW5zaW9uIHNsb3QgY29uZmlnICcke2tleVBhdGh9J2A7XG4gICAgY29uc3QgaW52YWxpZEtleXMgPSBPYmplY3Qua2V5cyhjb25maWcpLmZpbHRlcigoayk9PiFbXG4gICAgICAgICAgICAnYWRkJyxcbiAgICAgICAgICAgICdyZW1vdmUnLFxuICAgICAgICAgICAgJ29yZGVyJyxcbiAgICAgICAgICAgICdjb25maWd1cmUnXG4gICAgICAgIF0uaW5jbHVkZXMoaykpO1xuICAgIGlmIChpbnZhbGlkS2V5cy5sZW5ndGgpIHtcbiAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgJyBjb250YWlucyBpbnZhbGlkIGtleXMgJyR7aW52YWxpZEtleXMuam9pbihcIicsICdcIil9J2ApO1xuICAgIH1cbiAgICBpZiAoY29uZmlnLmFkZCkge1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkoY29uZmlnLmFkZCkgfHwgIWNvbmZpZy5hZGQuZXZlcnkoKG4pPT50eXBlb2YgbiA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAuYWRkJyBpcyBpbnZhbGlkLiBNdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3MgKGV4dGVuc2lvbiBJRHMpYCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNvbmZpZy5yZW1vdmUpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbmZpZy5yZW1vdmUpIHx8ICFjb25maWcucmVtb3ZlLmV2ZXJ5KChuKT0+dHlwZW9mIG4gPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgLnJlbW92ZScgaXMgaW52YWxpZC4gTXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIChleHRlbnNpb24gSURzKWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChjb25maWcub3JkZXIpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbmZpZy5vcmRlcikgfHwgIWNvbmZpZy5vcmRlci5ldmVyeSgobik9PnR5cGVvZiBuID09PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5vcmRlcicgaXMgaW52YWxpZC4gTXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIChleHRlbnNpb24gSURzKWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChjb25maWcuY29uZmlndXJlKSB7XG4gICAgICAgIGlmICghaXNPcmRpbmFyeU9iamVjdChjb25maWcuY29uZmlndXJlKSkge1xuICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgLmNvbmZpZ3VyZScgaXMgaW52YWxpZC4gTXVzdCBiZSBhbiBvYmplY3Qgd2l0aCBleHRlbnNpb24gSURzIGZvciBrZXlzYCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIHJldHVybiBbXG4gICAgICAgIC4uLmNvbmZpZ1N0YXRlLnByb3ZpZGVkQ29uZmlncy5tYXAoKGMpPT5jLmNvbmZpZyksXG4gICAgICAgIHRlbXBDb25maWdTdGF0ZS5jb25maWdcbiAgICBdO1xufVxuLyoqXG4gKiBWYWxpZGF0ZXMgdGhlIGNvbmZpZyBzY2hlbWEgZm9yIGEgbW9kdWxlLiBTaW5jZSBwcm9ibGVtcyBpZGVudGlmaWVkIGhlcmUgYXJlIHByb2dyYW1taW5nIGVycm9yc1xuICogdGhhdCBob3BlZnVsbHkgd2lsbCBiZSBjYXVnaHQgZHVyaW5nIGRldmVsb3BtZW50LCB0aGlzIGZ1bmN0aW9uIGxvZ3MgZXJyb3JzIHRvIHRoZSBjb25zb2xlIGRpcmVjdGx5O1xuICogaXQncyBmaW5lIGlmIHdlIHNwYW0gdGhlIHVzZXIgd2l0aCB0aGVzZSBlcnJvcnMuXG4gKi8gZnVuY3Rpb24gdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hLCBrZXlQYXRoID0gJycpIHtcbiAgICBjb25zdCB1cGRhdGVNZXNzYWdlID0gYFBsZWFzZSB2ZXJpZnkgdGhhdCB5b3UgYXJlIHJ1bm5pbmcgdGhlIGxhdGVzdCB2ZXJzaW9uIGFuZCwgaWYgc28sIGFsZXJ0IHRoZSBtYWludGFpbmVyLmA7XG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoc2NoZW1hKS5maWx0ZXIoKGspPT4hay5zdGFydHNXaXRoKCdfJykpKXtcbiAgICAgICAgY29uc3QgdGhpc0tleVBhdGggPSBrZXlQYXRoICsgKGtleVBhdGggJiYgJy4nKSArIGtleTtcbiAgICAgICAgY29uc3Qgc2NoZW1hUGFydCA9IHNjaGVtYVtrZXldO1xuICAgICAgICBpZiAodGhpc0tleVBhdGggPT09ICdEaXNwbGF5IGNvbmRpdGlvbnMnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGRlY2xhcmVzIGEgY29uZmlndXJhdGlvbiBvcHRpb24gY2FsbGVkIFwiRGlzcGxheSBjb25kaXRpb25zXCI7IHRoZSBcIkRpc3BsYXkgY29uZGl0aW9uc1wiIG9wdGlvbiBpcyBhIHJlc2VydmVkIG5hbWUuICR7dXBkYXRlTWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpc0tleVBhdGggPT09ICdUcmFuc2xhdGlvbiBvdmVycmlkZXMnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGRlY2xhcmVzIGEgY29uZmlndXJhdGlvbiBvcHRpb24gY2FsbGVkIFwiVHJhbnNsYXRpb24gb3ZlcnJpZGVzXCI7IHRoZSBcIlRyYW5zbGF0aW9uIG92ZXJyaWRlc1wiIG9wdGlvbiBpcyBhIHJlc2VydmVkIG5hbWUuICR7dXBkYXRlTWVzc2FnZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWlzT3JkaW5hcnlPYmplY3Qoc2NoZW1hUGFydCkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGJhZCBjb25maWcgc2NoZW1hIGRlZmluaXRpb24gZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nLiAke3VwZGF0ZU1lc3NhZ2V9YCk7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ19kZWZhdWx0JykpIHtcbiAgICAgICAgICAgIC8vIHJlY3Vyc2UgZm9yIG5lc3RlZCBjb25maWcga2V5c1xuICAgICAgICAgICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgc2NoZW1hUGFydCwgdGhpc0tleVBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGVsZW1lbnRzID0gc2NoZW1hUGFydC5fZWxlbWVudHM7XG4gICAgICAgIGlmIChoYXNPYmplY3RTY2hlbWEoZWxlbWVudHMpKSB7XG4gICAgICAgICAgICB2YWxpZGF0ZUNvbmZpZ1NjaGVtYShtb2R1bGVOYW1lLCBlbGVtZW50cywgdGhpc0tleVBhdGggKyAnLl9lbGVtZW50cycpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzY2hlbWFQYXJ0Ll92YWxpZGF0b3JzKSB7XG4gICAgICAgICAgICBmb3IgKGxldCB2YWxpZGF0b3Igb2Ygc2NoZW1hUGFydC5fdmFsaWRhdG9ycyl7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWxpZGF0b3IgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgaW52YWxpZCB2YWxpZGF0b3IgZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IHZhbGlkYXRvcnMgbXVzdCBiZSBmdW5jdGlvbnMgdGhhdCByZXR1cm4gZWl0aGVyIGAgKyBgdW5kZWZpbmVkIG9yIGFuIGVycm9yIHN0cmluZy4gUmVjZWl2ZWQgJHt2YWxpZGF0b3J9LmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCB2YWx1ZVR5cGUgPSBzY2hlbWFQYXJ0Ll90eXBlO1xuICAgICAgICBpZiAodmFsdWVUeXBlICYmICFPYmplY3QudmFsdWVzKFR5cGUpLmluY2x1ZGVzKHZhbHVlVHlwZSkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGludmFsaWQgdHlwZSBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScgJHt1cGRhdGVNZXNzYWdlfS5gICsgYFxcblxcbklmIHlvdSdyZSB0aGUgbWFpbnRhaW5lcjogdGhlIGFsbG93ZWQgdHlwZXMgYXJlICR7T2JqZWN0LnZhbHVlcyhUeXBlKS5qb2luKCcsICcpfS4gYCArIGBSZWNlaXZlZCAnJHt2YWx1ZVR5cGV9J2ApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChPYmplY3Qua2V5cyhzY2hlbWFQYXJ0KS5ldmVyeSgoayk9PltcbiAgICAgICAgICAgICAgICAnX2Rlc2NyaXB0aW9uJyxcbiAgICAgICAgICAgICAgICAnX3ZhbGlkYXRvcnMnLFxuICAgICAgICAgICAgICAgICdfZWxlbWVudHMnLFxuICAgICAgICAgICAgICAgICdfdHlwZSdcbiAgICAgICAgICAgIF0uaW5jbHVkZXMoaykpICYmICFrZXlQYXRoLmluY2x1ZGVzKCcuX2VsZW1lbnRzJykpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGJhZCBjb25maWcgc2NoZW1hIGRlZmluaXRpb24gZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nLiAke3VwZGF0ZU1lc3NhZ2V9LmAgKyBgXFxuXFxuSWYgeW91J3JlIHRoZSBtYWludGFpbmVyOiBhbGwgY29uZmlnIGVsZW1lbnRzIG11c3QgaGF2ZSBhIGRlZmF1bHQuIGAgKyBgUmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShzY2hlbWFQYXJ0KX1gKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudHMgJiYgdmFsdWVUeXBlICYmICFbXG4gICAgICAgICAgICBUeXBlLkFycmF5LFxuICAgICAgICAgICAgVHlwZS5PYmplY3RcbiAgICAgICAgXS5pbmNsdWRlcyh2YWx1ZVR5cGUpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBiYWQgY29uZmlnIHNjaGVtYSBkZWZpbml0aW9uIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9Jy4gJHt1cGRhdGVNZXNzYWdlfS5gICsgYFxcblxcbklmIHlvdSdyZSB0aGUgbWFpbnRhaW5lcjogdGhlICdlbGVtZW50cycga2V5IG9ubHkgd29ya3Mgd2l0aCAnX3R5cGUnIGVxdWFsIHRvICdBcnJheScgb3IgJ09iamVjdCcuIGAgKyBgUmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeSh2YWx1ZVR5cGUpfWApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0Q29uZmlnRm9yTW9kdWxlKG1vZHVsZU5hbWUsIGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBzY2hlbWEgPSBjb25maWdTdGF0ZS5zY2hlbWFzW21vZHVsZU5hbWVdO1xuICAgIGNvbnN0IGlucHV0Q29uZmlnID0gbWVyZ2VDb25maWdzRm9yKG1vZHVsZU5hbWUsIGdldFByb3ZpZGVkQ29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSk7XG4gICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBpbnB1dENvbmZpZywgbW9kdWxlTmFtZSk7XG4gICAgY29uc3QgY29uZmlnID0gc2V0RGVmYXVsdHMoc2NoZW1hLCBpbnB1dENvbmZpZyk7XG4gICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEsIGNvbmZpZywgbW9kdWxlTmFtZSk7XG4gICAgZGVsZXRlIGNvbmZpZy5leHRlbnNpb25TbG90cztcbiAgICByZXR1cm4gY29uZmlnO1xufVxuZnVuY3Rpb24gZ2V0Q29uZmlnRm9yTW9kdWxlSW1wbGljaXRTY2hlbWEobW9kdWxlTmFtZSwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIGNvbnN0IGlucHV0Q29uZmlnID0gbWVyZ2VDb25maWdzRm9yKG1vZHVsZU5hbWUsIGdldFByb3ZpZGVkQ29uZmlncyhjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSk7XG4gICAgY29uc3QgY29uZmlnID0gc2V0RGVmYXVsdHMoaW1wbGljaXRDb25maWdTY2hlbWEsIGlucHV0Q29uZmlnKTtcbiAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKGltcGxpY2l0Q29uZmlnU2NoZW1hLCBjb25maWcsIG1vZHVsZU5hbWUpO1xuICAgIGRlbGV0ZSBjb25maWcuZXh0ZW5zaW9uU2xvdHM7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmZ1bmN0aW9uIG1lcmdlQ29uZmlnc0Zvcihtb2R1bGVOYW1lLCBhbGxDb25maWdzKSB7XG4gICAgY29uc3QgYWxsQ29uZmlnc0Zvck1vZHVsZSA9IGFsbENvbmZpZ3MubWFwKCh7IFttb2R1bGVOYW1lXTogYyB9KT0+YykuZmlsdGVyKChjKT0+ISFjKTtcbiAgICByZXR1cm4gbWVyZ2VDb25maWdzKGFsbENvbmZpZ3NGb3JNb2R1bGUpO1xufVxuLyoqXG4gKiBNZXJnZXMgYSB3aG9sZSBsaXN0IGF0IG9uY2UsIGFjY3VtdWxhdGluZyBpbnRvIG9uZSBkZXN0aW5hdGlvbi5cbiAqLyBmdW5jdGlvbiBtZXJnZUNvbmZpZ3MoY29uZmlncykge1xuICAgIHJldHVybiBjb25maWdzLnJlZHVjZSgoYWNjLCBjb25maWcpPT5tZXJnZVdpdGgoYWNjLCBjb25maWcsIHJlcGxhY2VBcnJheXMpLCB7fSk7XG59XG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGNoZWNrIHRoZSBwcm92aWRlZCBjb25maWcgdHJlZSB0byBtYWtlIHN1cmUgdGhhdCBhbGxcbiAqIG9mIHRoZSBwcm92aWRlZCBwcm9wZXJ0aWVzIGV4aXN0IGluIHRoZSBzY2hlbWEsIGFuZCB0aGF0IHR5cGVzIGFyZVxuICogY29ycmVjdC4gRG9lcyBub3QgcnVuIHZhbGlkYXRvcnMgeWV0LCBzaW5jZSB0aG9zZSB3aWxsIGJlIHJ1biBvblxuICogdGhlIGNvbmZpZyB3aXRoIHRoZSBkZWZhdWx0cyBmaWxsZWQgaW4uXG4gKi8gZnVuY3Rpb24gdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBjb25maWcsIGtleVBhdGggPSAnJykge1xuICAgIC8vIHZhbGlkYXRlIGVhY2ggY29uc3RpdHVlbnQgZWxlbWVudFxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpe1xuICAgICAgICBjb25zdCB2YWx1ZSA9IGNvbmZpZ1trZXldO1xuICAgICAgICBjb25zdCB0aGlzS2V5UGF0aCA9IGtleVBhdGggKyAnLicgKyBrZXk7XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgaWYgKCFzY2hlbWEuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgaWYgKCEoa2V5ID09PSAnZXh0ZW5zaW9uU2xvdHMnICYmIGtleVBhdGggIT09ICcnKSkge1xuICAgICAgICAgICAgICAgIGxvZ0Vycm9yKHRoaXNLZXlQYXRoLCBgVW5rbm93biBjb25maWcga2V5ICcke3RoaXNLZXlQYXRofScgcHJvdmlkZWQuIElnbm9yaW5nLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgdmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIHRoaXNLZXlQYXRoKTtcbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCkge1xuICAgIGNoZWNrVHlwZShrZXlQYXRoLCBzY2hlbWFQYXJ0Ll90eXBlLCB2YWx1ZSk7XG4gICAgaWYgKGlzT3JkaW5hcnlPYmplY3QodmFsdWUpKSB7XG4gICAgICAgIGlmIChzY2hlbWFQYXJ0Ll90eXBlID09PSBUeXBlLk9iamVjdCkge1xuICAgICAgICAgICAgLy8gdmFsaWRhdGUgYXMgZnJlZWZvcm0gb2JqZWN0XG4gICAgICAgICAgICB2YWxpZGF0ZUZyZWVmb3JtT2JqZWN0U3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCBrZXlQYXRoKTtcbiAgICAgICAgfSBlbHNlIGlmICghKHNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ19kZWZhdWx0JykgfHwgc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX3R5cGUnKSkpIHtcbiAgICAgICAgICAgIC8vIHZhbGlkYXRlIGFzIG5vcm1hbCBuZXN0ZWQgY29uZmlnXG4gICAgICAgICAgICB2YWxpZGF0ZVN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCk7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoc2NoZW1hUGFydC5fdHlwZSA9PT0gVHlwZS5BcnJheSkge1xuICAgICAgICAgICAgdmFsaWRhdGVBcnJheVN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCk7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUZyZWVmb3JtT2JqZWN0U3RydWN0dXJlKGZyZWVmb3JtT2JqZWN0U2NoZW1hLCBjb25maWcsIGtleVBhdGgpIHtcbiAgICBpZiAoZnJlZWZvcm1PYmplY3RTY2hlbWEuX2VsZW1lbnRzKSB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpe1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdba2V5XTtcbiAgICAgICAgICAgIHZhbGlkYXRlQnJhbmNoU3RydWN0dXJlKGZyZWVmb3JtT2JqZWN0U2NoZW1hLl9lbGVtZW50cywgdmFsdWUsIGAke2tleVBhdGh9LiR7a2V5fWApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVBcnJheVN0cnVjdHVyZShhcnJheVNjaGVtYSwgdmFsdWUsIGtleVBhdGgpIHtcbiAgICBjb25zdCB2YWxpZGF0ZWRBc0FycmF5ID0gY2hlY2tUeXBlKGtleVBhdGgsIFR5cGUuQXJyYXksIHZhbHVlKTtcbiAgICBpZiAoIXZhbGlkYXRlZEFzQXJyYXkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBpZiB0aGVyZSBpcyBhbiBhcnJheSBlbGVtZW50IG9iamVjdCBzY2hlbWEsIHZlcmlmeSB0aGF0IGVsZW1lbnRzIG1hdGNoIGl0XG4gICAgaWYgKGhhc09iamVjdFNjaGVtYShhcnJheVNjaGVtYS5fZWxlbWVudHMpKSB7XG4gICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKyl7XG4gICAgICAgICAgICB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShhcnJheVNjaGVtYS5fZWxlbWVudHMsIHZhbHVlW2ldLCBgJHtrZXlQYXRofVske2l9XWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGZvcihsZXQgaSA9IDA7IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKyl7XG4gICAgICAgIGNoZWNrVHlwZShgJHtrZXlQYXRofVske2l9XWAsIGFycmF5U2NoZW1hLl9lbGVtZW50cz8uX3R5cGUsIHZhbHVlW2ldKTtcbiAgICB9XG59XG4vKipcbiAqIFJ1biBhbGwgdGhlIHZhbGlkYXRvcnMgaW4gdGhlIGNvbmZpZyB0cmVlLiBUaGlzIHNob3VsZCBiZSBydW5cbiAqIG9uIHRoZSBjb25maWcgb2JqZWN0IGFmdGVyIGl0IGhhcyBiZWVuIGZpbGxlZCBpbiB3aXRoIGFsbCB0aGUgZGVmYXVsdHMsIHNpbmNlXG4gKiBoaWdoZXItbGV2ZWwgdmFsaWRhdG9ycyBtYXkgcmVmZXIgdG8gZGVmYXVsdCB2YWx1ZXMuXG4gKi8gZnVuY3Rpb24gcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEsIGNvbmZpZywga2V5UGF0aCA9ICcnKSB7XG4gICAgLy8gSWYgYCFzY2hlbWFgLCB0aGVyZSBzaG91bGQgaGF2ZSBiZWVuIGEgc3RydWN0dXJhbCB2YWxpZGF0aW9uIGVycm9yIHByaW50ZWQgYWxyZWFkeS5cbiAgICBpZiAoc2NoZW1hKSB7XG4gICAgICAgIGlmIChjb25maWcgIT09IHNjaGVtYS5fZGVmYXVsdCkge1xuICAgICAgICAgICAgcnVuVmFsaWRhdG9ycyhrZXlQYXRoLCBzY2hlbWEuX3ZhbGlkYXRvcnMsIGNvbmZpZyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGlzT3JkaW5hcnlPYmplY3QoY29uZmlnKSkge1xuICAgICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMoY29uZmlnKSl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdba2V5XTtcbiAgICAgICAgICAgICAgICBjb25zdCB0aGlzS2V5UGF0aCA9IGtleVBhdGggKyAnLicgKyBrZXk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc2NoZW1hUGFydCA9IHNjaGVtYVtrZXldO1xuICAgICAgICAgICAgICAgIGlmIChzY2hlbWEuX3R5cGUgPT09IFR5cGUuT2JqZWN0ICYmIHNjaGVtYS5fZWxlbWVudHMpIHtcbiAgICAgICAgICAgICAgICAgICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShzY2hlbWEuX2VsZW1lbnRzLCB2YWx1ZSwgdGhpc0tleVBhdGgpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hUGFydCwgdmFsdWUsIHRoaXNLZXlQYXRoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjb25maWcpICYmIHNjaGVtYS5fZWxlbWVudHMpIHtcbiAgICAgICAgICAgIGZvcihsZXQgaSA9IDA7IGkgPCBjb25maWcubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLl9lbGVtZW50cywgY29uZmlnW2ldLCBgJHtrZXlQYXRofVske2l9XWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuLyoqXG4gKiBSdW4gdHlwZSB2YWxpZGF0aW9uIGZvciB0aGUgdmFsdWUsIGxvZ2dpbmcgYW55IGVycm9ycy5cbiAqIEByZXR1cm5zIHRydWUgaWYgdmFsaWRhdGlvbiBwYXNzZXMsIGZhbHNlIG90aGVyd2lzZVxuICovIGZ1bmN0aW9uIGNoZWNrVHlwZShrZXlQYXRoLCBfdHlwZSwgdmFsdWUpIHtcbiAgICBpZiAoX3R5cGUpIHtcbiAgICAgICAgY29uc3QgdmFsaWRhdG9yID0ge1xuICAgICAgICAgICAgQXJyYXk6IGlzQXJyYXksXG4gICAgICAgICAgICBCb29sZWFuOiBpc0Jvb2xlYW4sXG4gICAgICAgICAgICBDb25jZXB0VXVpZDogaXNVdWlkLFxuICAgICAgICAgICAgTnVtYmVyOiBpc051bWJlcixcbiAgICAgICAgICAgIE9iamVjdDogaXNPYmplY3QsXG4gICAgICAgICAgICBTdHJpbmc6IGlzU3RyaW5nLFxuICAgICAgICAgICAgVVVJRDogaXNVdWlkLFxuICAgICAgICAgICAgUGVyc29uQXR0cmlidXRlVHlwZVV1aWQ6IGlzVXVpZCxcbiAgICAgICAgICAgIFBhdGllbnRJZGVudGlmaWVyVHlwZVV1aWQ6IGlzVXVpZFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcnVuVmFsaWRhdG9ycyhrZXlQYXRoLCBbXG4gICAgICAgICAgICB2YWxpZGF0b3JbX3R5cGVdXG4gICAgICAgIF0sIHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG59XG4vKipcbiAqIFJ1bnMgdmFsaWRhdG9ycywgbG9nZ2luZyBlcnJvcnMuXG4gKiBAcmV0dXJucyB0cnVlIGlmIGFsbCBwYXNzLCBmYWxzZSBvdGhlcndpc2UuXG4gKi8gZnVuY3Rpb24gcnVuVmFsaWRhdG9ycyhrZXlQYXRoLCB2YWxpZGF0b3JzLCB2YWx1ZSkge1xuICAgIGxldCByZXR1cm5WYWx1ZSA9IHRydWU7XG4gICAgaWYgKHZhbGlkYXRvcnMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZvciAobGV0IHZhbGlkYXRvciBvZiB2YWxpZGF0b3JzKXtcbiAgICAgICAgICAgICAgICBjb25zdCB2YWxpZGF0b3JSZXN1bHQgPSB2YWxpZGF0b3IodmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsaWRhdG9yUmVzdWx0ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyA/IGBJbnZhbGlkIGNvbmZpZ3VyYXRpb24gZm9yICR7a2V5UGF0aH06ICR7dmFsaWRhdG9yUmVzdWx0fWAgOiBgSW52YWxpZCBjb25maWd1cmF0aW9uIHZhbHVlICR7dmFsdWV9IGZvciAke2tleVBhdGh9OiAke3ZhbGlkYXRvclJlc3VsdH1gO1xuICAgICAgICAgICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBtZXNzYWdlKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFNraXBwaW5nIGludmFsaWQgdmFsaWRhdG9yIGF0IFwiJHtrZXlQYXRofVwiLiBFbmNvdW50ZXJlZCBlcnJvclxcblxcdCR7ZX1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmV0dXJuVmFsdWU7XG59XG4vLyBSZWN1cnNpdmVseSBmaWxsIGluIHRoZSBjb25maWcgd2l0aCB2YWx1ZXMgZnJvbSB0aGUgc2NoZW1hLlxuY29uc3Qgc2V0RGVmYXVsdHMgPSAoc2NoZW1hLCBpbnB1dENvbmZpZyk9PntcbiAgICBjb25zdCBjb25maWcgPSBzdHJ1Y3R1cmVkQ2xvbmUoaW5wdXRDb25maWcpO1xuICAgIGlmICghc2NoZW1hKSB7XG4gICAgICAgIHJldHVybiBjb25maWc7XG4gICAgfVxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYSkpe1xuICAgICAgICBjb25zdCBjb25maWdQYXJ0ID0gY29uZmlnW2tleV07XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgLy8gVGhlIGBzY2hlbWFQYXJ0ICYmYCBjbGF1c2Ugb2YgdGhpcyBgaWZgIHN0YXRlbWVudCB3aWxsIG9ubHkgZmFpbFxuICAgICAgICAvLyBpZiB0aGUgc2NoZW1hIGlzIHZlcnkgaW52YWxpZC4gSXQgaXMgdGhlcmUgdG8gcHJldmVudCB0aGUgYXBwIGZyb21cbiAgICAgICAgLy8gY3Jhc2hpbmcgY29tcGxldGVseSwgdGhvdWdoIGl0IHdpbGwgcHJvZHVjZSB1bmV4cGVjdGVkIGJlaGF2aW9yLlxuICAgICAgICAvLyBJZiB0aGlzIGhhcHBlbnMsIHRoZXJlIHNob3VsZCBiZSBsZWdpYmxlIGVycm9ycyBpbiB0aGUgY29uc29sZSBmcm9tXG4gICAgICAgIC8vIHRoZSBzY2hlbWEgdmFsaWRhdG9yLlxuICAgICAgICBpZiAoc2NoZW1hUGFydCAmJiAoc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX3R5cGUnKSB8fCBzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpKSkge1xuICAgICAgICAgICAgLy8gV2UgYXNzdW1lIHRoYXQgc2NoZW1hUGFydCBkZWZpbmVzIGEgY29uZmlnIHZhbHVlLCBzaW5jZSBpdCBoYXNcbiAgICAgICAgICAgIC8vIGEgcHJvcGVydHkgYF90eXBlYCBvciBgX2RlZmF1bHRgLlxuICAgICAgICAgICAgaWYgKCFjb25maWcuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgICAgIGNvbmZpZ1trZXldID0gc2NoZW1hUGFydFsnX2RlZmF1bHQnXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFdlIGFsc28gY2hlY2sgaWYgaXQgaXMgYW4gb2JqZWN0IG9yIGFycmF5IHdpdGggb2JqZWN0IGVsZW1lbnRzLCBpbiB3aGljaCBjYXNlIHdlIHJlY3Vyc2VcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRzID0gc2NoZW1hUGFydC5fZWxlbWVudHM7XG4gICAgICAgICAgICBpZiAoY29uZmlnUGFydCAmJiBoYXNPYmplY3RTY2hlbWEoZWxlbWVudHMpKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuQXJyYXkgJiYgQXJyYXkuaXNBcnJheShjb25maWdQYXJ0KSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25maWdXaXRoRGVmYXVsdHMgPSBjb25maWdQYXJ0Lm1hcCgoY29uZik9PnNldERlZmF1bHRzKGVsZW1lbnRzLCBjb25mKSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbmZpZ1trZXldID0gY29uZmlnV2l0aERlZmF1bHRzO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc2NoZW1hUGFydC5fdHlwZSA9PT0gVHlwZS5PYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgZm9yIChsZXQgb2JqZWN0S2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZ1BhcnQpKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZ1BhcnRbb2JqZWN0S2V5XSA9IHNldERlZmF1bHRzKGVsZW1lbnRzLCBjb25maWdQYXJ0W29iamVjdEtleV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGlzT3JkaW5hcnlPYmplY3Qoc2NoZW1hUGFydCkpIHtcbiAgICAgICAgICAgIC8vIFNpbmNlIHNjaGVtYVBhcnQgaGFzIG5vIHByb3BlcnR5IFwiX3R5cGVcIiwgaWYgaXQncyBhbiBvcmRpbmFyeSBvYmplY3RcbiAgICAgICAgICAgIC8vICh1bmxpa2UsIGltcG9ydGFudGx5LCB0aGUgdmFsaWRhdG9ycyBhcnJheSksIHdlIGFzc3VtZSBpdCBpcyBhIHBhcmVudCBjb25maWcgcHJvcGVydHkuXG4gICAgICAgICAgICAvLyBXZSByZWN1cnNlIHRvIGNvbmZpZ1trZXldIGFuZCBzY2hlbWFba2V5XS4gRGVmYXVsdCBjb25maWdba2V5XSB0byB7fS5cbiAgICAgICAgICAgIGNvbnN0IHNlbGVjdGVkQ29uZmlnUGFydCA9IGNvbmZpZ1BhcnQgPz8ge307XG4gICAgICAgICAgICAvLyBUaGVyZSB3aWxsIGhhdmUgYmVlbiBhIHZhbGlkYXRpb24gZXJyb3IgYWxyZWFkeSBpZiBjb25maWdQYXJ0IGlzIG5vdCBhIHBsYWluIG9iamVjdC5cbiAgICAgICAgICAgIGlmIChpc09yZGluYXJ5T2JqZWN0KHNlbGVjdGVkQ29uZmlnUGFydCkpIHtcbiAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IHNldERlZmF1bHRzKHNjaGVtYVBhcnQsIHNlbGVjdGVkQ29uZmlnUGFydCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNvbmZpZztcbn07XG5mdW5jdGlvbiBoYXNPYmplY3RTY2hlbWEoZWxlbWVudHNTY2hlbWEpIHtcbiAgICByZXR1cm4gISFlbGVtZW50c1NjaGVtYSAmJiBPYmplY3Qua2V5cyhlbGVtZW50c1NjaGVtYSkuZmlsdGVyKChlKT0+IVtcbiAgICAgICAgICAgICdfZGVmYXVsdCcsXG4gICAgICAgICAgICAnX3ZhbGlkYXRvcnMnXG4gICAgICAgIF0uaW5jbHVkZXMoZSkpLmxlbmd0aCA+IDA7XG59XG5mdW5jdGlvbiBpc09yZGluYXJ5T2JqZWN0KHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIHZhbHVlICE9PSBudWxsO1xufVxuLyoqIEtlZXAgdHJhY2sgb2Ygd2hpY2ggdmFsaWRhdGlvbiBlcnJvcnMgd2UgaGF2ZSBkaXNwbGF5ZWQuIEVhY2ggb25lIHNob3VsZCBvbmx5IGJlIGRpc3BsYXllZCBvbmNlLiAqLyBsZXQgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzID0gbmV3IFNldCgpO1xuZnVuY3Rpb24gbG9nRXJyb3Ioa2V5UGF0aCwgbWVzc2FnZSkge1xuICAgIGNvbnN0IGtleSA9IGAke2tleVBhdGh9Ojo6JHttZXNzYWdlfWA7XG4gICAgLy8gdGVjaG5pY2FsbHksIHRoaXMgc2hvdWxkIG5vdCBiZSBwb3NzaWJsZSwgYnV0IGJlY2F1c2Ugb2YgaG93IHRoaW5ncyB3aW5kLXVwIHRyYW5zcGlsZWQsIHRoaXMgaXNuJ3QgaW1wb3NzaWJsZVxuICAgIGlmICghZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzKSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcyA9IG5ldyBTZXQoKTtcbiAgICB9XG4gICAgaWYgKCFkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMuaGFzKGtleSkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihtZXNzYWdlKTtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmFkZChrZXkpO1xuICAgIH1cbn1cbi8qKlxuICogTm9ybWFsbHksIGNvbmZpZ3VyYXRpb24gZXJyb3JzIGFyZSBvbmx5IGRpc3BsYXllZCBvbmNlLiBUaGlzIGZ1bmN0aW9uIGNsZWFycyB0aGUgbGlzdCBvZlxuICogZGlzcGxheWVkIGVycm9ycywgc28gdGhhdCB0aGV5IHdpbGwgYmUgZGlzcGxheWVkIGFnYWluLlxuICpcbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBmdW5jdGlvbiBjbGVhckNvbmZpZ0Vycm9ycyhrZXlQYXRoKSB7XG4gICAgaWYgKGtleVBhdGgpIHtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmZvckVhY2goKGtleSk9PntcbiAgICAgICAgICAgIGlmIChrZXkuc3RhcnRzV2l0aChrZXlQYXRoKSkge1xuICAgICAgICAgICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmNsZWFyKCk7XG4gICAgfVxufVxuLyoqXG4gKiBDbGVhbnMgdXAgYWxsIGNvbmZpZyBzdG9yZSBzdWJzY3JpcHRpb25zIGFuZCByZS1lc3RhYmxpc2hlcyB0aGVtLiBUaGlzIGlzIHByaW1hcmlseVxuICogdXNlZnVsIGZvciB0ZXN0aW5nLCB3aGVyZSBzdWJzY3JpcHRpb25zIHNldCB1cCBhdCBtb2R1bGUgbG9hZCB0aW1lIG5lZWQgdG8gYmUgY2xlYXJlZFxuICogYmV0d2VlbiB0ZXN0cyB0byBwcmV2ZW50IGluZmluaXRlIHVwZGF0ZSBsb29wcy4gQWZ0ZXIgY2xlYXJpbmcsIHN1YnNjcmlwdGlvbnMgYXJlXG4gKiByZS1lc3RhYmxpc2hlZCBzbyB0aGUgY29uZmlnIHN5c3RlbSBjb250aW51ZXMgdG8gd29yayBub3JtYWxseS5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVzZXRDb25maWdTeXN0ZW0oKSB7XG4gICAgY29uZmlnU3Vic2NyaXB0aW9ucy5mb3JFYWNoKCh1bnN1YnNjcmliZSk9PnVuc3Vic2NyaWJlKCkpO1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMubGVuZ3RoID0gMDtcbiAgICAvLyBDYWNoZWQgY29uZmlncyBhcmUga2V5ZWQgb24gaW5wdXQgaWRlbnRpdHksIHNvIGEgdGVzdCB0aGF0IHJldXNlcyB0aGUgc2FtZSBzY2hlbWEgb3IgY29uZmlnXG4gICAgLy8gb2JqZWN0cyBhY3Jvc3MgY2FzZXMgd291bGQgb3RoZXJ3aXNlIGJlIHNlcnZlZCB0aGUgcHJldmlvdXMgY2FzZSdzIHJlc3VsdC5cbiAgICBtb2R1bGVDb25maWdDYWNoZS5jbGVhcigpO1xuICAgIGV4dGVuc2lvbkNvbmZpZ0NhY2hlLmNsZWFyKCk7XG4gICAgc2NoZW1hVmFsdWVzQW5kU291cmNlc0NhY2hlLmNsZWFyKCk7XG4gICAgaW1wbGVtZW50ZXJUb29sc01vZHVsZUNhY2hlLmNsZWFyKCk7XG4gICAgc2V0dXBDb25maWdTdWJzY3JpcHRpb25zKCk7XG59XG4vKipcbiAqIENvcGllZCBvdmVyIGZyb20gZXNtLWV4dGVuc2lvbnMuIEl0IHJpZ2h0bHkgYmVsb25ncyB0byB0aGF0IG1vZHVsZSwgYnV0IGVzbS1jb25maWdcbiAqIGNhbm5vdCBkZXBlbmQgb24gZXNtLWV4dGVuc2lvbnMuXG4gKi8gZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZChleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IFtleHRlbnNpb25OYW1lXSA9IGV4dGVuc2lvbklkLnNwbGl0KCcjJyk7XG4gICAgcmV0dXJuIGV4dGVuc2lvbk5hbWU7XG59XG4vKipcbiAqIFRoZSB0cmFuc2xhdGlvbiBvdmVycmlkZXMgc2NoZW1hIGlzIHVzZWQgaW4gdGhlIGltcGxpY2l0IHNjaGVtYSBnaXZlbiB0byBldmVyeSBtb2R1bGU7XG4gKiBwbHVzIGFueSBhZGRpdGlvbmFsIHRyYW5zbGF0aW9uIG5hbWVzcGFjZXMgKGF0IHRpbWUgb2Ygd3JpdGluZywgdGhpcyBpcyBqdXN0ICdjb3JlJykuXG4gKi8gY29uc3QgdHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWEgPSB7XG4gICAgJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcyc6IHtcbiAgICAgICAgX2Rlc2NyaXB0aW9uOiAnUGVyLWxhbmd1YWdlIG92ZXJyaWRlcyBmb3IgZnJvbnRlbmQgdHJhbnNsYXRpb25zIHNob3VsZCBiZSBrZXllZCBieSBsYW5ndWFnZSBjb2RlIGFuZCBlYWNoIGxhbmd1YWdlIGRpY3Rpb25hcnkgY29udGFpbnMgdGhlIHRyYW5zbGF0aW9uIGtleSBhbmQgdGhlIGRpc3BsYXkgdmFsdWUnLFxuICAgICAgICBfdHlwZTogVHlwZS5PYmplY3QsXG4gICAgICAgIF9kZWZhdWx0OiB7fSxcbiAgICAgICAgX3ZhbGlkYXRvcnM6IFtcbiAgICAgICAgICAgIHZhbGlkYXRvcigobyk9Pk9iamVjdC5rZXlzKG8pLmV2ZXJ5KChrKT0+L15bYS16XXsyLDN9KC1bQS1aXXsyLDN9KT8kLy50ZXN0KGspKSwgKG8pPT57XG4gICAgICAgICAgICAgICAgY29uc3QgYmFkS2V5cyA9IE9iamVjdC5rZXlzKG8pLmZpbHRlcigoayk9PiEvXlthLXpdezIsM30oLVtBLVpdezIsM30pPyQvLnRlc3QoaykpO1xuICAgICAgICAgICAgICAgIHJldHVybiBgVGhlICdUcmFuc2xhdGlvbiBvdmVycmlkZXMnIG9iamVjdCBzaG91bGQgaGF2ZSBsYW5ndWFnZSBjb2RlcyBmb3Iga2V5cy4gTGFuZ3VhZ2UgY29kZXMgbXVzdCBiZSBpbiB0aGUgZm9ybSBvZiBhIHR3by10by10aHJlZSBsZXR0ZXIgbGFuZ3VhZ2UgY29kZSBvcHRpb25hbGx5IGZvbGxvd2VkIGJ5IGEgaHlwaGVuIGFuZCBhIHR3by10by10aHJlZSBsZXR0ZXIgY291bnRyeSBjb2RlLiBUaGUgZm9sbG93aW5nIGtleXMgZG8gbm90IGNvbmZvcm06ICR7YmFkS2V5cy5qb2luKCcsICcpfS5gO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgXVxuICAgIH1cbn07XG4vKipcbiAqIFRoZSBpbXBsaWNpdENvbmZpZ1NjaGVtYSBpcyBpbXBsaWNpdGx5IGluY2x1ZGVkIGluIGV2ZXJ5IGNvbmZpZ3VyYXRpb24gc2NoZW1hXG4gKi8gY29uc3QgaW1wbGljaXRDb25maWdTY2hlbWEgPSB7XG4gICAgJ0Rpc3BsYXkgY29uZGl0aW9ucyc6IHtcbiAgICAgICAgcHJpdmlsZWdlczoge1xuICAgICAgICAgICAgX2Rlc2NyaXB0aW9uOiAnVGhlIHByaXZpbGVnZShzKSB0aGUgdXNlciBtdXN0IGhhdmUgdG8gdXNlIHRoaXMgZXh0ZW5zaW9uJyxcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLkFycmF5LFxuICAgICAgICAgICAgX2RlZmF1bHQ6IFtdXG4gICAgICAgIH0sXG4gICAgICAgIGV4cHJlc3Npb246IHtcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBleHByZXNzaW9uIHRoYXQgZGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBleHRlbnNpb24gaXMgZGlzcGxheWVkJyxcbiAgICAgICAgICAgIF90eXBlOiBUeXBlLlN0cmluZyxcbiAgICAgICAgICAgIF9kZWZhdWx0OiB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLi4udHJhbnNsYXRpb25PdmVycmlkZXNTY2hlbWFcbn07XG4iXSwibmFtZXMiOlsiY2xvbmVEZWVwIiwiaXNFcXVhbCIsIm1lcmdlV2l0aCIsIm9taXQiLCJsb2Rhc2hPbWl0IiwiVHlwZSIsImlzQXJyYXkiLCJpc0Jvb2xlYW4iLCJpc1V1aWQiLCJpc051bWJlciIsImlzT2JqZWN0IiwiaXNTdHJpbmciLCJ2YWxpZGF0b3IiLCJjb25maWdFeHRlbnNpb25TdG9yZSIsImNvbmZpZ0ludGVybmFsU3RvcmUiLCJnZXRDb25maWdTdG9yZSIsImdldEV4dGVuc2lvbkNvbmZpZyIsImdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUiLCJnZXRFeHRlbnNpb25zQ29uZmlnU3RvcmUiLCJjbGVhckNvbmZpZ0Rlcml2YXRpb25FcnJvciIsImltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSIsImludmFsaWRhdGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnIiwicmVjb3JkQ29uZmlnRGVyaXZhdGlvbkVycm9yIiwic2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZ1JlY29tcHV0ZXIiLCJ0ZW1wb3JhcnlDb25maWdTdG9yZSIsInJlcGxhY2VBcnJheXMiLCJfb2JqVmFsdWUiLCJzcmNWYWx1ZSIsIkFycmF5IiwibWVyZ2VEZWVwUmVwbGFjZSIsImxlZnQiLCJyaWdodCIsImNvbmZpZ1N1YnNjcmlwdGlvbnMiLCJyZWNvbXB1dGVBbGxDb25maWdzIiwiY29uZmlnU3RhdGUiLCJ0ZW1wQ29uZmlnU3RhdGUiLCJleHRlbnNpb25TdGF0ZSIsImNvbXB1dGVNb2R1bGVDb25maWciLCJzbG90Q29uZmlncyIsImdldEV4dGVuc2lvblNsb3RDb25maWdzIiwiY29tcHV0ZUV4dGVuc2lvblNsb3RDb25maWdzIiwiY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3MiLCJzZXR1cENvbmZpZ1N1YnNjcmlwdGlvbnMiLCJjb21wdXRlSW1wbGVtZW50ZXJUb29sc0NvbmZpZyIsInJlY29tcHV0ZUFsbENvbmZpZ3NTYWZlbHkiLCJlIiwiY29uc29sZSIsIm1vZHVsZUNvbmZpZ0NhY2hlIiwiTWFwIiwic3RhdGUiLCJ0ZW1wU3RhdGUiLCJtb2R1bGVOYW1lIiwiT2JqZWN0IiwibW9kdWxlU3RvcmUiLCJzY2hlbWEiLCJtb2R1bGVMb2FkZWQiLCJCb29sZWFuIiwiY2FjaGVkIiwibmV3U3RhdGUiLCJjb25maWciLCJnZXRDb25maWdGb3JNb2R1bGUiLCJnZXRDb25maWdGb3JNb2R1bGVJbXBsaWNpdFNjaGVtYSIsIm9sZFN0YXRlIiwic2xvdFN0b3JlIiwib2xkU2xvdHMiLCJzbG90cyIsImNoYW5nZWQiLCJzbG90TmFtZSIsInByZXZpb3VzIiwiZ2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZyIsImV4dGVuc2lvbnNDb25maWdTdG9yZSIsIm9sZENvbmZpZ3MiLCJjb25maWdzIiwiZW50cnlDb3VudCIsImV4dGVuc2lvbiIsImNvbXB1dGVFeHRlbnNpb25Db25maWciLCJlbnRyeSIsInByZXZpb3VzU2xvdCIsImV4dGVuc2lvbklkIiwidG90YWwiLCJzbG90IiwiZGVmaW5lQ29uZmlnU2NoZW1hIiwidmFsaWRhdGVDb25maWdTY2hlbWEiLCJlbmhhbmNlZFNjaGVtYSIsImltcGxpY2l0Q29uZmlnU2NoZW1hIiwicmVnaXN0ZXJNb2R1bGVXaXRoQ29uZmlnU3lzdGVtIiwicmVnaXN0ZXJNb2R1bGVMb2FkIiwicmVnaXN0ZXJUcmFuc2xhdGlvbk5hbWVzcGFjZSIsIm5hbWVzcGFjZSIsInRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hIiwiZGVmaW5lRXh0ZW5zaW9uQ29uZmlnU2NoZW1hIiwiZXh0ZW5zaW9uTmFtZSIsInByb3ZpZGUiLCJzb3VyY2VOYW1lIiwid2hlblN0b3JlUmVhZHkiLCJzdG9yZSIsInJlYWR5Iiwic2VsZWN0IiwiUHJvbWlzZSIsInJlc29sdmUiLCJ1bnN1YnNjcmliZSIsInJlc29sdmVkIiwidXBkYXRlIiwiZ2V0Q29uZmlnIiwiZ2V0VHJhbnNsYXRpb25PdmVycmlkZXMiLCJwcm9taXNlcyIsInByb2Nlc3NDb25maWciLCJwcm92aWRlZENvbmZpZyIsImtleVBhdGhDb250ZXh0IiwidmFsaWRhdGVTdHJ1Y3R1cmUiLCJzZXREZWZhdWx0cyIsInJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUiLCJleHRlbnNpb25Db25maWdDYWNoZSIsInNsb3RNb2R1bGVOYW1lIiwiZXh0ZW5zaW9uTW9kdWxlTmFtZSIsInNsb3RDb25maWciLCJnZXRFeHRlbnNpb25OYW1lRnJvbUlkIiwiZXh0ZW5zaW9uQ29uZmlnU2NoZW1hIiwiY2FjaGVLZXkiLCJKU09OIiwibmFtZU9mU2NoZW1hU291cmNlIiwicHJvdmlkZWRDb25maWdzIiwiZ2V0UHJvdmlkZWRDb25maWdzIiwic2hhcmVkT3ZlcnJpZGUiLCJzbG90TW9kdWxlQ29uZmlnIiwibWVyZ2VDb25maWdzRm9yIiwiY29uZmlnT3ZlcnJpZGUiLCJleHRlbnNpb25Db25maWciLCJjb21iaW5lZENvbmZpZyIsIm1lcmdlQ29uZmlncyIsImltcGxlbWVudGVyVG9vbHNNb2R1bGVDYWNoZSIsImFubm90YXRlZFNjaGVtYXMiLCJnZXRBbGxTY2hlbWFzV2l0aFZhbHVlc0FuZFNvdXJjZXMiLCJjb25maWdzQW5kU291cmNlcyIsImMiLCJtb2R1bGVOYW1lcyIsIlNldCIsInJlc3VsdCIsImFubm90YXRlZFNjaGVtYSIsImNvbmZpZ1NsaWNlcyIsInNvdXJjZXMiLCJzb3VyY2UiLCJzbGljZSIsImkiLCJtZXJnZWQiLCJ1bmRlZmluZWQiLCJjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZSIsInNjaGVtYVZhbHVlc0FuZFNvdXJjZXNDYWNoZSIsInNjaGVtYXMiLCJhbm5vdGF0ZWQiLCJnZXRTY2hlbWFXaXRoVmFsdWVzQW5kU291cmNlcyIsImlzT3JkaW5hcnlPYmplY3QiLCJvYmoiLCJrZXkiLCJhbGxDb25maWdzIiwic2xvdENvbmZpZ1Blck1vZHVsZSIsInZhbGlkYXRlQWxsRXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJjb25maWd1cmVCbG9ja3MiLCJjb25maWdCeVNsb3ROYW1lIiwiX2NvbmZpZ3VyZUJsb2NrcyIsIl9zbG90TmFtZSIsImJsb2NrcyIsImNvbmZpZ3VyZSIsInZhbGlkYXRlRXh0ZW5zaW9uU2xvdENvbmZpZyIsImtleVBhdGgiLCJlcnJvclByZWZpeCIsImludmFsaWRLZXlzIiwiayIsImxvZ0Vycm9yIiwibiIsInVwZGF0ZU1lc3NhZ2UiLCJ0aGlzS2V5UGF0aCIsInNjaGVtYVBhcnQiLCJlbGVtZW50cyIsImhhc09iamVjdFNjaGVtYSIsInZhbHVlVHlwZSIsImlucHV0Q29uZmlnIiwiYWxsQ29uZmlnc0Zvck1vZHVsZSIsImFjYyIsInZhbHVlIiwidmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUiLCJjaGVja1R5cGUiLCJ2YWxpZGF0ZUZyZWVmb3JtT2JqZWN0U3RydWN0dXJlIiwidmFsaWRhdGVBcnJheVN0cnVjdHVyZSIsImZyZWVmb3JtT2JqZWN0U2NoZW1hIiwiYXJyYXlTY2hlbWEiLCJ2YWxpZGF0ZWRBc0FycmF5IiwicnVuVmFsaWRhdG9ycyIsIl90eXBlIiwidmFsaWRhdG9ycyIsInJldHVyblZhbHVlIiwidmFsaWRhdG9yUmVzdWx0IiwibWVzc2FnZSIsInN0cnVjdHVyZWRDbG9uZSIsImNvbmZpZ1BhcnQiLCJjb25maWdXaXRoRGVmYXVsdHMiLCJjb25mIiwib2JqZWN0S2V5Iiwic2VsZWN0ZWRDb25maWdQYXJ0IiwiZWxlbWVudHNTY2hlbWEiLCJkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMiLCJjbGVhckNvbmZpZ0Vycm9ycyIsInJlc2V0Q29uZmlnU3lzdGVtIiwi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\n//# sourceURL=webpack-internal:///../../framework/esm-config/dist/module-config/module-config.js\n\n}");
4524
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n clearConfigErrors: () => (clearConfigErrors),\n defineConfigSchema: () => (defineConfigSchema),\n defineExtensionConfigSchema: () => (defineExtensionConfigSchema),\n getConfig: () => (getConfig),\n getTranslationOverrides: () => (getTranslationOverrides),\n processConfig: () => (processConfig),\n provide: () => (provide),\n registerModuleLoad: () => (registerModuleLoad),\n registerModuleWithConfigSystem: () => (registerModuleWithConfigSystem),\n registerTranslationNamespace: () => (registerTranslationNamespace),\n resetConfigSystem: () => (resetConfigSystem)\n});\n/* import */ var lodash_es__rspack_import_4 = __webpack_require__(\"../../../node_modules/lodash-es/mergeWith.js\");\n/* import */ var lodash_es__rspack_import_5 = __webpack_require__(\"../../../node_modules/lodash-es/isEqual.js\");\n/* import */ var lodash_es__rspack_import_6 = __webpack_require__(\"../../../node_modules/lodash-es/omit.js\");\n/* import */ var lodash_es__rspack_import_7 = __webpack_require__(\"../../../node_modules/lodash-es/cloneDeep.js\");\n/* import */ var _types_js__rspack_import_0 = __webpack_require__(\"../../framework/esm-config/dist/types.js\");\n/* import */ var _validators_type_validators_js__rspack_import_1 = __webpack_require__(\"../../framework/esm-config/dist/validators/type-validators.js\");\n/* import */ var _validators_validator_js__rspack_import_2 = __webpack_require__(\"../../framework/esm-config/dist/validators/validator.js\");\n/* import */ var _state_js__rspack_import_3 = __webpack_require__(\"../../framework/esm-config/dist/module-config/state.js\");\n/** @module @category Config */ \n\n\n\n\n/**\n * Deep merge two objects, with right-side values taking precedence.\n * Arrays are replaced entirely (not merged by index), matching the\n * behavior of ramda's mergeDeepRight.\n */ function replaceArrays(_objValue, srcValue) {\n if (Array.isArray(srcValue)) {\n return srcValue;\n }\n}\nfunction mergeDeepReplace(left, right) {\n return (0,lodash_es__rspack_import_4[\"default\"])({}, left, right, replaceArrays);\n}\n/**\n * Store setup\n *\n *\n * Set up stores and subscriptions so that inputs get processed appropriately.\n *\n * There are *input* stores and *output* stores. The *input* stores\n * are configInternalStore, temporaryConfigStore, and configExtensionStore. The\n * output stores are set in the `compute...` functions. They are the module\n * config stores, the extension slot config stores (by module), the extension\n * config stores, and the implementer tools config store.\n *\n * This code sets up the subscriptions so that when an input store changes,\n * the correct set of output stores are updated.\n *\n * All `compute...` functions except `computeExtensionConfigs` are pure\n * (or are supposed to be), other than the fact that they all `setState`\n * store values at the end. `computeExtensionConfigs` calls `getGlobalStore`,\n * which creates stores.\n */ // Store unsubscribe functions to allow cleanup (e.g., in tests or hot module reloading)\nconst configSubscriptions = [];\n/**\n * Recomputes all configuration derived stores based on current state of input stores.\n * Called whenever any input store (configInternalStore, temporaryConfigStore, configExtensionStore) changes.\n */ function recomputeAllConfigs() {\n const configState = _state_js__rspack_import_3.configInternalStore.getState();\n const tempConfigState = _state_js__rspack_import_3.temporaryConfigStore.getState();\n const extensionState = _state_js__rspack_import_3.configExtensionStore.getState();\n // Mounting an extension changes only `configExtensionStore`, which only the extension configs\n // depend on, so the rest of the last derivation is reused.\n const configInputsUnchanged = lastDerivation?.configState === configState && lastDerivation.tempConfigState === tempConfigState;\n if (configInputsUnchanged) {\n computeExtensionConfigs(configState, extensionState, tempConfigState, lastDerivation.slotConfigs, true);\n return;\n }\n computeModuleConfig(configState, tempConfigState);\n const slotConfigs = getExtensionSlotConfigs(configState, tempConfigState);\n computeExtensionSlotConfigs(slotConfigs);\n computeExtensionConfigs(configState, extensionState, tempConfigState, slotConfigs, false);\n // Recorded only after the outputs above are written, so a failure forces a full derivation next time.\n lastDerivation = {\n configState,\n tempConfigState,\n slotConfigs\n };\n // Last, because a failure here must not skip the outputs above. Only kept current while the\n // implementer tools are watching it; otherwise derived on read.\n (0,_state_js__rspack_import_3.invalidateImplementerToolsConfig)();\n}\n/** The inputs the outputs were last fully derived from, compared by identity. */ let lastDerivation = null;\n/**\n * The mounted extension each extension config entry was derived for. An extension ID can be\n * mounted under a different module while its slot and ID stay the same, so an entry is only\n * current if its modules match too.\n */ let entryOrigins = new WeakMap();\nfunction setupConfigSubscriptions() {\n // Registered here rather than at module load so that `resetConfigSystem` restores it.\n (0,_state_js__rspack_import_3.setImplementerToolsConfigRecomputer)(()=>computeImplementerToolsConfig(_state_js__rspack_import_3.configInternalStore.getState(), _state_js__rspack_import_3.temporaryConfigStore.getState()));\n // Initial computation\n recomputeAllConfigs();\n // Subscribe to all input stores with a single handler\n // This ensures we only recompute once even if multiple stores change simultaneously\n configSubscriptions.push(_state_js__rspack_import_3.configInternalStore.subscribe(recomputeAllConfigsSafely), _state_js__rspack_import_3.temporaryConfigStore.subscribe(recomputeAllConfigsSafely), _state_js__rspack_import_3.configExtensionStore.subscribe(recomputeAllConfigsSafely));\n}\n/** Ensure that we do not throw during a store subscription */ function recomputeAllConfigsSafely() {\n (0,_state_js__rspack_import_3.clearConfigDerivationError)();\n try {\n recomputeAllConfigs();\n } catch (e) {\n (0,_state_js__rspack_import_3.recordConfigDerivationError)(e);\n console.error('Failed to recompute the configuration', e);\n }\n}\n// Set up subscriptions at module load time\nsetupConfigSubscriptions();\nconst moduleConfigCache = new Map();\nfunction computeModuleConfig(state, tempState) {\n for (let moduleName of Object.keys(state.schemas)){\n // At this point the schema could be either just the implicit schema or the actually\n // defined schema. We run with just the implicit schema because we want to populate\n // the config store with the translation overrides as soon as possible. In fact, the\n // translation system will throw for Suspense until the translation overrides are\n // available, which as of this writing blocks the schema definition from occurring\n // for modules loaded based on their extensions.\n const moduleStore = (0,_state_js__rspack_import_3.getConfigStore)(moduleName);\n const schema = state.schemas[moduleName];\n const moduleLoaded = Boolean(state.moduleLoaded[moduleName]);\n const cached = moduleConfigCache.get(moduleName);\n let newState;\n if (cached && cached.schema === schema && cached.moduleLoaded === moduleLoaded && cached.providedConfigs === state.providedConfigs && cached.temporaryConfig === tempState.config) {\n newState = cached.state;\n } else {\n const config = moduleLoaded ? getConfigForModule(moduleName, state, tempState) : getConfigForModuleImplicitSchema(moduleName, state, tempState);\n newState = {\n translationOverridesLoaded: true,\n loaded: moduleLoaded,\n config\n };\n moduleConfigCache.set(moduleName, {\n schema,\n moduleLoaded,\n providedConfigs: state.providedConfigs,\n temporaryConfig: tempState.config,\n state: newState\n });\n }\n // Writing unconditionally would hand every `useConfig` consumer in the application a new\n // object — and a re-render — whenever any module or extension anywhere is loaded.\n const oldState = moduleStore.getState();\n if (oldState.loaded !== newState.loaded || oldState.translationOverridesLoaded !== newState.translationOverridesLoaded || !(0,lodash_es__rspack_import_5[\"default\"])(oldState.config, newState.config)) {\n moduleStore.setState(newState);\n }\n }\n}\nfunction computeExtensionSlotConfigs(slotConfigs) {\n const slotStore = (0,_state_js__rspack_import_3.getExtensionSlotsConfigStore)();\n const oldSlots = slotStore.getState().slots;\n const slots = {};\n let changed = false;\n for (const [slotName, config] of Object.entries(slotConfigs)){\n const previous = oldSlots[slotName];\n // Entries keep their identity when the configuration behind them hasn't changed, so that\n // changing one slot's configuration doesn't invalidate every other configured slot.\n if (previous?.loaded && (0,lodash_es__rspack_import_5[\"default\"])(previous.config, config)) {\n slots[slotName] = previous;\n } else {\n slots[slotName] = {\n loaded: true,\n config\n };\n changed = true;\n }\n }\n // Built from scratch rather than merged over the previous state: a slot whose configuration\n // has been removed — clearing the temporary config, say — has to lose its entry, or the old\n // configuration stays in force until the page is reloaded.\n if (changed || Object.keys(oldSlots).length !== Object.keys(slots).length) {\n slotStore.setState({\n slots\n });\n }\n}\nfunction computeImplementerToolsConfig(state, tempConfigState) {\n const oldState = _state_js__rspack_import_3.implementerToolsConfigStore.getState();\n const config = getImplementerToolsConfig(state, tempConfigState);\n const newState = {\n config\n };\n // Use deep equality on the actual config content, not the wrapper object\n if (!(0,lodash_es__rspack_import_5[\"default\"])(oldState.config, newState.config)) {\n _state_js__rspack_import_3.implementerToolsConfigStore.setState(newState);\n }\n}\nfunction computeExtensionConfigs(configState, extensionState, tempConfigState, slotConfigs, configInputsUnchanged) {\n const extensionsConfigStore = (0,_state_js__rspack_import_3.getExtensionsConfigStore)();\n const oldConfigs = extensionsConfigStore.getState().configs;\n const configs = {};\n let changed = false;\n let entryCount = 0;\n // We assume that the module schema has already been defined, since the extension\n // it contains is mounted.\n for (let extension of extensionState.mountedExtensions){\n const previous = oldConfigs[extension.slotName]?.[extension.extensionId];\n let entry;\n const origin = previous && entryOrigins.get(previous);\n if (configInputsUnchanged && previous?.loaded && origin?.slotModuleName === extension.slotModuleName && origin.extensionModuleName === extension.extensionModuleName) {\n // Derived from these same inputs by the previous run, so it is still current.\n entry = previous;\n } else {\n const config = computeExtensionConfig(extension.slotModuleName, extension.extensionModuleName, extension.slotName, extension.extensionId, configState, tempConfigState, slotConfigs[extension.slotName]);\n // Entries keep their identity when the configuration behind them hasn't changed, so that\n // mounting one extension doesn't hand every other mounted extension a new config object.\n entry = previous?.loaded && (0,lodash_es__rspack_import_5[\"default\"])(previous.config, config) ? previous : {\n config,\n loaded: true\n };\n }\n entryOrigins.set(entry, extension);\n if (entry !== previous) {\n changed = true;\n }\n if (!configs[extension.slotName]) {\n configs[extension.slotName] = {};\n }\n configs[extension.slotName][extension.extensionId] = entry;\n entryCount++;\n }\n // Slots keep their identity too when none of their entries changed. Subscribers compare these\n // per-slot objects to work out which slots to re-derive, so handing out a fresh one for every\n // slot on every write would mark every slot with a mounted extension dirty.\n for (const [slotName, slotConfigs] of Object.entries(configs)){\n const previousSlot = oldConfigs[slotName];\n if (previousSlot && Object.keys(previousSlot).length === Object.keys(slotConfigs).length && Object.entries(slotConfigs).every(([extensionId, entry])=>previousSlot[extensionId] === entry)) {\n configs[slotName] = previousSlot;\n }\n }\n if (!changed) {\n // Nothing was added or altered, but an extension may have unmounted, which only shows up as a\n // missing entry.\n changed = Object.keys(oldConfigs).length !== Object.keys(configs).length || Object.values(oldConfigs).reduce((total, slot)=>total + Object.keys(slot).length, 0) !== entryCount;\n }\n if (changed) {\n extensionsConfigStore.setState({\n configs\n });\n }\n}\n/*\n * API\n *\n */ /**\n * This defines a configuration schema for a module. The schema tells the\n * configuration system how the module can be configured. It specifies\n * what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/en-US/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param moduleName Name of the module the schema is being defined for. Generally\n * should be the one in which the `defineConfigSchema` call takes place.\n * @param schema The config schema for the module\n */ function defineConfigSchema(moduleName, schema) {\n validateConfigSchema(moduleName, schema);\n const enhancedSchema = mergeDeepReplace(schema, implicitConfigSchema);\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: enhancedSchema\n },\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This alerts the configuration system that a module exists. This allows config to be\n * processed, while still allowing the extension system to know whether the module has\n * actually had its front bundle executed yet.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleWithConfigSystem(moduleName) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [moduleName]: implicitConfigSchema\n }\n }));\n}\n/**\n * This alerts the configuration system that a module has been loaded.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param moduleName\n */ function registerModuleLoad(moduleName) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n moduleLoaded: {\n ...state.moduleLoaded,\n [moduleName]: true\n }\n }));\n}\n/**\n * This allows the config system to support translation overrides for namespaces that\n * do not correspond to modules.\n *\n * This should only be used in esm-app-shell.\n *\n * @internal\n * @param namespace\n */ function registerTranslationNamespace(namespace) {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [namespace]: translationOverridesSchema\n }\n }));\n}\n/**\n * This defines a configuration schema for an extension. When a schema is defined\n * for an extension, that extension will receive the configuration corresponding\n * to that schema, rather than the configuration corresponding to the module\n * in which it is defined.\n *\n * The schema tells the configuration system how the module can be configured.\n * It specifies what makes configuration valid or invalid.\n *\n * See [Configuration System](https://o3-docs.openmrs.org/en-US/docs/configuration-system)\n * for more information about defining a config schema.\n *\n * @param extensionName Name of the extension the schema is being defined for.\n * Should match the `name` of one of the `extensions` entries defined in\n * the app's `routes.json` file.\n * @param schema The config schema for the extension\n */ function defineExtensionConfigSchema(extensionName, schema) {\n validateConfigSchema(extensionName, schema);\n const enhancedSchema = mergeDeepReplace(schema, implicitConfigSchema);\n const state = _state_js__rspack_import_3.configInternalStore.getState();\n if (state.schemas[extensionName]) {\n console.error(`Config schema for extension ${extensionName} already exists. If there are multiple extensions with this same name, one will probably crash.`);\n }\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n schemas: {\n ...state.schemas,\n [extensionName]: enhancedSchema\n }\n }));\n}\n/**\n * Provides configuration values programmatically. This is an alternative to\n * providing configuration through the config-file. Configuration provided this\n * way will be merged with configuration from other sources.\n *\n * @param config A configuration object to merge into the existing configuration.\n * @param sourceName An optional name to identify the source of this configuration,\n * used for debugging purposes. Defaults to 'provided'.\n */ function provide(config, sourceName = 'provided') {\n _state_js__rspack_import_3.configInternalStore.setState((state)=>({\n ...state,\n providedConfigs: [\n ...state.providedConfigs,\n {\n source: sourceName,\n config\n }\n ]\n }));\n}\n/**\n * Resolves with `select(state)` as soon as the store's state satisfies `ready`, leaving no\n * subscription behind: nothing subscribes at all when the store is already ready. That matters\n * because `getConfig` runs on every HTTP request, and a subscription that outlives its promise\n * both retains its closure forever and slows down every later write to that store.\n */ function whenStoreReady(store, ready, select) {\n return new Promise((resolve)=>{\n let unsubscribe;\n let resolved = false;\n function update(state) {\n if (!resolved && ready(state)) {\n resolved = true;\n resolve(select(state));\n unsubscribe?.();\n }\n }\n update(store.getState());\n if (!resolved) {\n unsubscribe = store.subscribe(update);\n }\n });\n}\n/**\n * A promise-based way to access the config as soon as it is fully loaded.\n * If it is already loaded, resolves the config in its present state.\n *\n * This is a useful function if you need to get the config in the course\n * of the execution of a function.\n *\n * @param moduleName The name of the module for which to look up the config\n */ function getConfig(moduleName) {\n return whenStoreReady((0,_state_js__rspack_import_3.getConfigStore)(moduleName), (state)=>Boolean(state.loaded && state.config), (state)=>(0,lodash_es__rspack_import_6[\"default\"])(state.config, [\n 'Display conditions',\n 'Translation overrides'\n ]));\n}\n/**\n * Retrieves translation overrides for an extension, optionally scoped to a specific\n * extension slot. When called with only a module name, retrieves module-level overrides.\n * Translation overrides allow customizing translated strings without modifying the\n * original translation files.\n *\n * @param moduleName The name of the module providing the translation context.\n * @param slotName Optional extension slot name to include slot-specific overrides.\n * @param extensionId Optional extension ID to include extension-specific overrides.\n * @returns A Promise resolving to an array of translation override objects.\n *\n * @internal\n */ function getTranslationOverrides(moduleName, slotName, extensionId) {\n const promises = [\n whenStoreReady((0,_state_js__rspack_import_3.getConfigStore)(moduleName), (state)=>Boolean(state.translationOverridesLoaded && state.config), (state)=>state.config['Translation overrides'] ?? {})\n ];\n if (slotName && extensionId) {\n promises.push(whenStoreReady((0,_state_js__rspack_import_3.getExtensionConfig)(slotName, extensionId), (state)=>Boolean(state.loaded && state.config), (state)=>state.config['Translation overrides'] ?? {}));\n }\n return Promise.all(promises);\n}\n/**\n * Validate and interpolate defaults for `providedConfig` according to `schema`\n *\n * @param schema a configuration schema\n * @param providedConfig an object of config values (without the top-level module name)\n * @param keyPathContext a dot-separated string which helps the user figure out where\n * the provided config came from\n * @returns The validated and processed configuration object with defaults applied.\n * @internal\n */ function processConfig(schema, providedConfig, keyPathContext) {\n validateStructure(schema, providedConfig, keyPathContext);\n const config = setDefaults(schema, providedConfig);\n runAllValidatorsInConfigTree(schema, config, keyPathContext);\n return config;\n}\nconst extensionConfigCache = new Map();\n/**\n * Returns the configuration for an extension. This configuration is specific\n * to the slot in which it is mounted, and its ID within that slot.\n *\n * The schema for that configuration is the extension schema. If no extension\n * schema has been provided, the schema used is the schema of the module in\n * which the extension is defined.\n *\n * @param slotModuleName The name of the module which defines the extension slot\n * @param extensionModuleName The name of the module which defines the extension (and therefore the config schema)\n * @param slotName The name of the extension slot where the extension is mounted\n * @param extensionId The ID of the extension in its slot\n * @param slotConfig The slot's configuration, gathered from every module that configures it\n */ function computeExtensionConfig(slotModuleName, extensionModuleName, slotName, extensionId, configState, tempConfigState, slotConfig) {\n const extensionName = getExtensionNameFromId(extensionId);\n const extensionConfigSchema = configState.schemas[extensionName];\n // JSON string of these elements should be unique-per-extension\n const cacheKey = JSON.stringify([\n slotName,\n extensionId,\n slotModuleName,\n extensionModuleName\n ]);\n const cached = extensionConfigCache.get(cacheKey);\n if (cached && cached.extensionSchema === extensionConfigSchema && cached.extensionModuleSchema === configState.schemas[extensionModuleName] && cached.providedConfigs === configState.providedConfigs && cached.temporaryConfig === tempConfigState.config) {\n return cached.config;\n }\n const nameOfSchemaSource = extensionConfigSchema ? extensionName : extensionModuleName;\n const providedConfigs = getProvidedConfigs(configState, tempConfigState);\n const sharedOverride = slotConfig?.configure?.[extensionId] ?? {};\n const slotModuleConfig = mergeConfigsFor(slotModuleName, providedConfigs);\n const configOverride = slotModuleConfig?.extensionSlots?.[slotName]?.configure?.[extensionId] ?? {};\n const extensionConfig = mergeConfigsFor(nameOfSchemaSource, providedConfigs);\n const combinedConfig = mergeConfigs([\n extensionConfig,\n sharedOverride,\n configOverride\n ]);\n const schema = extensionConfigSchema ?? configState.schemas[extensionModuleName];\n validateStructure(schema, combinedConfig, nameOfSchemaSource);\n const config = setDefaults(schema, combinedConfig);\n runAllValidatorsInConfigTree(schema, config, nameOfSchemaSource);\n delete config.extensionSlots;\n extensionConfigCache.set(cacheKey, {\n extensionSchema: extensionConfigSchema,\n extensionModuleSchema: configState.schemas[extensionModuleName],\n providedConfigs: configState.providedConfigs,\n temporaryConfig: tempConfigState.config,\n config\n });\n return config;\n}\nconst implementerToolsModuleCache = new Map();\nfunction getImplementerToolsConfig(configState, tempConfigState) {\n const annotatedSchemas = getAllSchemasWithValuesAndSources(configState.schemas);\n const configsAndSources = [\n ...configState.providedConfigs.map((c)=>[\n c.config,\n c.source\n ]),\n [\n tempConfigState.config,\n 'temporary config'\n ]\n ];\n // A module can be configured without having declared a schema, so the module list is the union\n // of both rather than just the schemas.\n const moduleNames = new Set(Object.keys(annotatedSchemas));\n for (const [config] of configsAndSources){\n for (const moduleName of Object.keys(config)){\n moduleNames.add(moduleName);\n }\n }\n const result = {};\n for (const moduleName of moduleNames){\n const annotatedSchema = annotatedSchemas[moduleName];\n const configSlices = configsAndSources.map(([config])=>config[moduleName]);\n const sources = configsAndSources.map(([, source])=>source);\n const cached = implementerToolsModuleCache.get(moduleName);\n if (cached && cached.annotatedSchema === annotatedSchema && cached.configSlices.length === configSlices.length && cached.configSlices.every((slice, i)=>slice === configSlices[i]) && cached.sources.every((source, i)=>source === sources[i])) {\n result[moduleName] = cached.result;\n continue;\n }\n let merged = annotatedSchema ?? {};\n configsAndSources.forEach(([, source], i)=>{\n const slice = configSlices[i];\n if (slice !== undefined) {\n merged = mergeDeepReplace(merged, createValuesAndSourcesTree(slice, source));\n }\n });\n implementerToolsModuleCache.set(moduleName, {\n annotatedSchema,\n configSlices,\n sources,\n result: merged\n });\n result[moduleName] = merged;\n }\n return result;\n}\n/**\n * Caching per module is what stops the walk being quadratic: defining one module's schema\n * recomputes every module.\n *\n * A module with no configuration of its own is published straight from this cache, so nothing may\n * mutate a tree it reads out of the implementer tools config — it is the cache entry.\n */ const schemaValuesAndSourcesCache = new Map();\nfunction getAllSchemasWithValuesAndSources(schemas) {\n const result = {};\n for (const [moduleName, schema] of Object.entries(schemas)){\n const cached = schemaValuesAndSourcesCache.get(moduleName);\n if (cached && cached.schema === schema) {\n result[moduleName] = cached.annotated;\n } else {\n const annotated = getSchemaWithValuesAndSources((0,lodash_es__rspack_import_7[\"default\"])(schema));\n schemaValuesAndSourcesCache.set(moduleName, {\n schema,\n annotated\n });\n result[moduleName] = annotated;\n }\n }\n return result;\n}\nfunction getSchemaWithValuesAndSources(schema) {\n if (schema.hasOwnProperty('_default')) {\n return {\n ...schema,\n _value: schema._default,\n _source: 'default'\n };\n } else if (isOrdinaryObject(schema)) {\n return Object.keys(schema).reduce((obj, key)=>{\n obj[key] = getSchemaWithValuesAndSources(schema[key]);\n return obj;\n }, {});\n } else {\n // at this point, the schema is bad and an error will have been logged during schema validation\n return {};\n }\n}\nfunction createValuesAndSourcesTree(config, source) {\n if (isOrdinaryObject(config)) {\n return Object.keys(config).reduce((obj, key)=>{\n obj[key] = createValuesAndSourcesTree(config[key], source);\n return obj;\n }, {});\n } else {\n return {\n _value: config,\n _source: source\n };\n }\n}\nfunction getExtensionSlotConfigs(configState, tempConfigState) {\n const allConfigs = mergeConfigs(getProvidedConfigs(configState, tempConfigState));\n const slotConfigPerModule = Object.keys(allConfigs).reduce((obj, key)=>{\n if (allConfigs[key]?.extensionSlots) {\n obj[key] = allConfigs[key]?.extensionSlots;\n }\n return obj;\n }, {});\n validateAllExtensionSlotConfigs(slotConfigPerModule);\n const slotConfigs = {};\n const configureBlocks = {};\n for (const configBySlotName of Object.values(slotConfigPerModule)){\n for (const [slotName, config] of Object.entries(configBySlotName)){\n slotConfigs[slotName] = config;\n if (config.configure) {\n var _configureBlocks, _slotName;\n ((_configureBlocks = configureBlocks)[_slotName = slotName] ?? (_configureBlocks[_slotName] = [])).push(config.configure);\n }\n }\n }\n for (const [slotName, blocks] of Object.entries(configureBlocks)){\n const configure = blocks.length === 1 ? blocks[0] : mergeConfigs(blocks);\n if (slotConfigs[slotName].configure !== configure) {\n slotConfigs[slotName] = {\n ...slotConfigs[slotName],\n configure\n };\n }\n }\n return slotConfigs;\n}\nfunction validateAllExtensionSlotConfigs(slotConfigPerModule) {\n for (let [moduleName, configBySlotName] of Object.entries(slotConfigPerModule)){\n for (let [slotName, config] of Object.entries(configBySlotName)){\n validateExtensionSlotConfig(config, moduleName, slotName);\n }\n }\n}\nfunction validateExtensionSlotConfig(config, moduleName, slotName) {\n const keyPath = `${moduleName}.extensionSlots.${slotName}`;\n const errorPrefix = `Extension slot config '${keyPath}'`;\n const invalidKeys = Object.keys(config).filter((k)=>![\n 'add',\n 'remove',\n 'order',\n 'configure'\n ].includes(k));\n if (invalidKeys.length) {\n logError(keyPath, errorPrefix + `' contains invalid keys '${invalidKeys.join(\"', '\")}'`);\n }\n if (config.add) {\n if (!Array.isArray(config.add) || !config.add.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.add' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.remove) {\n if (!Array.isArray(config.remove) || !config.remove.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.remove' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.order) {\n if (!Array.isArray(config.order) || !config.order.every((n)=>typeof n === 'string')) {\n logError(keyPath, errorPrefix + `.order' is invalid. Must be an array of strings (extension IDs)`);\n }\n }\n if (config.configure) {\n if (!isOrdinaryObject(config.configure)) {\n logError(keyPath, errorPrefix + `.configure' is invalid. Must be an object with extension IDs for keys`);\n }\n }\n}\nfunction getProvidedConfigs(configState, tempConfigState) {\n return [\n ...configState.providedConfigs.map((c)=>c.config),\n tempConfigState.config\n ];\n}\n/**\n * Validates the config schema for a module. Since problems identified here are programming errors\n * that hopefully will be caught during development, this function logs errors to the console directly;\n * it's fine if we spam the user with these errors.\n */ function validateConfigSchema(moduleName, schema, keyPath = '') {\n const updateMessage = `Please verify that you are running the latest version and, if so, alert the maintainer.`;\n for (const key of Object.keys(schema).filter((k)=>!k.startsWith('_'))){\n const thisKeyPath = keyPath + (keyPath && '.') + key;\n const schemaPart = schema[key];\n if (thisKeyPath === 'Display conditions') {\n console.error(`${moduleName} declares a configuration option called \"Display conditions\"; the \"Display conditions\" option is a reserved name. ${updateMessage}`);\n }\n if (thisKeyPath === 'Translation overrides') {\n console.error(`${moduleName} declares a configuration option called \"Translation overrides\"; the \"Translation overrides\" option is a reserved name. ${updateMessage}`);\n }\n if (!isOrdinaryObject(schemaPart)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}`);\n continue;\n }\n if (!schemaPart.hasOwnProperty('_default')) {\n // recurse for nested config keys\n validateConfigSchema(moduleName, schemaPart, thisKeyPath);\n }\n const elements = schemaPart._elements;\n if (hasObjectSchema(elements)) {\n validateConfigSchema(moduleName, elements, thisKeyPath + '._elements');\n }\n if (schemaPart._validators) {\n for (let validator of schemaPart._validators){\n if (typeof validator !== 'function') {\n console.error(`${moduleName} has invalid validator for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: validators must be functions that return either ` + `undefined or an error string. Received ${validator}.`);\n }\n }\n }\n const valueType = schemaPart._type;\n if (valueType && !Object.values(_types_js__rspack_import_0.Type).includes(valueType)) {\n console.error(`${moduleName} has invalid type for key '${thisKeyPath}' ${updateMessage}.` + `\\n\\nIf you're the maintainer: the allowed types are ${Object.values(_types_js__rspack_import_0.Type).join(', ')}. ` + `Received '${valueType}'`);\n }\n if (Object.keys(schemaPart).every((k)=>[\n '_description',\n '_validators',\n '_elements',\n '_type'\n ].includes(k)) && !keyPath.includes('._elements')) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: all config elements must have a default. ` + `Received ${JSON.stringify(schemaPart)}`);\n }\n if (elements && valueType && ![\n _types_js__rspack_import_0.Type.Array,\n _types_js__rspack_import_0.Type.Object\n ].includes(valueType)) {\n console.error(`${moduleName} has bad config schema definition for key '${thisKeyPath}'. ${updateMessage}.` + `\\n\\nIf you're the maintainer: the 'elements' key only works with '_type' equal to 'Array' or 'Object'. ` + `Received ${JSON.stringify(valueType)}`);\n }\n }\n}\nfunction getConfigForModule(moduleName, configState, tempConfigState) {\n const schema = configState.schemas[moduleName];\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n validateStructure(schema, inputConfig, moduleName);\n const config = setDefaults(schema, inputConfig);\n runAllValidatorsInConfigTree(schema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction getConfigForModuleImplicitSchema(moduleName, configState, tempConfigState) {\n const inputConfig = mergeConfigsFor(moduleName, getProvidedConfigs(configState, tempConfigState));\n const config = setDefaults(implicitConfigSchema, inputConfig);\n runAllValidatorsInConfigTree(implicitConfigSchema, config, moduleName);\n delete config.extensionSlots;\n return config;\n}\nfunction mergeConfigsFor(moduleName, allConfigs) {\n const allConfigsForModule = allConfigs.map(({ [moduleName]: c })=>c).filter((c)=>!!c);\n return mergeConfigs(allConfigsForModule);\n}\n/**\n * Merges a whole list at once, accumulating into one destination.\n */ function mergeConfigs(configs) {\n return configs.reduce((acc, config)=>(0,lodash_es__rspack_import_4[\"default\"])(acc, config, replaceArrays), {});\n}\n/**\n * Recursively check the provided config tree to make sure that all\n * of the provided properties exist in the schema, and that types are\n * correct. Does not run validators yet, since those will be run on\n * the config with the defaults filled in.\n */ function validateStructure(schema, config, keyPath = '') {\n // validate each constituent element\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (!schema.hasOwnProperty(key)) {\n if (!(key === 'extensionSlots' && keyPath !== '')) {\n logError(thisKeyPath, `Unknown config key '${thisKeyPath}' provided. Ignoring.`);\n }\n continue;\n }\n validateBranchStructure(schemaPart, value, thisKeyPath);\n }\n}\nfunction validateBranchStructure(schemaPart, value, keyPath) {\n checkType(keyPath, schemaPart._type, value);\n if (isOrdinaryObject(value)) {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Object) {\n // validate as freeform object\n validateFreeformObjectStructure(schemaPart, value, keyPath);\n } else if (!(schemaPart.hasOwnProperty('_default') || schemaPart.hasOwnProperty('_type'))) {\n // validate as normal nested config\n validateStructure(schemaPart, value, keyPath);\n }\n } else {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Array) {\n validateArrayStructure(schemaPart, value, keyPath);\n }\n }\n}\nfunction validateFreeformObjectStructure(freeformObjectSchema, config, keyPath) {\n if (freeformObjectSchema._elements) {\n for (const key of Object.keys(config)){\n const value = config[key];\n validateBranchStructure(freeformObjectSchema._elements, value, `${keyPath}.${key}`);\n }\n }\n}\nfunction validateArrayStructure(arraySchema, value, keyPath) {\n const validatedAsArray = checkType(keyPath, _types_js__rspack_import_0.Type.Array, value);\n if (!validatedAsArray) {\n return;\n }\n // if there is an array element object schema, verify that elements match it\n if (hasObjectSchema(arraySchema._elements)) {\n for(let i = 0; i < value.length; i++){\n validateBranchStructure(arraySchema._elements, value[i], `${keyPath}[${i}]`);\n }\n }\n for(let i = 0; i < value.length; i++){\n checkType(`${keyPath}[${i}]`, arraySchema._elements?._type, value[i]);\n }\n}\n/**\n * Run all the validators in the config tree. This should be run\n * on the config object after it has been filled in with all the defaults, since\n * higher-level validators may refer to default values.\n */ function runAllValidatorsInConfigTree(schema, config, keyPath = '') {\n // If `!schema`, there should have been a structural validation error printed already.\n if (schema) {\n if (config !== schema._default) {\n runValidators(keyPath, schema._validators, config);\n }\n if (isOrdinaryObject(config)) {\n for (const key of Object.keys(config)){\n const value = config[key];\n const thisKeyPath = keyPath + '.' + key;\n const schemaPart = schema[key];\n if (schema._type === _types_js__rspack_import_0.Type.Object && schema._elements) {\n runAllValidatorsInConfigTree(schema._elements, value, thisKeyPath);\n } else {\n runAllValidatorsInConfigTree(schemaPart, value, thisKeyPath);\n }\n }\n } else if (Array.isArray(config) && schema._elements) {\n for(let i = 0; i < config.length; i++){\n runAllValidatorsInConfigTree(schema._elements, config[i], `${keyPath}[${i}]`);\n }\n }\n }\n}\n/**\n * Run type validation for the value, logging any errors.\n * @returns true if validation passes, false otherwise\n */ function checkType(keyPath, _type, value) {\n if (_type) {\n const validator = {\n Array: _validators_type_validators_js__rspack_import_1.isArray,\n Boolean: _validators_type_validators_js__rspack_import_1.isBoolean,\n ConceptUuid: _validators_type_validators_js__rspack_import_1.isUuid,\n Number: _validators_type_validators_js__rspack_import_1.isNumber,\n Object: _validators_type_validators_js__rspack_import_1.isObject,\n String: _validators_type_validators_js__rspack_import_1.isString,\n UUID: _validators_type_validators_js__rspack_import_1.isUuid,\n PersonAttributeTypeUuid: _validators_type_validators_js__rspack_import_1.isUuid,\n PatientIdentifierTypeUuid: _validators_type_validators_js__rspack_import_1.isUuid\n };\n return runValidators(keyPath, [\n validator[_type]\n ], value);\n }\n return true;\n}\n/**\n * Runs validators, logging errors.\n * @returns true if all pass, false otherwise.\n */ function runValidators(keyPath, validators, value) {\n let returnValue = true;\n if (validators) {\n try {\n for (let validator of validators){\n const validatorResult = validator(value);\n if (typeof validatorResult === 'string') {\n const message = typeof value === 'object' ? `Invalid configuration for ${keyPath}: ${validatorResult}` : `Invalid configuration value ${value} for ${keyPath}: ${validatorResult}`;\n logError(keyPath, message);\n returnValue = false;\n }\n }\n } catch (e) {\n console.error(`Skipping invalid validator at \"${keyPath}\". Encountered error\\n\\t${e}`);\n }\n }\n return returnValue;\n}\n// Recursively fill in the config with values from the schema.\nconst setDefaults = (schema, inputConfig)=>{\n const config = structuredClone(inputConfig);\n if (!schema) {\n return config;\n }\n for (const key of Object.keys(schema)){\n const configPart = config[key];\n const schemaPart = schema[key];\n // The `schemaPart &&` clause of this `if` statement will only fail\n // if the schema is very invalid. It is there to prevent the app from\n // crashing completely, though it will produce unexpected behavior.\n // If this happens, there should be legible errors in the console from\n // the schema validator.\n if (schemaPart && (schemaPart.hasOwnProperty('_type') || schemaPart.hasOwnProperty('_default'))) {\n // We assume that schemaPart defines a config value, since it has\n // a property `_type` or `_default`.\n if (!config.hasOwnProperty(key)) {\n config[key] = schemaPart['_default'];\n }\n // We also check if it is an object or array with object elements, in which case we recurse\n const elements = schemaPart._elements;\n if (configPart && hasObjectSchema(elements)) {\n if (schemaPart._type === _types_js__rspack_import_0.Type.Array && Array.isArray(configPart)) {\n const configWithDefaults = configPart.map((conf)=>setDefaults(elements, conf));\n config[key] = configWithDefaults;\n } else if (schemaPart._type === _types_js__rspack_import_0.Type.Object) {\n for (let objectKey of Object.keys(configPart)){\n configPart[objectKey] = setDefaults(elements, configPart[objectKey]);\n }\n }\n }\n } else if (isOrdinaryObject(schemaPart)) {\n // Since schemaPart has no property \"_type\", if it's an ordinary object\n // (unlike, importantly, the validators array), we assume it is a parent config property.\n // We recurse to config[key] and schema[key]. Default config[key] to {}.\n const selectedConfigPart = configPart ?? {};\n // There will have been a validation error already if configPart is not a plain object.\n if (isOrdinaryObject(selectedConfigPart)) {\n config[key] = setDefaults(schemaPart, selectedConfigPart);\n }\n }\n }\n return config;\n};\nfunction hasObjectSchema(elementsSchema) {\n return !!elementsSchema && Object.keys(elementsSchema).filter((e)=>![\n '_default',\n '_validators'\n ].includes(e)).length > 0;\n}\nfunction isOrdinaryObject(value) {\n return typeof value === 'object' && !Array.isArray(value) && value !== null;\n}\n/** Keep track of which validation errors we have displayed. Each one should only be displayed once. */ let displayedValidationMessages = new Set();\nfunction logError(keyPath, message) {\n const key = `${keyPath}:::${message}`;\n // technically, this should not be possible, but because of how things wind-up transpiled, this isn't impossible\n if (!displayedValidationMessages) {\n displayedValidationMessages = new Set();\n }\n if (!displayedValidationMessages.has(key)) {\n console.error(message);\n displayedValidationMessages.add(key);\n }\n}\n/**\n * Normally, configuration errors are only displayed once. This function clears the list of\n * displayed errors, so that they will be displayed again.\n *\n * @internal\n */ function clearConfigErrors(keyPath) {\n if (keyPath) {\n displayedValidationMessages.forEach((key)=>{\n if (key.startsWith(keyPath)) {\n displayedValidationMessages.delete(key);\n }\n });\n } else {\n displayedValidationMessages.clear();\n }\n}\n/**\n * Cleans up all config store subscriptions and re-establishes them. This is primarily\n * useful for testing, where subscriptions set up at module load time need to be cleared\n * between tests to prevent infinite update loops. After clearing, subscriptions are\n * re-established so the config system continues to work normally.\n *\n * @internal\n */ function resetConfigSystem() {\n configSubscriptions.forEach((unsubscribe)=>unsubscribe());\n configSubscriptions.length = 0;\n // Cached configs are keyed on input identity, so a test that reuses the same schema or config\n // objects across cases would otherwise be served the previous case's result.\n moduleConfigCache.clear();\n extensionConfigCache.clear();\n schemaValuesAndSourcesCache.clear();\n implementerToolsModuleCache.clear();\n lastDerivation = null;\n entryOrigins = new WeakMap();\n setupConfigSubscriptions();\n}\n/**\n * Copied over from esm-extensions. It rightly belongs to that module, but esm-config\n * cannot depend on esm-extensions.\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\n/**\n * The translation overrides schema is used in the implicit schema given to every module;\n * plus any additional translation namespaces (at time of writing, this is just 'core').\n */ const translationOverridesSchema = {\n 'Translation overrides': {\n _description: 'Per-language overrides for frontend translations should be keyed by language code and each language dictionary contains the translation key and the display value',\n _type: _types_js__rspack_import_0.Type.Object,\n _default: {},\n _validators: [\n (0,_validators_validator_js__rspack_import_2.validator)((o)=>Object.keys(o).every((k)=>/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k)), (o)=>{\n const badKeys = Object.keys(o).filter((k)=>!/^[a-z]{2,3}(-[A-Z]{2,3})?$/.test(k));\n return `The 'Translation overrides' object should have language codes for keys. Language codes must be in the form of a two-to-three letter language code optionally followed by a hyphen and a two-to-three letter country code. The following keys do not conform: ${badKeys.join(', ')}.`;\n })\n ]\n }\n};\n/**\n * The implicitConfigSchema is implicitly included in every configuration schema\n */ const implicitConfigSchema = {\n 'Display conditions': {\n privileges: {\n _description: 'The privilege(s) the user must have to use this extension',\n _type: _types_js__rspack_import_0.Type.Array,\n _default: []\n },\n expression: {\n _description: 'The expression that determines whether the extension is displayed',\n _type: _types_js__rspack_import_0.Type.String,\n _default: undefined\n }\n },\n ...translationOverridesSchema\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1jb25maWcvZGlzdC9tb2R1bGUtY29uZmlnL21vZHVsZS1jb25maWcuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tY29uZmlnL2Rpc3QvbW9kdWxlLWNvbmZpZy9tb2R1bGUtY29uZmlnLmpzP2MzYTUiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIEBtb2R1bGUgQGNhdGVnb3J5IENvbmZpZyAqLyBpbXBvcnQgeyBjbG9uZURlZXAsIGlzRXF1YWwsIG1lcmdlV2l0aCwgb21pdCBhcyBsb2Rhc2hPbWl0IH0gZnJvbSBcImxvZGFzaC1lc1wiO1xuaW1wb3J0IHsgVHlwZSB9IGZyb20gXCIuLi90eXBlcy5qc1wiO1xuaW1wb3J0IHsgaXNBcnJheSwgaXNCb29sZWFuLCBpc1V1aWQsIGlzTnVtYmVyLCBpc09iamVjdCwgaXNTdHJpbmcgfSBmcm9tIFwiLi4vdmFsaWRhdG9ycy90eXBlLXZhbGlkYXRvcnMuanNcIjtcbmltcG9ydCB7IHZhbGlkYXRvciB9IGZyb20gXCIuLi92YWxpZGF0b3JzL3ZhbGlkYXRvci5qc1wiO1xuaW1wb3J0IHsgY29uZmlnRXh0ZW5zaW9uU3RvcmUsIGNvbmZpZ0ludGVybmFsU3RvcmUsIGdldENvbmZpZ1N0b3JlLCBnZXRFeHRlbnNpb25Db25maWcsIGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUsIGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSwgY2xlYXJDb25maWdEZXJpdmF0aW9uRXJyb3IsIGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZSwgaW52YWxpZGF0ZUltcGxlbWVudGVyVG9vbHNDb25maWcsIHJlY29yZENvbmZpZ0Rlcml2YXRpb25FcnJvciwgc2V0SW1wbGVtZW50ZXJUb29sc0NvbmZpZ1JlY29tcHV0ZXIsIHRlbXBvcmFyeUNvbmZpZ1N0b3JlIH0gZnJvbSBcIi4vc3RhdGUuanNcIjtcbi8qKlxuICogRGVlcCBtZXJnZSB0d28gb2JqZWN0cywgd2l0aCByaWdodC1zaWRlIHZhbHVlcyB0YWtpbmcgcHJlY2VkZW5jZS5cbiAqIEFycmF5cyBhcmUgcmVwbGFjZWQgZW50aXJlbHkgKG5vdCBtZXJnZWQgYnkgaW5kZXgpLCBtYXRjaGluZyB0aGVcbiAqIGJlaGF2aW9yIG9mIHJhbWRhJ3MgbWVyZ2VEZWVwUmlnaHQuXG4gKi8gZnVuY3Rpb24gcmVwbGFjZUFycmF5cyhfb2JqVmFsdWUsIHNyY1ZhbHVlKSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc3JjVmFsdWUpKSB7XG4gICAgICAgIHJldHVybiBzcmNWYWx1ZTtcbiAgICB9XG59XG5mdW5jdGlvbiBtZXJnZURlZXBSZXBsYWNlKGxlZnQsIHJpZ2h0KSB7XG4gICAgcmV0dXJuIG1lcmdlV2l0aCh7fSwgbGVmdCwgcmlnaHQsIHJlcGxhY2VBcnJheXMpO1xufVxuLyoqXG4gKiBTdG9yZSBzZXR1cFxuICpcbiAqXG4gKiBTZXQgdXAgc3RvcmVzIGFuZCBzdWJzY3JpcHRpb25zIHNvIHRoYXQgaW5wdXRzIGdldCBwcm9jZXNzZWQgYXBwcm9wcmlhdGVseS5cbiAqXG4gKiBUaGVyZSBhcmUgKmlucHV0KiBzdG9yZXMgYW5kICpvdXRwdXQqIHN0b3Jlcy4gVGhlICppbnB1dCogc3RvcmVzXG4gKiBhcmUgY29uZmlnSW50ZXJuYWxTdG9yZSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUsIGFuZCBjb25maWdFeHRlbnNpb25TdG9yZS4gVGhlXG4gKiBvdXRwdXQgc3RvcmVzIGFyZSBzZXQgaW4gdGhlIGBjb21wdXRlLi4uYCBmdW5jdGlvbnMuIFRoZXkgYXJlIHRoZSBtb2R1bGVcbiAqIGNvbmZpZyBzdG9yZXMsIHRoZSBleHRlbnNpb24gc2xvdCBjb25maWcgc3RvcmVzIChieSBtb2R1bGUpLCB0aGUgZXh0ZW5zaW9uXG4gKiBjb25maWcgc3RvcmVzLCBhbmQgdGhlIGltcGxlbWVudGVyIHRvb2xzIGNvbmZpZyBzdG9yZS5cbiAqXG4gKiBUaGlzIGNvZGUgc2V0cyB1cCB0aGUgc3Vic2NyaXB0aW9ucyBzbyB0aGF0IHdoZW4gYW4gaW5wdXQgc3RvcmUgY2hhbmdlcyxcbiAqIHRoZSBjb3JyZWN0IHNldCBvZiBvdXRwdXQgc3RvcmVzIGFyZSB1cGRhdGVkLlxuICpcbiAqIEFsbCBgY29tcHV0ZS4uLmAgZnVuY3Rpb25zIGV4Y2VwdCBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGFyZSBwdXJlXG4gKiAob3IgYXJlIHN1cHBvc2VkIHRvIGJlKSwgb3RoZXIgdGhhbiB0aGUgZmFjdCB0aGF0IHRoZXkgYWxsIGBzZXRTdGF0ZWBcbiAqIHN0b3JlIHZhbHVlcyBhdCB0aGUgZW5kLiBgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3NgIGNhbGxzIGBnZXRHbG9iYWxTdG9yZWAsXG4gKiB3aGljaCBjcmVhdGVzIHN0b3Jlcy5cbiAqLyAvLyBTdG9yZSB1bnN1YnNjcmliZSBmdW5jdGlvbnMgdG8gYWxsb3cgY2xlYW51cCAoZS5nLiwgaW4gdGVzdHMgb3IgaG90IG1vZHVsZSByZWxvYWRpbmcpXG5jb25zdCBjb25maWdTdWJzY3JpcHRpb25zID0gW107XG4vKipcbiAqIFJlY29tcHV0ZXMgYWxsIGNvbmZpZ3VyYXRpb24gZGVyaXZlZCBzdG9yZXMgYmFzZWQgb24gY3VycmVudCBzdGF0ZSBvZiBpbnB1dCBzdG9yZXMuXG4gKiBDYWxsZWQgd2hlbmV2ZXIgYW55IGlucHV0IHN0b3JlIChjb25maWdJbnRlcm5hbFN0b3JlLCB0ZW1wb3JhcnlDb25maWdTdG9yZSwgY29uZmlnRXh0ZW5zaW9uU3RvcmUpIGNoYW5nZXMuXG4gKi8gZnVuY3Rpb24gcmVjb21wdXRlQWxsQ29uZmlncygpIHtcbiAgICBjb25zdCBjb25maWdTdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCB0ZW1wQ29uZmlnU3RhdGUgPSB0ZW1wb3JhcnlDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGV4dGVuc2lvblN0YXRlID0gY29uZmlnRXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICAvLyBNb3VudGluZyBhbiBleHRlbnNpb24gY2hhbmdlcyBvbmx5IGBjb25maWdFeHRlbnNpb25TdG9yZWAsIHdoaWNoIG9ubHkgdGhlIGV4dGVuc2lvbiBjb25maWdzXG4gICAgLy8gZGVwZW5kIG9uLCBzbyB0aGUgcmVzdCBvZiB0aGUgbGFzdCBkZXJpdmF0aW9uIGlzIHJldXNlZC5cbiAgICBjb25zdCBjb25maWdJbnB1dHNVbmNoYW5nZWQgPSBsYXN0RGVyaXZhdGlvbj8uY29uZmlnU3RhdGUgPT09IGNvbmZpZ1N0YXRlICYmIGxhc3REZXJpdmF0aW9uLnRlbXBDb25maWdTdGF0ZSA9PT0gdGVtcENvbmZpZ1N0YXRlO1xuICAgIGlmIChjb25maWdJbnB1dHNVbmNoYW5nZWQpIHtcbiAgICAgICAgY29tcHV0ZUV4dGVuc2lvbkNvbmZpZ3MoY29uZmlnU3RhdGUsIGV4dGVuc2lvblN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUsIGxhc3REZXJpdmF0aW9uLnNsb3RDb25maWdzLCB0cnVlKTtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb21wdXRlTW9kdWxlQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpO1xuICAgIGNvbnN0IHNsb3RDb25maWdzID0gZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29tcHV0ZUV4dGVuc2lvblNsb3RDb25maWdzKHNsb3RDb25maWdzKTtcbiAgICBjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyhjb25maWdTdGF0ZSwgZXh0ZW5zaW9uU3RhdGUsIHRlbXBDb25maWdTdGF0ZSwgc2xvdENvbmZpZ3MsIGZhbHNlKTtcbiAgICAvLyBSZWNvcmRlZCBvbmx5IGFmdGVyIHRoZSBvdXRwdXRzIGFib3ZlIGFyZSB3cml0dGVuLCBzbyBhIGZhaWx1cmUgZm9yY2VzIGEgZnVsbCBkZXJpdmF0aW9uIG5leHQgdGltZS5cbiAgICBsYXN0RGVyaXZhdGlvbiA9IHtcbiAgICAgICAgY29uZmlnU3RhdGUsXG4gICAgICAgIHRlbXBDb25maWdTdGF0ZSxcbiAgICAgICAgc2xvdENvbmZpZ3NcbiAgICB9O1xuICAgIC8vIExhc3QsIGJlY2F1c2UgYSBmYWlsdXJlIGhlcmUgbXVzdCBub3Qgc2tpcCB0aGUgb3V0cHV0cyBhYm92ZS4gT25seSBrZXB0IGN1cnJlbnQgd2hpbGUgdGhlXG4gICAgLy8gaW1wbGVtZW50ZXIgdG9vbHMgYXJlIHdhdGNoaW5nIGl0OyBvdGhlcndpc2UgZGVyaXZlZCBvbiByZWFkLlxuICAgIGludmFsaWRhdGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKCk7XG59XG4vKiogVGhlIGlucHV0cyB0aGUgb3V0cHV0cyB3ZXJlIGxhc3QgZnVsbHkgZGVyaXZlZCBmcm9tLCBjb21wYXJlZCBieSBpZGVudGl0eS4gKi8gbGV0IGxhc3REZXJpdmF0aW9uID0gbnVsbDtcbi8qKlxuICogVGhlIG1vdW50ZWQgZXh0ZW5zaW9uIGVhY2ggZXh0ZW5zaW9uIGNvbmZpZyBlbnRyeSB3YXMgZGVyaXZlZCBmb3IuIEFuIGV4dGVuc2lvbiBJRCBjYW4gYmVcbiAqIG1vdW50ZWQgdW5kZXIgYSBkaWZmZXJlbnQgbW9kdWxlIHdoaWxlIGl0cyBzbG90IGFuZCBJRCBzdGF5IHRoZSBzYW1lLCBzbyBhbiBlbnRyeSBpcyBvbmx5XG4gKiBjdXJyZW50IGlmIGl0cyBtb2R1bGVzIG1hdGNoIHRvby5cbiAqLyBsZXQgZW50cnlPcmlnaW5zID0gbmV3IFdlYWtNYXAoKTtcbmZ1bmN0aW9uIHNldHVwQ29uZmlnU3Vic2NyaXB0aW9ucygpIHtcbiAgICAvLyBSZWdpc3RlcmVkIGhlcmUgcmF0aGVyIHRoYW4gYXQgbW9kdWxlIGxvYWQgc28gdGhhdCBgcmVzZXRDb25maWdTeXN0ZW1gIHJlc3RvcmVzIGl0LlxuICAgIHNldEltcGxlbWVudGVyVG9vbHNDb25maWdSZWNvbXB1dGVyKCgpPT5jb21wdXRlSW1wbGVtZW50ZXJUb29sc0NvbmZpZyhjb25maWdJbnRlcm5hbFN0b3JlLmdldFN0YXRlKCksIHRlbXBvcmFyeUNvbmZpZ1N0b3JlLmdldFN0YXRlKCkpKTtcbiAgICAvLyBJbml0aWFsIGNvbXB1dGF0aW9uXG4gICAgcmVjb21wdXRlQWxsQ29uZmlncygpO1xuICAgIC8vIFN1YnNjcmliZSB0byBhbGwgaW5wdXQgc3RvcmVzIHdpdGggYSBzaW5nbGUgaGFuZGxlclxuICAgIC8vIFRoaXMgZW5zdXJlcyB3ZSBvbmx5IHJlY29tcHV0ZSBvbmNlIGV2ZW4gaWYgbXVsdGlwbGUgc3RvcmVzIGNoYW5nZSBzaW11bHRhbmVvdXNseVxuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMucHVzaChjb25maWdJbnRlcm5hbFN0b3JlLnN1YnNjcmliZShyZWNvbXB1dGVBbGxDb25maWdzU2FmZWx5KSwgdGVtcG9yYXJ5Q29uZmlnU3RvcmUuc3Vic2NyaWJlKHJlY29tcHV0ZUFsbENvbmZpZ3NTYWZlbHkpLCBjb25maWdFeHRlbnNpb25TdG9yZS5zdWJzY3JpYmUocmVjb21wdXRlQWxsQ29uZmlnc1NhZmVseSkpO1xufVxuLyoqIEVuc3VyZSB0aGF0IHdlIGRvIG5vdCB0aHJvdyBkdXJpbmcgYSBzdG9yZSBzdWJzY3JpcHRpb24gKi8gZnVuY3Rpb24gcmVjb21wdXRlQWxsQ29uZmlnc1NhZmVseSgpIHtcbiAgICBjbGVhckNvbmZpZ0Rlcml2YXRpb25FcnJvcigpO1xuICAgIHRyeSB7XG4gICAgICAgIHJlY29tcHV0ZUFsbENvbmZpZ3MoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJlY29yZENvbmZpZ0Rlcml2YXRpb25FcnJvcihlKTtcbiAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIHJlY29tcHV0ZSB0aGUgY29uZmlndXJhdGlvbicsIGUpO1xuICAgIH1cbn1cbi8vIFNldCB1cCBzdWJzY3JpcHRpb25zIGF0IG1vZHVsZSBsb2FkIHRpbWVcbnNldHVwQ29uZmlnU3Vic2NyaXB0aW9ucygpO1xuY29uc3QgbW9kdWxlQ29uZmlnQ2FjaGUgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBjb21wdXRlTW9kdWxlQ29uZmlnKHN0YXRlLCB0ZW1wU3RhdGUpIHtcbiAgICBmb3IgKGxldCBtb2R1bGVOYW1lIG9mIE9iamVjdC5rZXlzKHN0YXRlLnNjaGVtYXMpKXtcbiAgICAgICAgLy8gQXQgdGhpcyBwb2ludCB0aGUgc2NoZW1hIGNvdWxkIGJlIGVpdGhlciBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgb3IgdGhlIGFjdHVhbGx5XG4gICAgICAgIC8vIGRlZmluZWQgc2NoZW1hLiBXZSBydW4gd2l0aCBqdXN0IHRoZSBpbXBsaWNpdCBzY2hlbWEgYmVjYXVzZSB3ZSB3YW50IHRvIHBvcHVsYXRlXG4gICAgICAgIC8vIHRoZSBjb25maWcgc3RvcmUgd2l0aCB0aGUgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIGFzIHNvb24gYXMgcG9zc2libGUuIEluIGZhY3QsIHRoZVxuICAgICAgICAvLyB0cmFuc2xhdGlvbiBzeXN0ZW0gd2lsbCB0aHJvdyBmb3IgU3VzcGVuc2UgdW50aWwgdGhlIHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBhcmVcbiAgICAgICAgLy8gYXZhaWxhYmxlLCB3aGljaCBhcyBvZiB0aGlzIHdyaXRpbmcgYmxvY2tzIHRoZSBzY2hlbWEgZGVmaW5pdGlvbiBmcm9tIG9jY3VycmluZ1xuICAgICAgICAvLyBmb3IgbW9kdWxlcyBsb2FkZWQgYmFzZWQgb24gdGhlaXIgZXh0ZW5zaW9ucy5cbiAgICAgICAgY29uc3QgbW9kdWxlU3RvcmUgPSBnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKTtcbiAgICAgICAgY29uc3Qgc2NoZW1hID0gc3RhdGUuc2NoZW1hc1ttb2R1bGVOYW1lXTtcbiAgICAgICAgY29uc3QgbW9kdWxlTG9hZGVkID0gQm9vbGVhbihzdGF0ZS5tb2R1bGVMb2FkZWRbbW9kdWxlTmFtZV0pO1xuICAgICAgICBjb25zdCBjYWNoZWQgPSBtb2R1bGVDb25maWdDYWNoZS5nZXQobW9kdWxlTmFtZSk7XG4gICAgICAgIGxldCBuZXdTdGF0ZTtcbiAgICAgICAgaWYgKGNhY2hlZCAmJiBjYWNoZWQuc2NoZW1hID09PSBzY2hlbWEgJiYgY2FjaGVkLm1vZHVsZUxvYWRlZCA9PT0gbW9kdWxlTG9hZGVkICYmIGNhY2hlZC5wcm92aWRlZENvbmZpZ3MgPT09IHN0YXRlLnByb3ZpZGVkQ29uZmlncyAmJiBjYWNoZWQudGVtcG9yYXJ5Q29uZmlnID09PSB0ZW1wU3RhdGUuY29uZmlnKSB7XG4gICAgICAgICAgICBuZXdTdGF0ZSA9IGNhY2hlZC5zdGF0ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IG1vZHVsZUxvYWRlZCA/IGdldENvbmZpZ0Zvck1vZHVsZShtb2R1bGVOYW1lLCBzdGF0ZSwgdGVtcFN0YXRlKSA6IGdldENvbmZpZ0Zvck1vZHVsZUltcGxpY2l0U2NoZW1hKG1vZHVsZU5hbWUsIHN0YXRlLCB0ZW1wU3RhdGUpO1xuICAgICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAgICAgdHJhbnNsYXRpb25PdmVycmlkZXNMb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgbG9hZGVkOiBtb2R1bGVMb2FkZWQsXG4gICAgICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgbW9kdWxlQ29uZmlnQ2FjaGUuc2V0KG1vZHVsZU5hbWUsIHtcbiAgICAgICAgICAgICAgICBzY2hlbWEsXG4gICAgICAgICAgICAgICAgbW9kdWxlTG9hZGVkLFxuICAgICAgICAgICAgICAgIHByb3ZpZGVkQ29uZmlnczogc3RhdGUucHJvdmlkZWRDb25maWdzLFxuICAgICAgICAgICAgICAgIHRlbXBvcmFyeUNvbmZpZzogdGVtcFN0YXRlLmNvbmZpZyxcbiAgICAgICAgICAgICAgICBzdGF0ZTogbmV3U3RhdGVcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFdyaXRpbmcgdW5jb25kaXRpb25hbGx5IHdvdWxkIGhhbmQgZXZlcnkgYHVzZUNvbmZpZ2AgY29uc3VtZXIgaW4gdGhlIGFwcGxpY2F0aW9uIGEgbmV3XG4gICAgICAgIC8vIG9iamVjdCDigJQgYW5kIGEgcmUtcmVuZGVyIOKAlCB3aGVuZXZlciBhbnkgbW9kdWxlIG9yIGV4dGVuc2lvbiBhbnl3aGVyZSBpcyBsb2FkZWQuXG4gICAgICAgIGNvbnN0IG9sZFN0YXRlID0gbW9kdWxlU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICAgICAgaWYgKG9sZFN0YXRlLmxvYWRlZCAhPT0gbmV3U3RhdGUubG9hZGVkIHx8IG9sZFN0YXRlLnRyYW5zbGF0aW9uT3ZlcnJpZGVzTG9hZGVkICE9PSBuZXdTdGF0ZS50cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZCB8fCAhaXNFcXVhbChvbGRTdGF0ZS5jb25maWcsIG5ld1N0YXRlLmNvbmZpZykpIHtcbiAgICAgICAgICAgIG1vZHVsZVN0b3JlLnNldFN0YXRlKG5ld1N0YXRlKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVFeHRlbnNpb25TbG90Q29uZmlncyhzbG90Q29uZmlncykge1xuICAgIGNvbnN0IHNsb3RTdG9yZSA9IGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUoKTtcbiAgICBjb25zdCBvbGRTbG90cyA9IHNsb3RTdG9yZS5nZXRTdGF0ZSgpLnNsb3RzO1xuICAgIGNvbnN0IHNsb3RzID0ge307XG4gICAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IFtzbG90TmFtZSwgY29uZmlnXSBvZiBPYmplY3QuZW50cmllcyhzbG90Q29uZmlncykpe1xuICAgICAgICBjb25zdCBwcmV2aW91cyA9IG9sZFNsb3RzW3Nsb3ROYW1lXTtcbiAgICAgICAgLy8gRW50cmllcyBrZWVwIHRoZWlyIGlkZW50aXR5IHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gYmVoaW5kIHRoZW0gaGFzbid0IGNoYW5nZWQsIHNvIHRoYXRcbiAgICAgICAgLy8gY2hhbmdpbmcgb25lIHNsb3QncyBjb25maWd1cmF0aW9uIGRvZXNuJ3QgaW52YWxpZGF0ZSBldmVyeSBvdGhlciBjb25maWd1cmVkIHNsb3QuXG4gICAgICAgIGlmIChwcmV2aW91cz8ubG9hZGVkICYmIGlzRXF1YWwocHJldmlvdXMuY29uZmlnLCBjb25maWcpKSB7XG4gICAgICAgICAgICBzbG90c1tzbG90TmFtZV0gPSBwcmV2aW91cztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNsb3RzW3Nsb3ROYW1lXSA9IHtcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgLy8gQnVpbHQgZnJvbSBzY3JhdGNoIHJhdGhlciB0aGFuIG1lcmdlZCBvdmVyIHRoZSBwcmV2aW91cyBzdGF0ZTogYSBzbG90IHdob3NlIGNvbmZpZ3VyYXRpb25cbiAgICAvLyBoYXMgYmVlbiByZW1vdmVkIOKAlCBjbGVhcmluZyB0aGUgdGVtcG9yYXJ5IGNvbmZpZywgc2F5IOKAlCBoYXMgdG8gbG9zZSBpdHMgZW50cnksIG9yIHRoZSBvbGRcbiAgICAvLyBjb25maWd1cmF0aW9uIHN0YXlzIGluIGZvcmNlIHVudGlsIHRoZSBwYWdlIGlzIHJlbG9hZGVkLlxuICAgIGlmIChjaGFuZ2VkIHx8IE9iamVjdC5rZXlzKG9sZFNsb3RzKS5sZW5ndGggIT09IE9iamVjdC5rZXlzKHNsb3RzKS5sZW5ndGgpIHtcbiAgICAgICAgc2xvdFN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNsb3RzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGNvbXB1dGVJbXBsZW1lbnRlclRvb2xzQ29uZmlnKHN0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBvbGRTdGF0ZSA9IGltcGxlbWVudGVyVG9vbHNDb25maWdTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIGNvbnN0IGNvbmZpZyA9IGdldEltcGxlbWVudGVyVG9vbHNDb25maWcoc3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICAgIGNvbmZpZ1xuICAgIH07XG4gICAgLy8gVXNlIGRlZXAgZXF1YWxpdHkgb24gdGhlIGFjdHVhbCBjb25maWcgY29udGVudCwgbm90IHRoZSB3cmFwcGVyIG9iamVjdFxuICAgIGlmICghaXNFcXVhbChvbGRTdGF0ZS5jb25maWcsIG5ld1N0YXRlLmNvbmZpZykpIHtcbiAgICAgICAgaW1wbGVtZW50ZXJUb29sc0NvbmZpZ1N0b3JlLnNldFN0YXRlKG5ld1N0YXRlKTtcbiAgICB9XG59XG5mdW5jdGlvbiBjb21wdXRlRXh0ZW5zaW9uQ29uZmlncyhjb25maWdTdGF0ZSwgZXh0ZW5zaW9uU3RhdGUsIHRlbXBDb25maWdTdGF0ZSwgc2xvdENvbmZpZ3MsIGNvbmZpZ0lucHV0c1VuY2hhbmdlZCkge1xuICAgIGNvbnN0IGV4dGVuc2lvbnNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSgpO1xuICAgIGNvbnN0IG9sZENvbmZpZ3MgPSBleHRlbnNpb25zQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKS5jb25maWdzO1xuICAgIGNvbnN0IGNvbmZpZ3MgPSB7fTtcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuICAgIGxldCBlbnRyeUNvdW50ID0gMDtcbiAgICAvLyBXZSBhc3N1bWUgdGhhdCB0aGUgbW9kdWxlIHNjaGVtYSBoYXMgYWxyZWFkeSBiZWVuIGRlZmluZWQsIHNpbmNlIHRoZSBleHRlbnNpb25cbiAgICAvLyBpdCBjb250YWlucyBpcyBtb3VudGVkLlxuICAgIGZvciAobGV0IGV4dGVuc2lvbiBvZiBleHRlbnNpb25TdGF0ZS5tb3VudGVkRXh0ZW5zaW9ucyl7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gb2xkQ29uZmlnc1tleHRlbnNpb24uc2xvdE5hbWVdPy5bZXh0ZW5zaW9uLmV4dGVuc2lvbklkXTtcbiAgICAgICAgbGV0IGVudHJ5O1xuICAgICAgICBjb25zdCBvcmlnaW4gPSBwcmV2aW91cyAmJiBlbnRyeU9yaWdpbnMuZ2V0KHByZXZpb3VzKTtcbiAgICAgICAgaWYgKGNvbmZpZ0lucHV0c1VuY2hhbmdlZCAmJiBwcmV2aW91cz8ubG9hZGVkICYmIG9yaWdpbj8uc2xvdE1vZHVsZU5hbWUgPT09IGV4dGVuc2lvbi5zbG90TW9kdWxlTmFtZSAmJiBvcmlnaW4uZXh0ZW5zaW9uTW9kdWxlTmFtZSA9PT0gZXh0ZW5zaW9uLmV4dGVuc2lvbk1vZHVsZU5hbWUpIHtcbiAgICAgICAgICAgIC8vIERlcml2ZWQgZnJvbSB0aGVzZSBzYW1lIGlucHV0cyBieSB0aGUgcHJldmlvdXMgcnVuLCBzbyBpdCBpcyBzdGlsbCBjdXJyZW50LlxuICAgICAgICAgICAgZW50cnkgPSBwcmV2aW91cztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IGNvbXB1dGVFeHRlbnNpb25Db25maWcoZXh0ZW5zaW9uLnNsb3RNb2R1bGVOYW1lLCBleHRlbnNpb24uZXh0ZW5zaW9uTW9kdWxlTmFtZSwgZXh0ZW5zaW9uLnNsb3ROYW1lLCBleHRlbnNpb24uZXh0ZW5zaW9uSWQsIGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUsIHNsb3RDb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV0pO1xuICAgICAgICAgICAgLy8gRW50cmllcyBrZWVwIHRoZWlyIGlkZW50aXR5IHdoZW4gdGhlIGNvbmZpZ3VyYXRpb24gYmVoaW5kIHRoZW0gaGFzbid0IGNoYW5nZWQsIHNvIHRoYXRcbiAgICAgICAgICAgIC8vIG1vdW50aW5nIG9uZSBleHRlbnNpb24gZG9lc24ndCBoYW5kIGV2ZXJ5IG90aGVyIG1vdW50ZWQgZXh0ZW5zaW9uIGEgbmV3IGNvbmZpZyBvYmplY3QuXG4gICAgICAgICAgICBlbnRyeSA9IHByZXZpb3VzPy5sb2FkZWQgJiYgaXNFcXVhbChwcmV2aW91cy5jb25maWcsIGNvbmZpZykgPyBwcmV2aW91cyA6IHtcbiAgICAgICAgICAgICAgICBjb25maWcsXG4gICAgICAgICAgICAgICAgbG9hZGVkOiB0cnVlXG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICAgIGVudHJ5T3JpZ2lucy5zZXQoZW50cnksIGV4dGVuc2lvbik7XG4gICAgICAgIGlmIChlbnRyeSAhPT0gcHJldmlvdXMpIHtcbiAgICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICghY29uZmlnc1tleHRlbnNpb24uc2xvdE5hbWVdKSB7XG4gICAgICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV0gPSB7fTtcbiAgICAgICAgfVxuICAgICAgICBjb25maWdzW2V4dGVuc2lvbi5zbG90TmFtZV1bZXh0ZW5zaW9uLmV4dGVuc2lvbklkXSA9IGVudHJ5O1xuICAgICAgICBlbnRyeUNvdW50Kys7XG4gICAgfVxuICAgIC8vIFNsb3RzIGtlZXAgdGhlaXIgaWRlbnRpdHkgdG9vIHdoZW4gbm9uZSBvZiB0aGVpciBlbnRyaWVzIGNoYW5nZWQuIFN1YnNjcmliZXJzIGNvbXBhcmUgdGhlc2VcbiAgICAvLyBwZXItc2xvdCBvYmplY3RzIHRvIHdvcmsgb3V0IHdoaWNoIHNsb3RzIHRvIHJlLWRlcml2ZSwgc28gaGFuZGluZyBvdXQgYSBmcmVzaCBvbmUgZm9yIGV2ZXJ5XG4gICAgLy8gc2xvdCBvbiBldmVyeSB3cml0ZSB3b3VsZCBtYXJrIGV2ZXJ5IHNsb3Qgd2l0aCBhIG1vdW50ZWQgZXh0ZW5zaW9uIGRpcnR5LlxuICAgIGZvciAoY29uc3QgW3Nsb3ROYW1lLCBzbG90Q29uZmlnc10gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlncykpe1xuICAgICAgICBjb25zdCBwcmV2aW91c1Nsb3QgPSBvbGRDb25maWdzW3Nsb3ROYW1lXTtcbiAgICAgICAgaWYgKHByZXZpb3VzU2xvdCAmJiBPYmplY3Qua2V5cyhwcmV2aW91c1Nsb3QpLmxlbmd0aCA9PT0gT2JqZWN0LmtleXMoc2xvdENvbmZpZ3MpLmxlbmd0aCAmJiBPYmplY3QuZW50cmllcyhzbG90Q29uZmlncykuZXZlcnkoKFtleHRlbnNpb25JZCwgZW50cnldKT0+cHJldmlvdXNTbG90W2V4dGVuc2lvbklkXSA9PT0gZW50cnkpKSB7XG4gICAgICAgICAgICBjb25maWdzW3Nsb3ROYW1lXSA9IHByZXZpb3VzU2xvdDtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWNoYW5nZWQpIHtcbiAgICAgICAgLy8gTm90aGluZyB3YXMgYWRkZWQgb3IgYWx0ZXJlZCwgYnV0IGFuIGV4dGVuc2lvbiBtYXkgaGF2ZSB1bm1vdW50ZWQsIHdoaWNoIG9ubHkgc2hvd3MgdXAgYXMgYVxuICAgICAgICAvLyBtaXNzaW5nIGVudHJ5LlxuICAgICAgICBjaGFuZ2VkID0gT2JqZWN0LmtleXMob2xkQ29uZmlncykubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhjb25maWdzKS5sZW5ndGggfHwgT2JqZWN0LnZhbHVlcyhvbGRDb25maWdzKS5yZWR1Y2UoKHRvdGFsLCBzbG90KT0+dG90YWwgKyBPYmplY3Qua2V5cyhzbG90KS5sZW5ndGgsIDApICE9PSBlbnRyeUNvdW50O1xuICAgIH1cbiAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgICBleHRlbnNpb25zQ29uZmlnU3RvcmUuc2V0U3RhdGUoe1xuICAgICAgICAgICAgY29uZmlnc1xuICAgICAgICB9KTtcbiAgICB9XG59XG4vKlxuICogQVBJXG4gKlxuICovIC8qKlxuICogVGhpcyBkZWZpbmVzIGEgY29uZmlndXJhdGlvbiBzY2hlbWEgZm9yIGEgbW9kdWxlLiBUaGUgc2NoZW1hIHRlbGxzIHRoZVxuICogY29uZmlndXJhdGlvbiBzeXN0ZW0gaG93IHRoZSBtb2R1bGUgY2FuIGJlIGNvbmZpZ3VyZWQuIEl0IHNwZWNpZmllc1xuICogd2hhdCBtYWtlcyBjb25maWd1cmF0aW9uIHZhbGlkIG9yIGludmFsaWQuXG4gKlxuICogU2VlIFtDb25maWd1cmF0aW9uIFN5c3RlbV0oaHR0cHM6Ly9vMy1kb2NzLm9wZW5tcnMub3JnL2VuLVVTL2RvY3MvY29uZmlndXJhdGlvbi1zeXN0ZW0pXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBkZWZpbmluZyBhIGNvbmZpZyBzY2hlbWEuXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgTmFtZSBvZiB0aGUgbW9kdWxlIHRoZSBzY2hlbWEgaXMgYmVpbmcgZGVmaW5lZCBmb3IuIEdlbmVyYWxseVxuICogICBzaG91bGQgYmUgdGhlIG9uZSBpbiB3aGljaCB0aGUgYGRlZmluZUNvbmZpZ1NjaGVtYWAgY2FsbCB0YWtlcyBwbGFjZS5cbiAqIEBwYXJhbSBzY2hlbWEgVGhlIGNvbmZpZyBzY2hlbWEgZm9yIHRoZSBtb2R1bGVcbiAqLyBleHBvcnQgZnVuY3Rpb24gZGVmaW5lQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYSkge1xuICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYSk7XG4gICAgY29uc3QgZW5oYW5jZWRTY2hlbWEgPSBtZXJnZURlZXBSZXBsYWNlKHNjaGVtYSwgaW1wbGljaXRDb25maWdTY2hlbWEpO1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW21vZHVsZU5hbWVdOiBlbmhhbmNlZFNjaGVtYVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsZXJ0cyB0aGUgY29uZmlndXJhdGlvbiBzeXN0ZW0gdGhhdCBhIG1vZHVsZSBleGlzdHMuIFRoaXMgYWxsb3dzIGNvbmZpZyB0byBiZVxuICogcHJvY2Vzc2VkLCB3aGlsZSBzdGlsbCBhbGxvd2luZyB0aGUgZXh0ZW5zaW9uIHN5c3RlbSB0byBrbm93IHdoZXRoZXIgdGhlIG1vZHVsZSBoYXNcbiAqIGFjdHVhbGx5IGhhZCBpdHMgZnJvbnQgYnVuZGxlIGV4ZWN1dGVkIHlldC5cbiAqXG4gKiBUaGlzIHNob3VsZCBvbmx5IGJlIHVzZWQgaW4gZXNtLWFwcC1zaGVsbC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqIEBwYXJhbSBtb2R1bGVOYW1lXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlZ2lzdGVyTW9kdWxlV2l0aENvbmZpZ1N5c3RlbShtb2R1bGVOYW1lKSB7XG4gICAgY29uZmlnSW50ZXJuYWxTdG9yZS5zZXRTdGF0ZSgoc3RhdGUpPT4oe1xuICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICBzY2hlbWFzOiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUuc2NoZW1hcyxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IGltcGxpY2l0Q29uZmlnU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBhbGVydHMgdGhlIGNvbmZpZ3VyYXRpb24gc3lzdGVtIHRoYXQgYSBtb2R1bGUgaGFzIGJlZW4gbG9hZGVkLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG1vZHVsZU5hbWVcbiAqLyBleHBvcnQgZnVuY3Rpb24gcmVnaXN0ZXJNb2R1bGVMb2FkKG1vZHVsZU5hbWUpIHtcbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIG1vZHVsZUxvYWRlZDoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLm1vZHVsZUxvYWRlZCxcbiAgICAgICAgICAgICAgICBbbW9kdWxlTmFtZV06IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xufVxuLyoqXG4gKiBUaGlzIGFsbG93cyB0aGUgY29uZmlnIHN5c3RlbSB0byBzdXBwb3J0IHRyYW5zbGF0aW9uIG92ZXJyaWRlcyBmb3IgbmFtZXNwYWNlcyB0aGF0XG4gKiBkbyBub3QgY29ycmVzcG9uZCB0byBtb2R1bGVzLlxuICpcbiAqIFRoaXMgc2hvdWxkIG9ubHkgYmUgdXNlZCBpbiBlc20tYXBwLXNoZWxsLlxuICpcbiAqIEBpbnRlcm5hbFxuICogQHBhcmFtIG5hbWVzcGFjZVxuICovIGV4cG9ydCBmdW5jdGlvbiByZWdpc3RlclRyYW5zbGF0aW9uTmFtZXNwYWNlKG5hbWVzcGFjZSkge1xuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW25hbWVzcGFjZV06IHRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hXG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbn1cbi8qKlxuICogVGhpcyBkZWZpbmVzIGEgY29uZmlndXJhdGlvbiBzY2hlbWEgZm9yIGFuIGV4dGVuc2lvbi4gV2hlbiBhIHNjaGVtYSBpcyBkZWZpbmVkXG4gKiBmb3IgYW4gZXh0ZW5zaW9uLCB0aGF0IGV4dGVuc2lvbiB3aWxsIHJlY2VpdmUgdGhlIGNvbmZpZ3VyYXRpb24gY29ycmVzcG9uZGluZ1xuICogdG8gdGhhdCBzY2hlbWEsIHJhdGhlciB0aGFuIHRoZSBjb25maWd1cmF0aW9uIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG1vZHVsZVxuICogaW4gd2hpY2ggaXQgaXMgZGVmaW5lZC5cbiAqXG4gKiBUaGUgc2NoZW1hIHRlbGxzIHRoZSBjb25maWd1cmF0aW9uIHN5c3RlbSBob3cgdGhlIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZC5cbiAqIEl0IHNwZWNpZmllcyB3aGF0IG1ha2VzIGNvbmZpZ3VyYXRpb24gdmFsaWQgb3IgaW52YWxpZC5cbiAqXG4gKiBTZWUgW0NvbmZpZ3VyYXRpb24gU3lzdGVtXShodHRwczovL28zLWRvY3Mub3Blbm1ycy5vcmcvZW4tVVMvZG9jcy9jb25maWd1cmF0aW9uLXN5c3RlbSlcbiAqIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IGRlZmluaW5nIGEgY29uZmlnIHNjaGVtYS5cbiAqXG4gKiBAcGFyYW0gZXh0ZW5zaW9uTmFtZSBOYW1lIG9mIHRoZSBleHRlbnNpb24gdGhlIHNjaGVtYSBpcyBiZWluZyBkZWZpbmVkIGZvci5cbiAqICAgU2hvdWxkIG1hdGNoIHRoZSBgbmFtZWAgb2Ygb25lIG9mIHRoZSBgZXh0ZW5zaW9uc2AgZW50cmllcyBkZWZpbmVkIGluXG4gKiAgIHRoZSBhcHAncyBgcm91dGVzLmpzb25gIGZpbGUuXG4gKiBAcGFyYW0gc2NoZW1hIFRoZSBjb25maWcgc2NoZW1hIGZvciB0aGUgZXh0ZW5zaW9uXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGRlZmluZUV4dGVuc2lvbkNvbmZpZ1NjaGVtYShleHRlbnNpb25OYW1lLCBzY2hlbWEpIHtcbiAgICB2YWxpZGF0ZUNvbmZpZ1NjaGVtYShleHRlbnNpb25OYW1lLCBzY2hlbWEpO1xuICAgIGNvbnN0IGVuaGFuY2VkU2NoZW1hID0gbWVyZ2VEZWVwUmVwbGFjZShzY2hlbWEsIGltcGxpY2l0Q29uZmlnU2NoZW1hKTtcbiAgICBjb25zdCBzdGF0ZSA9IGNvbmZpZ0ludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBpZiAoc3RhdGUuc2NoZW1hc1tleHRlbnNpb25OYW1lXSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBDb25maWcgc2NoZW1hIGZvciBleHRlbnNpb24gJHtleHRlbnNpb25OYW1lfSBhbHJlYWR5IGV4aXN0cy4gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGV4dGVuc2lvbnMgd2l0aCB0aGlzIHNhbWUgbmFtZSwgb25lIHdpbGwgcHJvYmFibHkgY3Jhc2guYCk7XG4gICAgfVxuICAgIGNvbmZpZ0ludGVybmFsU3RvcmUuc2V0U3RhdGUoKHN0YXRlKT0+KHtcbiAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgc2NoZW1hczoge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNjaGVtYXMsXG4gICAgICAgICAgICAgICAgW2V4dGVuc2lvbk5hbWVdOiBlbmhhbmNlZFNjaGVtYVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG59XG4vKipcbiAqIFByb3ZpZGVzIGNvbmZpZ3VyYXRpb24gdmFsdWVzIHByb2dyYW1tYXRpY2FsbHkuIFRoaXMgaXMgYW4gYWx0ZXJuYXRpdmUgdG9cbiAqIHByb3ZpZGluZyBjb25maWd1cmF0aW9uIHRocm91Z2ggdGhlIGNvbmZpZy1maWxlLiBDb25maWd1cmF0aW9uIHByb3ZpZGVkIHRoaXNcbiAqIHdheSB3aWxsIGJlIG1lcmdlZCB3aXRoIGNvbmZpZ3VyYXRpb24gZnJvbSBvdGhlciBzb3VyY2VzLlxuICpcbiAqIEBwYXJhbSBjb25maWcgQSBjb25maWd1cmF0aW9uIG9iamVjdCB0byBtZXJnZSBpbnRvIHRoZSBleGlzdGluZyBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIHNvdXJjZU5hbWUgQW4gb3B0aW9uYWwgbmFtZSB0byBpZGVudGlmeSB0aGUgc291cmNlIG9mIHRoaXMgY29uZmlndXJhdGlvbixcbiAqICAgdXNlZCBmb3IgZGVidWdnaW5nIHB1cnBvc2VzLiBEZWZhdWx0cyB0byAncHJvdmlkZWQnLlxuICovIGV4cG9ydCBmdW5jdGlvbiBwcm92aWRlKGNvbmZpZywgc291cmNlTmFtZSA9ICdwcm92aWRlZCcpIHtcbiAgICBjb25maWdJbnRlcm5hbFN0b3JlLnNldFN0YXRlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIHByb3ZpZGVkQ29uZmlnczogW1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLnByb3ZpZGVkQ29uZmlncyxcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZTogc291cmNlTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgY29uZmlnXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgXVxuICAgICAgICB9KSk7XG59XG4vKipcbiAqIFJlc29sdmVzIHdpdGggYHNlbGVjdChzdGF0ZSlgIGFzIHNvb24gYXMgdGhlIHN0b3JlJ3Mgc3RhdGUgc2F0aXNmaWVzIGByZWFkeWAsIGxlYXZpbmcgbm9cbiAqIHN1YnNjcmlwdGlvbiBiZWhpbmQ6IG5vdGhpbmcgc3Vic2NyaWJlcyBhdCBhbGwgd2hlbiB0aGUgc3RvcmUgaXMgYWxyZWFkeSByZWFkeS4gVGhhdCBtYXR0ZXJzXG4gKiBiZWNhdXNlIGBnZXRDb25maWdgIHJ1bnMgb24gZXZlcnkgSFRUUCByZXF1ZXN0LCBhbmQgYSBzdWJzY3JpcHRpb24gdGhhdCBvdXRsaXZlcyBpdHMgcHJvbWlzZVxuICogYm90aCByZXRhaW5zIGl0cyBjbG9zdXJlIGZvcmV2ZXIgYW5kIHNsb3dzIGRvd24gZXZlcnkgbGF0ZXIgd3JpdGUgdG8gdGhhdCBzdG9yZS5cbiAqLyBmdW5jdGlvbiB3aGVuU3RvcmVSZWFkeShzdG9yZSwgcmVhZHksIHNlbGVjdCkge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSk9PntcbiAgICAgICAgbGV0IHVuc3Vic2NyaWJlO1xuICAgICAgICBsZXQgcmVzb2x2ZWQgPSBmYWxzZTtcbiAgICAgICAgZnVuY3Rpb24gdXBkYXRlKHN0YXRlKSB7XG4gICAgICAgICAgICBpZiAoIXJlc29sdmVkICYmIHJlYWR5KHN0YXRlKSkge1xuICAgICAgICAgICAgICAgIHJlc29sdmVkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICByZXNvbHZlKHNlbGVjdChzdGF0ZSkpO1xuICAgICAgICAgICAgICAgIHVuc3Vic2NyaWJlPy4oKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB1cGRhdGUoc3RvcmUuZ2V0U3RhdGUoKSk7XG4gICAgICAgIGlmICghcmVzb2x2ZWQpIHtcbiAgICAgICAgICAgIHVuc3Vic2NyaWJlID0gc3RvcmUuc3Vic2NyaWJlKHVwZGF0ZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogQSBwcm9taXNlLWJhc2VkIHdheSB0byBhY2Nlc3MgdGhlIGNvbmZpZyBhcyBzb29uIGFzIGl0IGlzIGZ1bGx5IGxvYWRlZC5cbiAqIElmIGl0IGlzIGFscmVhZHkgbG9hZGVkLCByZXNvbHZlcyB0aGUgY29uZmlnIGluIGl0cyBwcmVzZW50IHN0YXRlLlxuICpcbiAqIFRoaXMgaXMgYSB1c2VmdWwgZnVuY3Rpb24gaWYgeW91IG5lZWQgdG8gZ2V0IHRoZSBjb25maWcgaW4gdGhlIGNvdXJzZVxuICogb2YgdGhlIGV4ZWN1dGlvbiBvZiBhIGZ1bmN0aW9uLlxuICpcbiAqIEBwYXJhbSBtb2R1bGVOYW1lIFRoZSBuYW1lIG9mIHRoZSBtb2R1bGUgZm9yIHdoaWNoIHRvIGxvb2sgdXAgdGhlIGNvbmZpZ1xuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRDb25maWcobW9kdWxlTmFtZSkge1xuICAgIHJldHVybiB3aGVuU3RvcmVSZWFkeShnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKSwgKHN0YXRlKT0+Qm9vbGVhbihzdGF0ZS5sb2FkZWQgJiYgc3RhdGUuY29uZmlnKSwgKHN0YXRlKT0+bG9kYXNoT21pdChzdGF0ZS5jb25maWcsIFtcbiAgICAgICAgICAgICdEaXNwbGF5IGNvbmRpdGlvbnMnLFxuICAgICAgICAgICAgJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcydcbiAgICAgICAgXSkpO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIGZvciBhbiBleHRlbnNpb24sIG9wdGlvbmFsbHkgc2NvcGVkIHRvIGEgc3BlY2lmaWNcbiAqIGV4dGVuc2lvbiBzbG90LiBXaGVuIGNhbGxlZCB3aXRoIG9ubHkgYSBtb2R1bGUgbmFtZSwgcmV0cmlldmVzIG1vZHVsZS1sZXZlbCBvdmVycmlkZXMuXG4gKiBUcmFuc2xhdGlvbiBvdmVycmlkZXMgYWxsb3cgY3VzdG9taXppbmcgdHJhbnNsYXRlZCBzdHJpbmdzIHdpdGhvdXQgbW9kaWZ5aW5nIHRoZVxuICogb3JpZ2luYWwgdHJhbnNsYXRpb24gZmlsZXMuXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSBwcm92aWRpbmcgdGhlIHRyYW5zbGF0aW9uIGNvbnRleHQuXG4gKiBAcGFyYW0gc2xvdE5hbWUgT3B0aW9uYWwgZXh0ZW5zaW9uIHNsb3QgbmFtZSB0byBpbmNsdWRlIHNsb3Qtc3BlY2lmaWMgb3ZlcnJpZGVzLlxuICogQHBhcmFtIGV4dGVuc2lvbklkIE9wdGlvbmFsIGV4dGVuc2lvbiBJRCB0byBpbmNsdWRlIGV4dGVuc2lvbi1zcGVjaWZpYyBvdmVycmlkZXMuXG4gKiBAcmV0dXJucyBBIFByb21pc2UgcmVzb2x2aW5nIHRvIGFuIGFycmF5IG9mIHRyYW5zbGF0aW9uIG92ZXJyaWRlIG9iamVjdHMuXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGdldFRyYW5zbGF0aW9uT3ZlcnJpZGVzKG1vZHVsZU5hbWUsIHNsb3ROYW1lLCBleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IHByb21pc2VzID0gW1xuICAgICAgICB3aGVuU3RvcmVSZWFkeShnZXRDb25maWdTdG9yZShtb2R1bGVOYW1lKSwgKHN0YXRlKT0+Qm9vbGVhbihzdGF0ZS50cmFuc2xhdGlvbk92ZXJyaWRlc0xvYWRlZCAmJiBzdGF0ZS5jb25maWcpLCAoc3RhdGUpPT5zdGF0ZS5jb25maWdbJ1RyYW5zbGF0aW9uIG92ZXJyaWRlcyddID8/IHt9KVxuICAgIF07XG4gICAgaWYgKHNsb3ROYW1lICYmIGV4dGVuc2lvbklkKSB7XG4gICAgICAgIHByb21pc2VzLnB1c2god2hlblN0b3JlUmVhZHkoZ2V0RXh0ZW5zaW9uQ29uZmlnKHNsb3ROYW1lLCBleHRlbnNpb25JZCksIChzdGF0ZSk9PkJvb2xlYW4oc3RhdGUubG9hZGVkICYmIHN0YXRlLmNvbmZpZyksIChzdGF0ZSk9PnN0YXRlLmNvbmZpZ1snVHJhbnNsYXRpb24gb3ZlcnJpZGVzJ10gPz8ge30pKTtcbiAgICB9XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKHByb21pc2VzKTtcbn1cbi8qKlxuICogVmFsaWRhdGUgYW5kIGludGVycG9sYXRlIGRlZmF1bHRzIGZvciBgcHJvdmlkZWRDb25maWdgIGFjY29yZGluZyB0byBgc2NoZW1hYFxuICpcbiAqIEBwYXJhbSBzY2hlbWEgIGEgY29uZmlndXJhdGlvbiBzY2hlbWFcbiAqIEBwYXJhbSBwcm92aWRlZENvbmZpZyAgYW4gb2JqZWN0IG9mIGNvbmZpZyB2YWx1ZXMgKHdpdGhvdXQgdGhlIHRvcC1sZXZlbCBtb2R1bGUgbmFtZSlcbiAqIEBwYXJhbSBrZXlQYXRoQ29udGV4dCAgYSBkb3Qtc2VwYXJhdGVkIHN0cmluZyB3aGljaCBoZWxwcyB0aGUgdXNlciBmaWd1cmUgb3V0IHdoZXJlXG4gKiAgICAgdGhlIHByb3ZpZGVkIGNvbmZpZyBjYW1lIGZyb21cbiAqIEByZXR1cm5zIFRoZSB2YWxpZGF0ZWQgYW5kIHByb2Nlc3NlZCBjb25maWd1cmF0aW9uIG9iamVjdCB3aXRoIGRlZmF1bHRzIGFwcGxpZWQuXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gcHJvY2Vzc0NvbmZpZyhzY2hlbWEsIHByb3ZpZGVkQ29uZmlnLCBrZXlQYXRoQ29udGV4dCkge1xuICAgIHZhbGlkYXRlU3RydWN0dXJlKHNjaGVtYSwgcHJvdmlkZWRDb25maWcsIGtleVBhdGhDb250ZXh0KTtcbiAgICBjb25zdCBjb25maWcgPSBzZXREZWZhdWx0cyhzY2hlbWEsIHByb3ZpZGVkQ29uZmlnKTtcbiAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYSwgY29uZmlnLCBrZXlQYXRoQ29udGV4dCk7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmNvbnN0IGV4dGVuc2lvbkNvbmZpZ0NhY2hlID0gbmV3IE1hcCgpO1xuLyoqXG4gKiBSZXR1cm5zIHRoZSBjb25maWd1cmF0aW9uIGZvciBhbiBleHRlbnNpb24uIFRoaXMgY29uZmlndXJhdGlvbiBpcyBzcGVjaWZpY1xuICogdG8gdGhlIHNsb3QgaW4gd2hpY2ggaXQgaXMgbW91bnRlZCwgYW5kIGl0cyBJRCB3aXRoaW4gdGhhdCBzbG90LlxuICpcbiAqIFRoZSBzY2hlbWEgZm9yIHRoYXQgY29uZmlndXJhdGlvbiBpcyB0aGUgZXh0ZW5zaW9uIHNjaGVtYS4gSWYgbm8gZXh0ZW5zaW9uXG4gKiBzY2hlbWEgaGFzIGJlZW4gcHJvdmlkZWQsIHRoZSBzY2hlbWEgdXNlZCBpcyB0aGUgc2NoZW1hIG9mIHRoZSBtb2R1bGUgaW5cbiAqIHdoaWNoIHRoZSBleHRlbnNpb24gaXMgZGVmaW5lZC5cbiAqXG4gKiBAcGFyYW0gc2xvdE1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWZpbmVzIHRoZSBleHRlbnNpb24gc2xvdFxuICogQHBhcmFtIGV4dGVuc2lvbk1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB3aGljaCBkZWZpbmVzIHRoZSBleHRlbnNpb24gKGFuZCB0aGVyZWZvcmUgdGhlIGNvbmZpZyBzY2hlbWEpXG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIG5hbWUgb2YgdGhlIGV4dGVuc2lvbiBzbG90IHdoZXJlIHRoZSBleHRlbnNpb24gaXMgbW91bnRlZFxuICogQHBhcmFtIGV4dGVuc2lvbklkIFRoZSBJRCBvZiB0aGUgZXh0ZW5zaW9uIGluIGl0cyBzbG90XG4gKiBAcGFyYW0gc2xvdENvbmZpZyBUaGUgc2xvdCdzIGNvbmZpZ3VyYXRpb24sIGdhdGhlcmVkIGZyb20gZXZlcnkgbW9kdWxlIHRoYXQgY29uZmlndXJlcyBpdFxuICovIGZ1bmN0aW9uIGNvbXB1dGVFeHRlbnNpb25Db25maWcoc2xvdE1vZHVsZU5hbWUsIGV4dGVuc2lvbk1vZHVsZU5hbWUsIHNsb3ROYW1lLCBleHRlbnNpb25JZCwgY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSwgc2xvdENvbmZpZykge1xuICAgIGNvbnN0IGV4dGVuc2lvbk5hbWUgPSBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKTtcbiAgICBjb25zdCBleHRlbnNpb25Db25maWdTY2hlbWEgPSBjb25maWdTdGF0ZS5zY2hlbWFzW2V4dGVuc2lvbk5hbWVdO1xuICAgIC8vIEpTT04gc3RyaW5nIG9mIHRoZXNlIGVsZW1lbnRzIHNob3VsZCBiZSB1bmlxdWUtcGVyLWV4dGVuc2lvblxuICAgIGNvbnN0IGNhY2hlS2V5ID0gSlNPTi5zdHJpbmdpZnkoW1xuICAgICAgICBzbG90TmFtZSxcbiAgICAgICAgZXh0ZW5zaW9uSWQsXG4gICAgICAgIHNsb3RNb2R1bGVOYW1lLFxuICAgICAgICBleHRlbnNpb25Nb2R1bGVOYW1lXG4gICAgXSk7XG4gICAgY29uc3QgY2FjaGVkID0gZXh0ZW5zaW9uQ29uZmlnQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcbiAgICBpZiAoY2FjaGVkICYmIGNhY2hlZC5leHRlbnNpb25TY2hlbWEgPT09IGV4dGVuc2lvbkNvbmZpZ1NjaGVtYSAmJiBjYWNoZWQuZXh0ZW5zaW9uTW9kdWxlU2NoZW1hID09PSBjb25maWdTdGF0ZS5zY2hlbWFzW2V4dGVuc2lvbk1vZHVsZU5hbWVdICYmIGNhY2hlZC5wcm92aWRlZENvbmZpZ3MgPT09IGNvbmZpZ1N0YXRlLnByb3ZpZGVkQ29uZmlncyAmJiBjYWNoZWQudGVtcG9yYXJ5Q29uZmlnID09PSB0ZW1wQ29uZmlnU3RhdGUuY29uZmlnKSB7XG4gICAgICAgIHJldHVybiBjYWNoZWQuY29uZmlnO1xuICAgIH1cbiAgICBjb25zdCBuYW1lT2ZTY2hlbWFTb3VyY2UgPSBleHRlbnNpb25Db25maWdTY2hlbWEgPyBleHRlbnNpb25OYW1lIDogZXh0ZW5zaW9uTW9kdWxlTmFtZTtcbiAgICBjb25zdCBwcm92aWRlZENvbmZpZ3MgPSBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSk7XG4gICAgY29uc3Qgc2hhcmVkT3ZlcnJpZGUgPSBzbG90Q29uZmlnPy5jb25maWd1cmU/LltleHRlbnNpb25JZF0gPz8ge307XG4gICAgY29uc3Qgc2xvdE1vZHVsZUNvbmZpZyA9IG1lcmdlQ29uZmlnc0ZvcihzbG90TW9kdWxlTmFtZSwgcHJvdmlkZWRDb25maWdzKTtcbiAgICBjb25zdCBjb25maWdPdmVycmlkZSA9IHNsb3RNb2R1bGVDb25maWc/LmV4dGVuc2lvblNsb3RzPy5bc2xvdE5hbWVdPy5jb25maWd1cmU/LltleHRlbnNpb25JZF0gPz8ge307XG4gICAgY29uc3QgZXh0ZW5zaW9uQ29uZmlnID0gbWVyZ2VDb25maWdzRm9yKG5hbWVPZlNjaGVtYVNvdXJjZSwgcHJvdmlkZWRDb25maWdzKTtcbiAgICBjb25zdCBjb21iaW5lZENvbmZpZyA9IG1lcmdlQ29uZmlncyhbXG4gICAgICAgIGV4dGVuc2lvbkNvbmZpZyxcbiAgICAgICAgc2hhcmVkT3ZlcnJpZGUsXG4gICAgICAgIGNvbmZpZ092ZXJyaWRlXG4gICAgXSk7XG4gICAgY29uc3Qgc2NoZW1hID0gZXh0ZW5zaW9uQ29uZmlnU2NoZW1hID8/IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTW9kdWxlTmFtZV07XG4gICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hLCBjb21iaW5lZENvbmZpZywgbmFtZU9mU2NoZW1hU291cmNlKTtcbiAgICBjb25zdCBjb25maWcgPSBzZXREZWZhdWx0cyhzY2hlbWEsIGNvbWJpbmVkQ29uZmlnKTtcbiAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYSwgY29uZmlnLCBuYW1lT2ZTY2hlbWFTb3VyY2UpO1xuICAgIGRlbGV0ZSBjb25maWcuZXh0ZW5zaW9uU2xvdHM7XG4gICAgZXh0ZW5zaW9uQ29uZmlnQ2FjaGUuc2V0KGNhY2hlS2V5LCB7XG4gICAgICAgIGV4dGVuc2lvblNjaGVtYTogZXh0ZW5zaW9uQ29uZmlnU2NoZW1hLFxuICAgICAgICBleHRlbnNpb25Nb2R1bGVTY2hlbWE6IGNvbmZpZ1N0YXRlLnNjaGVtYXNbZXh0ZW5zaW9uTW9kdWxlTmFtZV0sXG4gICAgICAgIHByb3ZpZGVkQ29uZmlnczogY29uZmlnU3RhdGUucHJvdmlkZWRDb25maWdzLFxuICAgICAgICB0ZW1wb3JhcnlDb25maWc6IHRlbXBDb25maWdTdGF0ZS5jb25maWcsXG4gICAgICAgIGNvbmZpZ1xuICAgIH0pO1xuICAgIHJldHVybiBjb25maWc7XG59XG5jb25zdCBpbXBsZW1lbnRlclRvb2xzTW9kdWxlQ2FjaGUgPSBuZXcgTWFwKCk7XG5mdW5jdGlvbiBnZXRJbXBsZW1lbnRlclRvb2xzQ29uZmlnKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBhbm5vdGF0ZWRTY2hlbWFzID0gZ2V0QWxsU2NoZW1hc1dpdGhWYWx1ZXNBbmRTb3VyY2VzKGNvbmZpZ1N0YXRlLnNjaGVtYXMpO1xuICAgIGNvbnN0IGNvbmZpZ3NBbmRTb3VyY2VzID0gW1xuICAgICAgICAuLi5jb25maWdTdGF0ZS5wcm92aWRlZENvbmZpZ3MubWFwKChjKT0+W1xuICAgICAgICAgICAgICAgIGMuY29uZmlnLFxuICAgICAgICAgICAgICAgIGMuc291cmNlXG4gICAgICAgICAgICBdKSxcbiAgICAgICAgW1xuICAgICAgICAgICAgdGVtcENvbmZpZ1N0YXRlLmNvbmZpZyxcbiAgICAgICAgICAgICd0ZW1wb3JhcnkgY29uZmlnJ1xuICAgICAgICBdXG4gICAgXTtcbiAgICAvLyBBIG1vZHVsZSBjYW4gYmUgY29uZmlndXJlZCB3aXRob3V0IGhhdmluZyBkZWNsYXJlZCBhIHNjaGVtYSwgc28gdGhlIG1vZHVsZSBsaXN0IGlzIHRoZSB1bmlvblxuICAgIC8vIG9mIGJvdGggcmF0aGVyIHRoYW4ganVzdCB0aGUgc2NoZW1hcy5cbiAgICBjb25zdCBtb2R1bGVOYW1lcyA9IG5ldyBTZXQoT2JqZWN0LmtleXMoYW5ub3RhdGVkU2NoZW1hcykpO1xuICAgIGZvciAoY29uc3QgW2NvbmZpZ10gb2YgY29uZmlnc0FuZFNvdXJjZXMpe1xuICAgICAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgb2YgT2JqZWN0LmtleXMoY29uZmlnKSl7XG4gICAgICAgICAgICBtb2R1bGVOYW1lcy5hZGQobW9kdWxlTmFtZSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIG9mIG1vZHVsZU5hbWVzKXtcbiAgICAgICAgY29uc3QgYW5ub3RhdGVkU2NoZW1hID0gYW5ub3RhdGVkU2NoZW1hc1ttb2R1bGVOYW1lXTtcbiAgICAgICAgY29uc3QgY29uZmlnU2xpY2VzID0gY29uZmlnc0FuZFNvdXJjZXMubWFwKChbY29uZmlnXSk9PmNvbmZpZ1ttb2R1bGVOYW1lXSk7XG4gICAgICAgIGNvbnN0IHNvdXJjZXMgPSBjb25maWdzQW5kU291cmNlcy5tYXAoKFssIHNvdXJjZV0pPT5zb3VyY2UpO1xuICAgICAgICBjb25zdCBjYWNoZWQgPSBpbXBsZW1lbnRlclRvb2xzTW9kdWxlQ2FjaGUuZ2V0KG1vZHVsZU5hbWUpO1xuICAgICAgICBpZiAoY2FjaGVkICYmIGNhY2hlZC5hbm5vdGF0ZWRTY2hlbWEgPT09IGFubm90YXRlZFNjaGVtYSAmJiBjYWNoZWQuY29uZmlnU2xpY2VzLmxlbmd0aCA9PT0gY29uZmlnU2xpY2VzLmxlbmd0aCAmJiBjYWNoZWQuY29uZmlnU2xpY2VzLmV2ZXJ5KChzbGljZSwgaSk9PnNsaWNlID09PSBjb25maWdTbGljZXNbaV0pICYmIGNhY2hlZC5zb3VyY2VzLmV2ZXJ5KChzb3VyY2UsIGkpPT5zb3VyY2UgPT09IHNvdXJjZXNbaV0pKSB7XG4gICAgICAgICAgICByZXN1bHRbbW9kdWxlTmFtZV0gPSBjYWNoZWQucmVzdWx0O1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IG1lcmdlZCA9IGFubm90YXRlZFNjaGVtYSA/PyB7fTtcbiAgICAgICAgY29uZmlnc0FuZFNvdXJjZXMuZm9yRWFjaCgoWywgc291cmNlXSwgaSk9PntcbiAgICAgICAgICAgIGNvbnN0IHNsaWNlID0gY29uZmlnU2xpY2VzW2ldO1xuICAgICAgICAgICAgaWYgKHNsaWNlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBtZXJnZWQgPSBtZXJnZURlZXBSZXBsYWNlKG1lcmdlZCwgY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUoc2xpY2UsIHNvdXJjZSkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgaW1wbGVtZW50ZXJUb29sc01vZHVsZUNhY2hlLnNldChtb2R1bGVOYW1lLCB7XG4gICAgICAgICAgICBhbm5vdGF0ZWRTY2hlbWEsXG4gICAgICAgICAgICBjb25maWdTbGljZXMsXG4gICAgICAgICAgICBzb3VyY2VzLFxuICAgICAgICAgICAgcmVzdWx0OiBtZXJnZWRcbiAgICAgICAgfSk7XG4gICAgICAgIHJlc3VsdFttb2R1bGVOYW1lXSA9IG1lcmdlZDtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogQ2FjaGluZyBwZXIgbW9kdWxlIGlzIHdoYXQgc3RvcHMgdGhlIHdhbGsgYmVpbmcgcXVhZHJhdGljOiBkZWZpbmluZyBvbmUgbW9kdWxlJ3Mgc2NoZW1hXG4gKiByZWNvbXB1dGVzIGV2ZXJ5IG1vZHVsZS5cbiAqXG4gKiBBIG1vZHVsZSB3aXRoIG5vIGNvbmZpZ3VyYXRpb24gb2YgaXRzIG93biBpcyBwdWJsaXNoZWQgc3RyYWlnaHQgZnJvbSB0aGlzIGNhY2hlLCBzbyBub3RoaW5nIG1heVxuICogbXV0YXRlIGEgdHJlZSBpdCByZWFkcyBvdXQgb2YgdGhlIGltcGxlbWVudGVyIHRvb2xzIGNvbmZpZyDigJQgaXQgaXMgdGhlIGNhY2hlIGVudHJ5LlxuICovIGNvbnN0IHNjaGVtYVZhbHVlc0FuZFNvdXJjZXNDYWNoZSA9IG5ldyBNYXAoKTtcbmZ1bmN0aW9uIGdldEFsbFNjaGVtYXNXaXRoVmFsdWVzQW5kU291cmNlcyhzY2hlbWFzKSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge307XG4gICAgZm9yIChjb25zdCBbbW9kdWxlTmFtZSwgc2NoZW1hXSBvZiBPYmplY3QuZW50cmllcyhzY2hlbWFzKSl7XG4gICAgICAgIGNvbnN0IGNhY2hlZCA9IHNjaGVtYVZhbHVlc0FuZFNvdXJjZXNDYWNoZS5nZXQobW9kdWxlTmFtZSk7XG4gICAgICAgIGlmIChjYWNoZWQgJiYgY2FjaGVkLnNjaGVtYSA9PT0gc2NoZW1hKSB7XG4gICAgICAgICAgICByZXN1bHRbbW9kdWxlTmFtZV0gPSBjYWNoZWQuYW5ub3RhdGVkO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgYW5ub3RhdGVkID0gZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMoY2xvbmVEZWVwKHNjaGVtYSkpO1xuICAgICAgICAgICAgc2NoZW1hVmFsdWVzQW5kU291cmNlc0NhY2hlLnNldChtb2R1bGVOYW1lLCB7XG4gICAgICAgICAgICAgICAgc2NoZW1hLFxuICAgICAgICAgICAgICAgIGFubm90YXRlZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICByZXN1bHRbbW9kdWxlTmFtZV0gPSBhbm5vdGF0ZWQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbn1cbmZ1bmN0aW9uIGdldFNjaGVtYVdpdGhWYWx1ZXNBbmRTb3VyY2VzKHNjaGVtYSkge1xuICAgIGlmIChzY2hlbWEuaGFzT3duUHJvcGVydHkoJ19kZWZhdWx0JykpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLnNjaGVtYSxcbiAgICAgICAgICAgIF92YWx1ZTogc2NoZW1hLl9kZWZhdWx0LFxuICAgICAgICAgICAgX3NvdXJjZTogJ2RlZmF1bHQnXG4gICAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpc09yZGluYXJ5T2JqZWN0KHNjaGVtYSkpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHNjaGVtYSkucmVkdWNlKChvYmosIGtleSk9PntcbiAgICAgICAgICAgIG9ialtrZXldID0gZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMoc2NoZW1hW2tleV0pO1xuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgfSwge30pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIGF0IHRoaXMgcG9pbnQsIHRoZSBzY2hlbWEgaXMgYmFkIGFuZCBhbiBlcnJvciB3aWxsIGhhdmUgYmVlbiBsb2dnZWQgZHVyaW5nIHNjaGVtYSB2YWxpZGF0aW9uXG4gICAgICAgIHJldHVybiB7fTtcbiAgICB9XG59XG5mdW5jdGlvbiBjcmVhdGVWYWx1ZXNBbmRTb3VyY2VzVHJlZShjb25maWcsIHNvdXJjZSkge1xuICAgIGlmIChpc09yZGluYXJ5T2JqZWN0KGNvbmZpZykpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKGNvbmZpZykucmVkdWNlKChvYmosIGtleSk9PntcbiAgICAgICAgICAgIG9ialtrZXldID0gY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUoY29uZmlnW2tleV0sIHNvdXJjZSk7XG4gICAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9LCB7fSk7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIF92YWx1ZTogY29uZmlnLFxuICAgICAgICAgICAgX3NvdXJjZTogc291cmNlXG4gICAgICAgIH07XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkge1xuICAgIGNvbnN0IGFsbENvbmZpZ3MgPSBtZXJnZUNvbmZpZ3MoZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpKTtcbiAgICBjb25zdCBzbG90Q29uZmlnUGVyTW9kdWxlID0gT2JqZWN0LmtleXMoYWxsQ29uZmlncykucmVkdWNlKChvYmosIGtleSk9PntcbiAgICAgICAgaWYgKGFsbENvbmZpZ3Nba2V5XT8uZXh0ZW5zaW9uU2xvdHMpIHtcbiAgICAgICAgICAgIG9ialtrZXldID0gYWxsQ29uZmlnc1trZXldPy5leHRlbnNpb25TbG90cztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb2JqO1xuICAgIH0sIHt9KTtcbiAgICB2YWxpZGF0ZUFsbEV4dGVuc2lvblNsb3RDb25maWdzKHNsb3RDb25maWdQZXJNb2R1bGUpO1xuICAgIGNvbnN0IHNsb3RDb25maWdzID0ge307XG4gICAgY29uc3QgY29uZmlndXJlQmxvY2tzID0ge307XG4gICAgZm9yIChjb25zdCBjb25maWdCeVNsb3ROYW1lIG9mIE9iamVjdC52YWx1ZXMoc2xvdENvbmZpZ1Blck1vZHVsZSkpe1xuICAgICAgICBmb3IgKGNvbnN0IFtzbG90TmFtZSwgY29uZmlnXSBvZiBPYmplY3QuZW50cmllcyhjb25maWdCeVNsb3ROYW1lKSl7XG4gICAgICAgICAgICBzbG90Q29uZmlnc1tzbG90TmFtZV0gPSBjb25maWc7XG4gICAgICAgICAgICBpZiAoY29uZmlnLmNvbmZpZ3VyZSkge1xuICAgICAgICAgICAgICAgIHZhciBfY29uZmlndXJlQmxvY2tzLCBfc2xvdE5hbWU7XG4gICAgICAgICAgICAgICAgKChfY29uZmlndXJlQmxvY2tzID0gY29uZmlndXJlQmxvY2tzKVtfc2xvdE5hbWUgPSBzbG90TmFtZV0gPz8gKF9jb25maWd1cmVCbG9ja3NbX3Nsb3ROYW1lXSA9IFtdKSkucHVzaChjb25maWcuY29uZmlndXJlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtzbG90TmFtZSwgYmxvY2tzXSBvZiBPYmplY3QuZW50cmllcyhjb25maWd1cmVCbG9ja3MpKXtcbiAgICAgICAgY29uc3QgY29uZmlndXJlID0gYmxvY2tzLmxlbmd0aCA9PT0gMSA/IGJsb2Nrc1swXSA6IG1lcmdlQ29uZmlncyhibG9ja3MpO1xuICAgICAgICBpZiAoc2xvdENvbmZpZ3Nbc2xvdE5hbWVdLmNvbmZpZ3VyZSAhPT0gY29uZmlndXJlKSB7XG4gICAgICAgICAgICBzbG90Q29uZmlnc1tzbG90TmFtZV0gPSB7XG4gICAgICAgICAgICAgICAgLi4uc2xvdENvbmZpZ3Nbc2xvdE5hbWVdLFxuICAgICAgICAgICAgICAgIGNvbmZpZ3VyZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc2xvdENvbmZpZ3M7XG59XG5mdW5jdGlvbiB2YWxpZGF0ZUFsbEV4dGVuc2lvblNsb3RDb25maWdzKHNsb3RDb25maWdQZXJNb2R1bGUpIHtcbiAgICBmb3IgKGxldCBbbW9kdWxlTmFtZSwgY29uZmlnQnlTbG90TmFtZV0gb2YgT2JqZWN0LmVudHJpZXMoc2xvdENvbmZpZ1Blck1vZHVsZSkpe1xuICAgICAgICBmb3IgKGxldCBbc2xvdE5hbWUsIGNvbmZpZ10gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnQnlTbG90TmFtZSkpe1xuICAgICAgICAgICAgdmFsaWRhdGVFeHRlbnNpb25TbG90Q29uZmlnKGNvbmZpZywgbW9kdWxlTmFtZSwgc2xvdE5hbWUpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVFeHRlbnNpb25TbG90Q29uZmlnKGNvbmZpZywgbW9kdWxlTmFtZSwgc2xvdE5hbWUpIHtcbiAgICBjb25zdCBrZXlQYXRoID0gYCR7bW9kdWxlTmFtZX0uZXh0ZW5zaW9uU2xvdHMuJHtzbG90TmFtZX1gO1xuICAgIGNvbnN0IGVycm9yUHJlZml4ID0gYEV4dGVuc2lvbiBzbG90IGNvbmZpZyAnJHtrZXlQYXRofSdgO1xuICAgIGNvbnN0IGludmFsaWRLZXlzID0gT2JqZWN0LmtleXMoY29uZmlnKS5maWx0ZXIoKGspPT4hW1xuICAgICAgICAgICAgJ2FkZCcsXG4gICAgICAgICAgICAncmVtb3ZlJyxcbiAgICAgICAgICAgICdvcmRlcicsXG4gICAgICAgICAgICAnY29uZmlndXJlJ1xuICAgICAgICBdLmluY2x1ZGVzKGspKTtcbiAgICBpZiAoaW52YWxpZEtleXMubGVuZ3RoKSB7XG4gICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYCcgY29udGFpbnMgaW52YWxpZCBrZXlzICcke2ludmFsaWRLZXlzLmpvaW4oXCInLCAnXCIpfSdgKTtcbiAgICB9XG4gICAgaWYgKGNvbmZpZy5hZGQpIHtcbiAgICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGNvbmZpZy5hZGQpIHx8ICFjb25maWcuYWRkLmV2ZXJ5KChuKT0+dHlwZW9mIG4gPT09ICdzdHJpbmcnKSkge1xuICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgZXJyb3JQcmVmaXggKyBgLmFkZCcgaXMgaW52YWxpZC4gTXVzdCBiZSBhbiBhcnJheSBvZiBzdHJpbmdzIChleHRlbnNpb24gSURzKWApO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChjb25maWcucmVtb3ZlKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb25maWcucmVtb3ZlKSB8fCAhY29uZmlnLnJlbW92ZS5ldmVyeSgobik9PnR5cGVvZiBuID09PSAnc3RyaW5nJykpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5yZW1vdmUnIGlzIGludmFsaWQuIE11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZXh0ZW5zaW9uIElEcylgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29uZmlnLm9yZGVyKSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheShjb25maWcub3JkZXIpIHx8ICFjb25maWcub3JkZXIuZXZlcnkoKG4pPT50eXBlb2YgbiA9PT0gJ3N0cmluZycpKSB7XG4gICAgICAgICAgICBsb2dFcnJvcihrZXlQYXRoLCBlcnJvclByZWZpeCArIGAub3JkZXInIGlzIGludmFsaWQuIE11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5ncyAoZXh0ZW5zaW9uIElEcylgKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBpZiAoY29uZmlnLmNvbmZpZ3VyZSkge1xuICAgICAgICBpZiAoIWlzT3JkaW5hcnlPYmplY3QoY29uZmlnLmNvbmZpZ3VyZSkpIHtcbiAgICAgICAgICAgIGxvZ0Vycm9yKGtleVBhdGgsIGVycm9yUHJlZml4ICsgYC5jb25maWd1cmUnIGlzIGludmFsaWQuIE11c3QgYmUgYW4gb2JqZWN0IHdpdGggZXh0ZW5zaW9uIElEcyBmb3Iga2V5c2ApO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gZ2V0UHJvdmlkZWRDb25maWdzKGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICByZXR1cm4gW1xuICAgICAgICAuLi5jb25maWdTdGF0ZS5wcm92aWRlZENvbmZpZ3MubWFwKChjKT0+Yy5jb25maWcpLFxuICAgICAgICB0ZW1wQ29uZmlnU3RhdGUuY29uZmlnXG4gICAgXTtcbn1cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBjb25maWcgc2NoZW1hIGZvciBhIG1vZHVsZS4gU2luY2UgcHJvYmxlbXMgaWRlbnRpZmllZCBoZXJlIGFyZSBwcm9ncmFtbWluZyBlcnJvcnNcbiAqIHRoYXQgaG9wZWZ1bGx5IHdpbGwgYmUgY2F1Z2h0IGR1cmluZyBkZXZlbG9wbWVudCwgdGhpcyBmdW5jdGlvbiBsb2dzIGVycm9ycyB0byB0aGUgY29uc29sZSBkaXJlY3RseTtcbiAqIGl0J3MgZmluZSBpZiB3ZSBzcGFtIHRoZSB1c2VyIHdpdGggdGhlc2UgZXJyb3JzLlxuICovIGZ1bmN0aW9uIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYSwga2V5UGF0aCA9ICcnKSB7XG4gICAgY29uc3QgdXBkYXRlTWVzc2FnZSA9IGBQbGVhc2UgdmVyaWZ5IHRoYXQgeW91IGFyZSBydW5uaW5nIHRoZSBsYXRlc3QgdmVyc2lvbiBhbmQsIGlmIHNvLCBhbGVydCB0aGUgbWFpbnRhaW5lci5gO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHNjaGVtYSkuZmlsdGVyKChrKT0+IWsuc3RhcnRzV2l0aCgnXycpKSl7XG4gICAgICAgIGNvbnN0IHRoaXNLZXlQYXRoID0ga2V5UGF0aCArIChrZXlQYXRoICYmICcuJykgKyBrZXk7XG4gICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgaWYgKHRoaXNLZXlQYXRoID09PSAnRGlzcGxheSBjb25kaXRpb25zJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBkZWNsYXJlcyBhIGNvbmZpZ3VyYXRpb24gb3B0aW9uIGNhbGxlZCBcIkRpc3BsYXkgY29uZGl0aW9uc1wiOyB0aGUgXCJEaXNwbGF5IGNvbmRpdGlvbnNcIiBvcHRpb24gaXMgYSByZXNlcnZlZCBuYW1lLiAke3VwZGF0ZU1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXNLZXlQYXRoID09PSAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJykge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBkZWNsYXJlcyBhIGNvbmZpZ3VyYXRpb24gb3B0aW9uIGNhbGxlZCBcIlRyYW5zbGF0aW9uIG92ZXJyaWRlc1wiOyB0aGUgXCJUcmFuc2xhdGlvbiBvdmVycmlkZXNcIiBvcHRpb24gaXMgYSByZXNlcnZlZCBuYW1lLiAke3VwZGF0ZU1lc3NhZ2V9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc09yZGluYXJ5T2JqZWN0KHNjaGVtYVBhcnQpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBiYWQgY29uZmlnIHNjaGVtYSBkZWZpbml0aW9uIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9Jy4gJHt1cGRhdGVNZXNzYWdlfWApO1xuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpKSB7XG4gICAgICAgICAgICAvLyByZWN1cnNlIGZvciBuZXN0ZWQgY29uZmlnIGtleXNcbiAgICAgICAgICAgIHZhbGlkYXRlQ29uZmlnU2NoZW1hKG1vZHVsZU5hbWUsIHNjaGVtYVBhcnQsIHRoaXNLZXlQYXRoKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBlbGVtZW50cyA9IHNjaGVtYVBhcnQuX2VsZW1lbnRzO1xuICAgICAgICBpZiAoaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzKSkge1xuICAgICAgICAgICAgdmFsaWRhdGVDb25maWdTY2hlbWEobW9kdWxlTmFtZSwgZWxlbWVudHMsIHRoaXNLZXlQYXRoICsgJy5fZWxlbWVudHMnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoc2NoZW1hUGFydC5fdmFsaWRhdG9ycykge1xuICAgICAgICAgICAgZm9yIChsZXQgdmFsaWRhdG9yIG9mIHNjaGVtYVBhcnQuX3ZhbGlkYXRvcnMpe1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsaWRhdG9yICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7bW9kdWxlTmFtZX0gaGFzIGludmFsaWQgdmFsaWRhdG9yIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9JyAke3VwZGF0ZU1lc3NhZ2V9LmAgKyBgXFxuXFxuSWYgeW91J3JlIHRoZSBtYWludGFpbmVyOiB2YWxpZGF0b3JzIG11c3QgYmUgZnVuY3Rpb25zIHRoYXQgcmV0dXJuIGVpdGhlciBgICsgYHVuZGVmaW5lZCBvciBhbiBlcnJvciBzdHJpbmcuIFJlY2VpdmVkICR7dmFsaWRhdG9yfS5gKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdmFsdWVUeXBlID0gc2NoZW1hUGFydC5fdHlwZTtcbiAgICAgICAgaWYgKHZhbHVlVHlwZSAmJiAhT2JqZWN0LnZhbHVlcyhUeXBlKS5pbmNsdWRlcyh2YWx1ZVR5cGUpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBpbnZhbGlkIHR5cGUgZm9yIGtleSAnJHt0aGlzS2V5UGF0aH0nICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IHRoZSBhbGxvd2VkIHR5cGVzIGFyZSAke09iamVjdC52YWx1ZXMoVHlwZSkuam9pbignLCAnKX0uIGAgKyBgUmVjZWl2ZWQgJyR7dmFsdWVUeXBlfSdgKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoT2JqZWN0LmtleXMoc2NoZW1hUGFydCkuZXZlcnkoKGspPT5bXG4gICAgICAgICAgICAgICAgJ19kZXNjcmlwdGlvbicsXG4gICAgICAgICAgICAgICAgJ192YWxpZGF0b3JzJyxcbiAgICAgICAgICAgICAgICAnX2VsZW1lbnRzJyxcbiAgICAgICAgICAgICAgICAnX3R5cGUnXG4gICAgICAgICAgICBdLmluY2x1ZGVzKGspKSAmJiAha2V5UGF0aC5pbmNsdWRlcygnLl9lbGVtZW50cycpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGAke21vZHVsZU5hbWV9IGhhcyBiYWQgY29uZmlnIHNjaGVtYSBkZWZpbml0aW9uIGZvciBrZXkgJyR7dGhpc0tleVBhdGh9Jy4gJHt1cGRhdGVNZXNzYWdlfS5gICsgYFxcblxcbklmIHlvdSdyZSB0aGUgbWFpbnRhaW5lcjogYWxsIGNvbmZpZyBlbGVtZW50cyBtdXN0IGhhdmUgYSBkZWZhdWx0LiBgICsgYFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkoc2NoZW1hUGFydCl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnRzICYmIHZhbHVlVHlwZSAmJiAhW1xuICAgICAgICAgICAgVHlwZS5BcnJheSxcbiAgICAgICAgICAgIFR5cGUuT2JqZWN0XG4gICAgICAgIF0uaW5jbHVkZXModmFsdWVUeXBlKSkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgJHttb2R1bGVOYW1lfSBoYXMgYmFkIGNvbmZpZyBzY2hlbWEgZGVmaW5pdGlvbiBmb3Iga2V5ICcke3RoaXNLZXlQYXRofScuICR7dXBkYXRlTWVzc2FnZX0uYCArIGBcXG5cXG5JZiB5b3UncmUgdGhlIG1haW50YWluZXI6IHRoZSAnZWxlbWVudHMnIGtleSBvbmx5IHdvcmtzIHdpdGggJ190eXBlJyBlcXVhbCB0byAnQXJyYXknIG9yICdPYmplY3QnLiBgICsgYFJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkodmFsdWVUeXBlKX1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGdldENvbmZpZ0Zvck1vZHVsZShtb2R1bGVOYW1lLCBjb25maWdTdGF0ZSwgdGVtcENvbmZpZ1N0YXRlKSB7XG4gICAgY29uc3Qgc2NoZW1hID0gY29uZmlnU3RhdGUuc2NoZW1hc1ttb2R1bGVOYW1lXTtcbiAgICBjb25zdCBpbnB1dENvbmZpZyA9IG1lcmdlQ29uZmlnc0Zvcihtb2R1bGVOYW1lLCBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIHZhbGlkYXRlU3RydWN0dXJlKHNjaGVtYSwgaW5wdXRDb25maWcsIG1vZHVsZU5hbWUpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKHNjaGVtYSwgaW5wdXRDb25maWcpO1xuICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIG1vZHVsZU5hbWUpO1xuICAgIGRlbGV0ZSBjb25maWcuZXh0ZW5zaW9uU2xvdHM7XG4gICAgcmV0dXJuIGNvbmZpZztcbn1cbmZ1bmN0aW9uIGdldENvbmZpZ0Zvck1vZHVsZUltcGxpY2l0U2NoZW1hKG1vZHVsZU5hbWUsIGNvbmZpZ1N0YXRlLCB0ZW1wQ29uZmlnU3RhdGUpIHtcbiAgICBjb25zdCBpbnB1dENvbmZpZyA9IG1lcmdlQ29uZmlnc0Zvcihtb2R1bGVOYW1lLCBnZXRQcm92aWRlZENvbmZpZ3MoY29uZmlnU3RhdGUsIHRlbXBDb25maWdTdGF0ZSkpO1xuICAgIGNvbnN0IGNvbmZpZyA9IHNldERlZmF1bHRzKGltcGxpY2l0Q29uZmlnU2NoZW1hLCBpbnB1dENvbmZpZyk7XG4gICAgcnVuQWxsVmFsaWRhdG9yc0luQ29uZmlnVHJlZShpbXBsaWNpdENvbmZpZ1NjaGVtYSwgY29uZmlnLCBtb2R1bGVOYW1lKTtcbiAgICBkZWxldGUgY29uZmlnLmV4dGVuc2lvblNsb3RzO1xuICAgIHJldHVybiBjb25maWc7XG59XG5mdW5jdGlvbiBtZXJnZUNvbmZpZ3NGb3IobW9kdWxlTmFtZSwgYWxsQ29uZmlncykge1xuICAgIGNvbnN0IGFsbENvbmZpZ3NGb3JNb2R1bGUgPSBhbGxDb25maWdzLm1hcCgoeyBbbW9kdWxlTmFtZV06IGMgfSk9PmMpLmZpbHRlcigoYyk9PiEhYyk7XG4gICAgcmV0dXJuIG1lcmdlQ29uZmlncyhhbGxDb25maWdzRm9yTW9kdWxlKTtcbn1cbi8qKlxuICogTWVyZ2VzIGEgd2hvbGUgbGlzdCBhdCBvbmNlLCBhY2N1bXVsYXRpbmcgaW50byBvbmUgZGVzdGluYXRpb24uXG4gKi8gZnVuY3Rpb24gbWVyZ2VDb25maWdzKGNvbmZpZ3MpIHtcbiAgICByZXR1cm4gY29uZmlncy5yZWR1Y2UoKGFjYywgY29uZmlnKT0+bWVyZ2VXaXRoKGFjYywgY29uZmlnLCByZXBsYWNlQXJyYXlzKSwge30pO1xufVxuLyoqXG4gKiBSZWN1cnNpdmVseSBjaGVjayB0aGUgcHJvdmlkZWQgY29uZmlnIHRyZWUgdG8gbWFrZSBzdXJlIHRoYXQgYWxsXG4gKiBvZiB0aGUgcHJvdmlkZWQgcHJvcGVydGllcyBleGlzdCBpbiB0aGUgc2NoZW1hLCBhbmQgdGhhdCB0eXBlcyBhcmVcbiAqIGNvcnJlY3QuIERvZXMgbm90IHJ1biB2YWxpZGF0b3JzIHlldCwgc2luY2UgdGhvc2Ugd2lsbCBiZSBydW4gb25cbiAqIHRoZSBjb25maWcgd2l0aCB0aGUgZGVmYXVsdHMgZmlsbGVkIGluLlxuICovIGZ1bmN0aW9uIHZhbGlkYXRlU3RydWN0dXJlKHNjaGVtYSwgY29uZmlnLCBrZXlQYXRoID0gJycpIHtcbiAgICAvLyB2YWxpZGF0ZSBlYWNoIGNvbnN0aXR1ZW50IGVsZW1lbnRcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhjb25maWcpKXtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBjb25maWdba2V5XTtcbiAgICAgICAgY29uc3QgdGhpc0tleVBhdGggPSBrZXlQYXRoICsgJy4nICsga2V5O1xuICAgICAgICBjb25zdCBzY2hlbWFQYXJ0ID0gc2NoZW1hW2tleV07XG4gICAgICAgIGlmICghc2NoZW1hLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGlmICghKGtleSA9PT0gJ2V4dGVuc2lvblNsb3RzJyAmJiBrZXlQYXRoICE9PSAnJykpIHtcbiAgICAgICAgICAgICAgICBsb2dFcnJvcih0aGlzS2V5UGF0aCwgYFVua25vd24gY29uZmlnIGtleSAnJHt0aGlzS2V5UGF0aH0nIHByb3ZpZGVkLiBJZ25vcmluZy5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHZhbGlkYXRlQnJhbmNoU3RydWN0dXJlKHNjaGVtYVBhcnQsIHZhbHVlLCB0aGlzS2V5UGF0aCk7XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIGtleVBhdGgpIHtcbiAgICBjaGVja1R5cGUoa2V5UGF0aCwgc2NoZW1hUGFydC5fdHlwZSwgdmFsdWUpO1xuICAgIGlmIChpc09yZGluYXJ5T2JqZWN0KHZhbHVlKSkge1xuICAgICAgICBpZiAoc2NoZW1hUGFydC5fdHlwZSA9PT0gVHlwZS5PYmplY3QpIHtcbiAgICAgICAgICAgIC8vIHZhbGlkYXRlIGFzIGZyZWVmb3JtIG9iamVjdFxuICAgICAgICAgICAgdmFsaWRhdGVGcmVlZm9ybU9iamVjdFN0cnVjdHVyZShzY2hlbWFQYXJ0LCB2YWx1ZSwga2V5UGF0aCk7XG4gICAgICAgIH0gZWxzZSBpZiAoIShzY2hlbWFQYXJ0Lmhhc093blByb3BlcnR5KCdfZGVmYXVsdCcpIHx8IHNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ190eXBlJykpKSB7XG4gICAgICAgICAgICAvLyB2YWxpZGF0ZSBhcyBub3JtYWwgbmVzdGVkIGNvbmZpZ1xuICAgICAgICAgICAgdmFsaWRhdGVTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIGtleVBhdGgpO1xuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuQXJyYXkpIHtcbiAgICAgICAgICAgIHZhbGlkYXRlQXJyYXlTdHJ1Y3R1cmUoc2NoZW1hUGFydCwgdmFsdWUsIGtleVBhdGgpO1xuICAgICAgICB9XG4gICAgfVxufVxuZnVuY3Rpb24gdmFsaWRhdGVGcmVlZm9ybU9iamVjdFN0cnVjdHVyZShmcmVlZm9ybU9iamVjdFNjaGVtYSwgY29uZmlnLCBrZXlQYXRoKSB7XG4gICAgaWYgKGZyZWVmb3JtT2JqZWN0U2NoZW1hLl9lbGVtZW50cykge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhjb25maWcpKXtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY29uZmlnW2tleV07XG4gICAgICAgICAgICB2YWxpZGF0ZUJyYW5jaFN0cnVjdHVyZShmcmVlZm9ybU9iamVjdFNjaGVtYS5fZWxlbWVudHMsIHZhbHVlLCBgJHtrZXlQYXRofS4ke2tleX1gKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlQXJyYXlTdHJ1Y3R1cmUoYXJyYXlTY2hlbWEsIHZhbHVlLCBrZXlQYXRoKSB7XG4gICAgY29uc3QgdmFsaWRhdGVkQXNBcnJheSA9IGNoZWNrVHlwZShrZXlQYXRoLCBUeXBlLkFycmF5LCB2YWx1ZSk7XG4gICAgaWYgKCF2YWxpZGF0ZWRBc0FycmF5KSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gaWYgdGhlcmUgaXMgYW4gYXJyYXkgZWxlbWVudCBvYmplY3Qgc2NoZW1hLCB2ZXJpZnkgdGhhdCBlbGVtZW50cyBtYXRjaCBpdFxuICAgIGlmIChoYXNPYmplY3RTY2hlbWEoYXJyYXlTY2hlbWEuX2VsZW1lbnRzKSkge1xuICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspe1xuICAgICAgICAgICAgdmFsaWRhdGVCcmFuY2hTdHJ1Y3R1cmUoYXJyYXlTY2hlbWEuX2VsZW1lbnRzLCB2YWx1ZVtpXSwgYCR7a2V5UGF0aH1bJHtpfV1gKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IobGV0IGkgPSAwOyBpIDwgdmFsdWUubGVuZ3RoOyBpKyspe1xuICAgICAgICBjaGVja1R5cGUoYCR7a2V5UGF0aH1bJHtpfV1gLCBhcnJheVNjaGVtYS5fZWxlbWVudHM/Ll90eXBlLCB2YWx1ZVtpXSk7XG4gICAgfVxufVxuLyoqXG4gKiBSdW4gYWxsIHRoZSB2YWxpZGF0b3JzIGluIHRoZSBjb25maWcgdHJlZS4gVGhpcyBzaG91bGQgYmUgcnVuXG4gKiBvbiB0aGUgY29uZmlnIG9iamVjdCBhZnRlciBpdCBoYXMgYmVlbiBmaWxsZWQgaW4gd2l0aCBhbGwgdGhlIGRlZmF1bHRzLCBzaW5jZVxuICogaGlnaGVyLWxldmVsIHZhbGlkYXRvcnMgbWF5IHJlZmVyIHRvIGRlZmF1bHQgdmFsdWVzLlxuICovIGZ1bmN0aW9uIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLCBjb25maWcsIGtleVBhdGggPSAnJykge1xuICAgIC8vIElmIGAhc2NoZW1hYCwgdGhlcmUgc2hvdWxkIGhhdmUgYmVlbiBhIHN0cnVjdHVyYWwgdmFsaWRhdGlvbiBlcnJvciBwcmludGVkIGFscmVhZHkuXG4gICAgaWYgKHNjaGVtYSkge1xuICAgICAgICBpZiAoY29uZmlnICE9PSBzY2hlbWEuX2RlZmF1bHQpIHtcbiAgICAgICAgICAgIHJ1blZhbGlkYXRvcnMoa2V5UGF0aCwgc2NoZW1hLl92YWxpZGF0b3JzLCBjb25maWcpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc09yZGluYXJ5T2JqZWN0KGNvbmZpZykpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGNvbmZpZykpe1xuICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gY29uZmlnW2tleV07XG4gICAgICAgICAgICAgICAgY29uc3QgdGhpc0tleVBhdGggPSBrZXlQYXRoICsgJy4nICsga2V5O1xuICAgICAgICAgICAgICAgIGNvbnN0IHNjaGVtYVBhcnQgPSBzY2hlbWFba2V5XTtcbiAgICAgICAgICAgICAgICBpZiAoc2NoZW1hLl90eXBlID09PSBUeXBlLk9iamVjdCAmJiBzY2hlbWEuX2VsZW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHJ1bkFsbFZhbGlkYXRvcnNJbkNvbmZpZ1RyZWUoc2NoZW1hLl9lbGVtZW50cywgdmFsdWUsIHRoaXNLZXlQYXRoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYVBhcnQsIHZhbHVlLCB0aGlzS2V5UGF0aCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoY29uZmlnKSAmJiBzY2hlbWEuX2VsZW1lbnRzKSB7XG4gICAgICAgICAgICBmb3IobGV0IGkgPSAwOyBpIDwgY29uZmlnLmxlbmd0aDsgaSsrKXtcbiAgICAgICAgICAgICAgICBydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlKHNjaGVtYS5fZWxlbWVudHMsIGNvbmZpZ1tpXSwgYCR7a2V5UGF0aH1bJHtpfV1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cbi8qKlxuICogUnVuIHR5cGUgdmFsaWRhdGlvbiBmb3IgdGhlIHZhbHVlLCBsb2dnaW5nIGFueSBlcnJvcnMuXG4gKiBAcmV0dXJucyB0cnVlIGlmIHZhbGlkYXRpb24gcGFzc2VzLCBmYWxzZSBvdGhlcndpc2VcbiAqLyBmdW5jdGlvbiBjaGVja1R5cGUoa2V5UGF0aCwgX3R5cGUsIHZhbHVlKSB7XG4gICAgaWYgKF90eXBlKSB7XG4gICAgICAgIGNvbnN0IHZhbGlkYXRvciA9IHtcbiAgICAgICAgICAgIEFycmF5OiBpc0FycmF5LFxuICAgICAgICAgICAgQm9vbGVhbjogaXNCb29sZWFuLFxuICAgICAgICAgICAgQ29uY2VwdFV1aWQ6IGlzVXVpZCxcbiAgICAgICAgICAgIE51bWJlcjogaXNOdW1iZXIsXG4gICAgICAgICAgICBPYmplY3Q6IGlzT2JqZWN0LFxuICAgICAgICAgICAgU3RyaW5nOiBpc1N0cmluZyxcbiAgICAgICAgICAgIFVVSUQ6IGlzVXVpZCxcbiAgICAgICAgICAgIFBlcnNvbkF0dHJpYnV0ZVR5cGVVdWlkOiBpc1V1aWQsXG4gICAgICAgICAgICBQYXRpZW50SWRlbnRpZmllclR5cGVVdWlkOiBpc1V1aWRcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIHJ1blZhbGlkYXRvcnMoa2V5UGF0aCwgW1xuICAgICAgICAgICAgdmFsaWRhdG9yW190eXBlXVxuICAgICAgICBdLCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuLyoqXG4gKiBSdW5zIHZhbGlkYXRvcnMsIGxvZ2dpbmcgZXJyb3JzLlxuICogQHJldHVybnMgdHJ1ZSBpZiBhbGwgcGFzcywgZmFsc2Ugb3RoZXJ3aXNlLlxuICovIGZ1bmN0aW9uIHJ1blZhbGlkYXRvcnMoa2V5UGF0aCwgdmFsaWRhdG9ycywgdmFsdWUpIHtcbiAgICBsZXQgcmV0dXJuVmFsdWUgPSB0cnVlO1xuICAgIGlmICh2YWxpZGF0b3JzKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBmb3IgKGxldCB2YWxpZGF0b3Igb2YgdmFsaWRhdG9ycyl7XG4gICAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdG9yUmVzdWx0ID0gdmFsaWRhdG9yKHZhbHVlKTtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbGlkYXRvclJlc3VsdCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbWVzc2FnZSA9IHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgPyBgSW52YWxpZCBjb25maWd1cmF0aW9uIGZvciAke2tleVBhdGh9OiAke3ZhbGlkYXRvclJlc3VsdH1gIDogYEludmFsaWQgY29uZmlndXJhdGlvbiB2YWx1ZSAke3ZhbHVlfSBmb3IgJHtrZXlQYXRofTogJHt2YWxpZGF0b3JSZXN1bHR9YDtcbiAgICAgICAgICAgICAgICAgICAgbG9nRXJyb3Ioa2V5UGF0aCwgbWVzc2FnZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVyblZhbHVlID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBTa2lwcGluZyBpbnZhbGlkIHZhbGlkYXRvciBhdCBcIiR7a2V5UGF0aH1cIi4gRW5jb3VudGVyZWQgZXJyb3JcXG5cXHQke2V9YCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJldHVyblZhbHVlO1xufVxuLy8gUmVjdXJzaXZlbHkgZmlsbCBpbiB0aGUgY29uZmlnIHdpdGggdmFsdWVzIGZyb20gdGhlIHNjaGVtYS5cbmNvbnN0IHNldERlZmF1bHRzID0gKHNjaGVtYSwgaW5wdXRDb25maWcpPT57XG4gICAgY29uc3QgY29uZmlnID0gc3RydWN0dXJlZENsb25lKGlucHV0Q29uZmlnKTtcbiAgICBpZiAoIXNjaGVtYSkge1xuICAgICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhzY2hlbWEpKXtcbiAgICAgICAgY29uc3QgY29uZmlnUGFydCA9IGNvbmZpZ1trZXldO1xuICAgICAgICBjb25zdCBzY2hlbWFQYXJ0ID0gc2NoZW1hW2tleV07XG4gICAgICAgIC8vIFRoZSBgc2NoZW1hUGFydCAmJmAgY2xhdXNlIG9mIHRoaXMgYGlmYCBzdGF0ZW1lbnQgd2lsbCBvbmx5IGZhaWxcbiAgICAgICAgLy8gaWYgdGhlIHNjaGVtYSBpcyB2ZXJ5IGludmFsaWQuIEl0IGlzIHRoZXJlIHRvIHByZXZlbnQgdGhlIGFwcCBmcm9tXG4gICAgICAgIC8vIGNyYXNoaW5nIGNvbXBsZXRlbHksIHRob3VnaCBpdCB3aWxsIHByb2R1Y2UgdW5leHBlY3RlZCBiZWhhdmlvci5cbiAgICAgICAgLy8gSWYgdGhpcyBoYXBwZW5zLCB0aGVyZSBzaG91bGQgYmUgbGVnaWJsZSBlcnJvcnMgaW4gdGhlIGNvbnNvbGUgZnJvbVxuICAgICAgICAvLyB0aGUgc2NoZW1hIHZhbGlkYXRvci5cbiAgICAgICAgaWYgKHNjaGVtYVBhcnQgJiYgKHNjaGVtYVBhcnQuaGFzT3duUHJvcGVydHkoJ190eXBlJykgfHwgc2NoZW1hUGFydC5oYXNPd25Qcm9wZXJ0eSgnX2RlZmF1bHQnKSkpIHtcbiAgICAgICAgICAgIC8vIFdlIGFzc3VtZSB0aGF0IHNjaGVtYVBhcnQgZGVmaW5lcyBhIGNvbmZpZyB2YWx1ZSwgc2luY2UgaXQgaGFzXG4gICAgICAgICAgICAvLyBhIHByb3BlcnR5IGBfdHlwZWAgb3IgYF9kZWZhdWx0YC5cbiAgICAgICAgICAgIGlmICghY29uZmlnLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IHNjaGVtYVBhcnRbJ19kZWZhdWx0J107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBXZSBhbHNvIGNoZWNrIGlmIGl0IGlzIGFuIG9iamVjdCBvciBhcnJheSB3aXRoIG9iamVjdCBlbGVtZW50cywgaW4gd2hpY2ggY2FzZSB3ZSByZWN1cnNlXG4gICAgICAgICAgICBjb25zdCBlbGVtZW50cyA9IHNjaGVtYVBhcnQuX2VsZW1lbnRzO1xuICAgICAgICAgICAgaWYgKGNvbmZpZ1BhcnQgJiYgaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzKSkge1xuICAgICAgICAgICAgICAgIGlmIChzY2hlbWFQYXJ0Ll90eXBlID09PSBUeXBlLkFycmF5ICYmIEFycmF5LmlzQXJyYXkoY29uZmlnUGFydCkpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uZmlnV2l0aERlZmF1bHRzID0gY29uZmlnUGFydC5tYXAoKGNvbmYpPT5zZXREZWZhdWx0cyhlbGVtZW50cywgY29uZikpO1xuICAgICAgICAgICAgICAgICAgICBjb25maWdba2V5XSA9IGNvbmZpZ1dpdGhEZWZhdWx0cztcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNjaGVtYVBhcnQuX3R5cGUgPT09IFR5cGUuT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IG9iamVjdEtleSBvZiBPYmplY3Qua2V5cyhjb25maWdQYXJ0KSl7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25maWdQYXJ0W29iamVjdEtleV0gPSBzZXREZWZhdWx0cyhlbGVtZW50cywgY29uZmlnUGFydFtvYmplY3RLZXldKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChpc09yZGluYXJ5T2JqZWN0KHNjaGVtYVBhcnQpKSB7XG4gICAgICAgICAgICAvLyBTaW5jZSBzY2hlbWFQYXJ0IGhhcyBubyBwcm9wZXJ0eSBcIl90eXBlXCIsIGlmIGl0J3MgYW4gb3JkaW5hcnkgb2JqZWN0XG4gICAgICAgICAgICAvLyAodW5saWtlLCBpbXBvcnRhbnRseSwgdGhlIHZhbGlkYXRvcnMgYXJyYXkpLCB3ZSBhc3N1bWUgaXQgaXMgYSBwYXJlbnQgY29uZmlnIHByb3BlcnR5LlxuICAgICAgICAgICAgLy8gV2UgcmVjdXJzZSB0byBjb25maWdba2V5XSBhbmQgc2NoZW1hW2tleV0uIERlZmF1bHQgY29uZmlnW2tleV0gdG8ge30uXG4gICAgICAgICAgICBjb25zdCBzZWxlY3RlZENvbmZpZ1BhcnQgPSBjb25maWdQYXJ0ID8/IHt9O1xuICAgICAgICAgICAgLy8gVGhlcmUgd2lsbCBoYXZlIGJlZW4gYSB2YWxpZGF0aW9uIGVycm9yIGFscmVhZHkgaWYgY29uZmlnUGFydCBpcyBub3QgYSBwbGFpbiBvYmplY3QuXG4gICAgICAgICAgICBpZiAoaXNPcmRpbmFyeU9iamVjdChzZWxlY3RlZENvbmZpZ1BhcnQpKSB7XG4gICAgICAgICAgICAgICAgY29uZmlnW2tleV0gPSBzZXREZWZhdWx0cyhzY2hlbWFQYXJ0LCBzZWxlY3RlZENvbmZpZ1BhcnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb25maWc7XG59O1xuZnVuY3Rpb24gaGFzT2JqZWN0U2NoZW1hKGVsZW1lbnRzU2NoZW1hKSB7XG4gICAgcmV0dXJuICEhZWxlbWVudHNTY2hlbWEgJiYgT2JqZWN0LmtleXMoZWxlbWVudHNTY2hlbWEpLmZpbHRlcigoZSk9PiFbXG4gICAgICAgICAgICAnX2RlZmF1bHQnLFxuICAgICAgICAgICAgJ192YWxpZGF0b3JzJ1xuICAgICAgICBdLmluY2x1ZGVzKGUpKS5sZW5ndGggPiAwO1xufVxuZnVuY3Rpb24gaXNPcmRpbmFyeU9iamVjdCh2YWx1ZSkge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZSAhPT0gbnVsbDtcbn1cbi8qKiBLZWVwIHRyYWNrIG9mIHdoaWNoIHZhbGlkYXRpb24gZXJyb3JzIHdlIGhhdmUgZGlzcGxheWVkLiBFYWNoIG9uZSBzaG91bGQgb25seSBiZSBkaXNwbGF5ZWQgb25jZS4gKi8gbGV0IGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcyA9IG5ldyBTZXQoKTtcbmZ1bmN0aW9uIGxvZ0Vycm9yKGtleVBhdGgsIG1lc3NhZ2UpIHtcbiAgICBjb25zdCBrZXkgPSBgJHtrZXlQYXRofTo6OiR7bWVzc2FnZX1gO1xuICAgIC8vIHRlY2huaWNhbGx5LCB0aGlzIHNob3VsZCBub3QgYmUgcG9zc2libGUsIGJ1dCBiZWNhdXNlIG9mIGhvdyB0aGluZ3Mgd2luZC11cCB0cmFuc3BpbGVkLCB0aGlzIGlzbid0IGltcG9zc2libGVcbiAgICBpZiAoIWRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcykge1xuICAgICAgICBkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMgPSBuZXcgU2V0KCk7XG4gICAgfVxuICAgIGlmICghZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzLmhhcyhrZXkpKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5hZGQoa2V5KTtcbiAgICB9XG59XG4vKipcbiAqIE5vcm1hbGx5LCBjb25maWd1cmF0aW9uIGVycm9ycyBhcmUgb25seSBkaXNwbGF5ZWQgb25jZS4gVGhpcyBmdW5jdGlvbiBjbGVhcnMgdGhlIGxpc3Qgb2ZcbiAqIGRpc3BsYXllZCBlcnJvcnMsIHNvIHRoYXQgdGhleSB3aWxsIGJlIGRpc3BsYXllZCBhZ2Fpbi5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gY2xlYXJDb25maWdFcnJvcnMoa2V5UGF0aCkge1xuICAgIGlmIChrZXlQYXRoKSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5mb3JFYWNoKChrZXkpPT57XG4gICAgICAgICAgICBpZiAoa2V5LnN0YXJ0c1dpdGgoa2V5UGF0aCkpIHtcbiAgICAgICAgICAgICAgICBkaXNwbGF5ZWRWYWxpZGF0aW9uTWVzc2FnZXMuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGRpc3BsYXllZFZhbGlkYXRpb25NZXNzYWdlcy5jbGVhcigpO1xuICAgIH1cbn1cbi8qKlxuICogQ2xlYW5zIHVwIGFsbCBjb25maWcgc3RvcmUgc3Vic2NyaXB0aW9ucyBhbmQgcmUtZXN0YWJsaXNoZXMgdGhlbS4gVGhpcyBpcyBwcmltYXJpbHlcbiAqIHVzZWZ1bCBmb3IgdGVzdGluZywgd2hlcmUgc3Vic2NyaXB0aW9ucyBzZXQgdXAgYXQgbW9kdWxlIGxvYWQgdGltZSBuZWVkIHRvIGJlIGNsZWFyZWRcbiAqIGJldHdlZW4gdGVzdHMgdG8gcHJldmVudCBpbmZpbml0ZSB1cGRhdGUgbG9vcHMuIEFmdGVyIGNsZWFyaW5nLCBzdWJzY3JpcHRpb25zIGFyZVxuICogcmUtZXN0YWJsaXNoZWQgc28gdGhlIGNvbmZpZyBzeXN0ZW0gY29udGludWVzIHRvIHdvcmsgbm9ybWFsbHkuXG4gKlxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIHJlc2V0Q29uZmlnU3lzdGVtKCkge1xuICAgIGNvbmZpZ1N1YnNjcmlwdGlvbnMuZm9yRWFjaCgodW5zdWJzY3JpYmUpPT51bnN1YnNjcmliZSgpKTtcbiAgICBjb25maWdTdWJzY3JpcHRpb25zLmxlbmd0aCA9IDA7XG4gICAgLy8gQ2FjaGVkIGNvbmZpZ3MgYXJlIGtleWVkIG9uIGlucHV0IGlkZW50aXR5LCBzbyBhIHRlc3QgdGhhdCByZXVzZXMgdGhlIHNhbWUgc2NoZW1hIG9yIGNvbmZpZ1xuICAgIC8vIG9iamVjdHMgYWNyb3NzIGNhc2VzIHdvdWxkIG90aGVyd2lzZSBiZSBzZXJ2ZWQgdGhlIHByZXZpb3VzIGNhc2UncyByZXN1bHQuXG4gICAgbW9kdWxlQ29uZmlnQ2FjaGUuY2xlYXIoKTtcbiAgICBleHRlbnNpb25Db25maWdDYWNoZS5jbGVhcigpO1xuICAgIHNjaGVtYVZhbHVlc0FuZFNvdXJjZXNDYWNoZS5jbGVhcigpO1xuICAgIGltcGxlbWVudGVyVG9vbHNNb2R1bGVDYWNoZS5jbGVhcigpO1xuICAgIGxhc3REZXJpdmF0aW9uID0gbnVsbDtcbiAgICBlbnRyeU9yaWdpbnMgPSBuZXcgV2Vha01hcCgpO1xuICAgIHNldHVwQ29uZmlnU3Vic2NyaXB0aW9ucygpO1xufVxuLyoqXG4gKiBDb3BpZWQgb3ZlciBmcm9tIGVzbS1leHRlbnNpb25zLiBJdCByaWdodGx5IGJlbG9uZ3MgdG8gdGhhdCBtb2R1bGUsIGJ1dCBlc20tY29uZmlnXG4gKiBjYW5ub3QgZGVwZW5kIG9uIGVzbS1leHRlbnNpb25zLlxuICovIGZ1bmN0aW9uIGdldEV4dGVuc2lvbk5hbWVGcm9tSWQoZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBbZXh0ZW5zaW9uTmFtZV0gPSBleHRlbnNpb25JZC5zcGxpdCgnIycpO1xuICAgIHJldHVybiBleHRlbnNpb25OYW1lO1xufVxuLyoqXG4gKiBUaGUgdHJhbnNsYXRpb24gb3ZlcnJpZGVzIHNjaGVtYSBpcyB1c2VkIGluIHRoZSBpbXBsaWNpdCBzY2hlbWEgZ2l2ZW4gdG8gZXZlcnkgbW9kdWxlO1xuICogcGx1cyBhbnkgYWRkaXRpb25hbCB0cmFuc2xhdGlvbiBuYW1lc3BhY2VzIChhdCB0aW1lIG9mIHdyaXRpbmcsIHRoaXMgaXMganVzdCAnY29yZScpLlxuICovIGNvbnN0IHRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hID0ge1xuICAgICdUcmFuc2xhdGlvbiBvdmVycmlkZXMnOiB7XG4gICAgICAgIF9kZXNjcmlwdGlvbjogJ1Blci1sYW5ndWFnZSBvdmVycmlkZXMgZm9yIGZyb250ZW5kIHRyYW5zbGF0aW9ucyBzaG91bGQgYmUga2V5ZWQgYnkgbGFuZ3VhZ2UgY29kZSBhbmQgZWFjaCBsYW5ndWFnZSBkaWN0aW9uYXJ5IGNvbnRhaW5zIHRoZSB0cmFuc2xhdGlvbiBrZXkgYW5kIHRoZSBkaXNwbGF5IHZhbHVlJyxcbiAgICAgICAgX3R5cGU6IFR5cGUuT2JqZWN0LFxuICAgICAgICBfZGVmYXVsdDoge30sXG4gICAgICAgIF92YWxpZGF0b3JzOiBbXG4gICAgICAgICAgICB2YWxpZGF0b3IoKG8pPT5PYmplY3Qua2V5cyhvKS5ldmVyeSgoayk9Pi9eW2Etel17MiwzfSgtW0EtWl17MiwzfSk/JC8udGVzdChrKSksIChvKT0+e1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhZEtleXMgPSBPYmplY3Qua2V5cyhvKS5maWx0ZXIoKGspPT4hL15bYS16XXsyLDN9KC1bQS1aXXsyLDN9KT8kLy50ZXN0KGspKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gYFRoZSAnVHJhbnNsYXRpb24gb3ZlcnJpZGVzJyBvYmplY3Qgc2hvdWxkIGhhdmUgbGFuZ3VhZ2UgY29kZXMgZm9yIGtleXMuIExhbmd1YWdlIGNvZGVzIG11c3QgYmUgaW4gdGhlIGZvcm0gb2YgYSB0d28tdG8tdGhyZWUgbGV0dGVyIGxhbmd1YWdlIGNvZGUgb3B0aW9uYWxseSBmb2xsb3dlZCBieSBhIGh5cGhlbiBhbmQgYSB0d28tdG8tdGhyZWUgbGV0dGVyIGNvdW50cnkgY29kZS4gVGhlIGZvbGxvd2luZyBrZXlzIGRvIG5vdCBjb25mb3JtOiAke2JhZEtleXMuam9pbignLCAnKX0uYDtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIF1cbiAgICB9XG59O1xuLyoqXG4gKiBUaGUgaW1wbGljaXRDb25maWdTY2hlbWEgaXMgaW1wbGljaXRseSBpbmNsdWRlZCBpbiBldmVyeSBjb25maWd1cmF0aW9uIHNjaGVtYVxuICovIGNvbnN0IGltcGxpY2l0Q29uZmlnU2NoZW1hID0ge1xuICAgICdEaXNwbGF5IGNvbmRpdGlvbnMnOiB7XG4gICAgICAgIHByaXZpbGVnZXM6IHtcbiAgICAgICAgICAgIF9kZXNjcmlwdGlvbjogJ1RoZSBwcml2aWxlZ2UocykgdGhlIHVzZXIgbXVzdCBoYXZlIHRvIHVzZSB0aGlzIGV4dGVuc2lvbicsXG4gICAgICAgICAgICBfdHlwZTogVHlwZS5BcnJheSxcbiAgICAgICAgICAgIF9kZWZhdWx0OiBbXVxuICAgICAgICB9LFxuICAgICAgICBleHByZXNzaW9uOiB7XG4gICAgICAgICAgICBfZGVzY3JpcHRpb246ICdUaGUgZXhwcmVzc2lvbiB0aGF0IGRldGVybWluZXMgd2hldGhlciB0aGUgZXh0ZW5zaW9uIGlzIGRpc3BsYXllZCcsXG4gICAgICAgICAgICBfdHlwZTogVHlwZS5TdHJpbmcsXG4gICAgICAgICAgICBfZGVmYXVsdDogdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICB9LFxuICAgIC4uLnRyYW5zbGF0aW9uT3ZlcnJpZGVzU2NoZW1hXG59O1xuIl0sIm5hbWVzIjpbImNsb25lRGVlcCIsImlzRXF1YWwiLCJtZXJnZVdpdGgiLCJvbWl0IiwibG9kYXNoT21pdCIsIlR5cGUiLCJpc0FycmF5IiwiaXNCb29sZWFuIiwiaXNVdWlkIiwiaXNOdW1iZXIiLCJpc09iamVjdCIsImlzU3RyaW5nIiwidmFsaWRhdG9yIiwiY29uZmlnRXh0ZW5zaW9uU3RvcmUiLCJjb25maWdJbnRlcm5hbFN0b3JlIiwiZ2V0Q29uZmlnU3RvcmUiLCJnZXRFeHRlbnNpb25Db25maWciLCJnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlIiwiZ2V0RXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiY2xlYXJDb25maWdEZXJpdmF0aW9uRXJyb3IiLCJpbXBsZW1lbnRlclRvb2xzQ29uZmlnU3RvcmUiLCJpbnZhbGlkYXRlSW1wbGVtZW50ZXJUb29sc0NvbmZpZyIsInJlY29yZENvbmZpZ0Rlcml2YXRpb25FcnJvciIsInNldEltcGxlbWVudGVyVG9vbHNDb25maWdSZWNvbXB1dGVyIiwidGVtcG9yYXJ5Q29uZmlnU3RvcmUiLCJyZXBsYWNlQXJyYXlzIiwiX29ialZhbHVlIiwic3JjVmFsdWUiLCJBcnJheSIsIm1lcmdlRGVlcFJlcGxhY2UiLCJsZWZ0IiwicmlnaHQiLCJjb25maWdTdWJzY3JpcHRpb25zIiwicmVjb21wdXRlQWxsQ29uZmlncyIsImNvbmZpZ1N0YXRlIiwidGVtcENvbmZpZ1N0YXRlIiwiZXh0ZW5zaW9uU3RhdGUiLCJjb25maWdJbnB1dHNVbmNoYW5nZWQiLCJsYXN0RGVyaXZhdGlvbiIsImNvbXB1dGVFeHRlbnNpb25Db25maWdzIiwiY29tcHV0ZU1vZHVsZUNvbmZpZyIsInNsb3RDb25maWdzIiwiZ2V0RXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJjb21wdXRlRXh0ZW5zaW9uU2xvdENvbmZpZ3MiLCJlbnRyeU9yaWdpbnMiLCJXZWFrTWFwIiwic2V0dXBDb25maWdTdWJzY3JpcHRpb25zIiwiY29tcHV0ZUltcGxlbWVudGVyVG9vbHNDb25maWciLCJyZWNvbXB1dGVBbGxDb25maWdzU2FmZWx5IiwiZSIsImNvbnNvbGUiLCJtb2R1bGVDb25maWdDYWNoZSIsIk1hcCIsInN0YXRlIiwidGVtcFN0YXRlIiwibW9kdWxlTmFtZSIsIk9iamVjdCIsIm1vZHVsZVN0b3JlIiwic2NoZW1hIiwibW9kdWxlTG9hZGVkIiwiQm9vbGVhbiIsImNhY2hlZCIsIm5ld1N0YXRlIiwiY29uZmlnIiwiZ2V0Q29uZmlnRm9yTW9kdWxlIiwiZ2V0Q29uZmlnRm9yTW9kdWxlSW1wbGljaXRTY2hlbWEiLCJvbGRTdGF0ZSIsInNsb3RTdG9yZSIsIm9sZFNsb3RzIiwic2xvdHMiLCJjaGFuZ2VkIiwic2xvdE5hbWUiLCJwcmV2aW91cyIsImdldEltcGxlbWVudGVyVG9vbHNDb25maWciLCJleHRlbnNpb25zQ29uZmlnU3RvcmUiLCJvbGRDb25maWdzIiwiY29uZmlncyIsImVudHJ5Q291bnQiLCJleHRlbnNpb24iLCJlbnRyeSIsIm9yaWdpbiIsImNvbXB1dGVFeHRlbnNpb25Db25maWciLCJwcmV2aW91c1Nsb3QiLCJleHRlbnNpb25JZCIsInRvdGFsIiwic2xvdCIsImRlZmluZUNvbmZpZ1NjaGVtYSIsInZhbGlkYXRlQ29uZmlnU2NoZW1hIiwiZW5oYW5jZWRTY2hlbWEiLCJpbXBsaWNpdENvbmZpZ1NjaGVtYSIsInJlZ2lzdGVyTW9kdWxlV2l0aENvbmZpZ1N5c3RlbSIsInJlZ2lzdGVyTW9kdWxlTG9hZCIsInJlZ2lzdGVyVHJhbnNsYXRpb25OYW1lc3BhY2UiLCJuYW1lc3BhY2UiLCJ0cmFuc2xhdGlvbk92ZXJyaWRlc1NjaGVtYSIsImRlZmluZUV4dGVuc2lvbkNvbmZpZ1NjaGVtYSIsImV4dGVuc2lvbk5hbWUiLCJwcm92aWRlIiwic291cmNlTmFtZSIsIndoZW5TdG9yZVJlYWR5Iiwic3RvcmUiLCJyZWFkeSIsInNlbGVjdCIsIlByb21pc2UiLCJyZXNvbHZlIiwidW5zdWJzY3JpYmUiLCJyZXNvbHZlZCIsInVwZGF0ZSIsImdldENvbmZpZyIsImdldFRyYW5zbGF0aW9uT3ZlcnJpZGVzIiwicHJvbWlzZXMiLCJwcm9jZXNzQ29uZmlnIiwicHJvdmlkZWRDb25maWciLCJrZXlQYXRoQ29udGV4dCIsInZhbGlkYXRlU3RydWN0dXJlIiwic2V0RGVmYXVsdHMiLCJydW5BbGxWYWxpZGF0b3JzSW5Db25maWdUcmVlIiwiZXh0ZW5zaW9uQ29uZmlnQ2FjaGUiLCJzbG90TW9kdWxlTmFtZSIsImV4dGVuc2lvbk1vZHVsZU5hbWUiLCJzbG90Q29uZmlnIiwiZ2V0RXh0ZW5zaW9uTmFtZUZyb21JZCIsImV4dGVuc2lvbkNvbmZpZ1NjaGVtYSIsImNhY2hlS2V5IiwiSlNPTiIsIm5hbWVPZlNjaGVtYVNvdXJjZSIsInByb3ZpZGVkQ29uZmlncyIsImdldFByb3ZpZGVkQ29uZmlncyIsInNoYXJlZE92ZXJyaWRlIiwic2xvdE1vZHVsZUNvbmZpZyIsIm1lcmdlQ29uZmlnc0ZvciIsImNvbmZpZ092ZXJyaWRlIiwiZXh0ZW5zaW9uQ29uZmlnIiwiY29tYmluZWRDb25maWciLCJtZXJnZUNvbmZpZ3MiLCJpbXBsZW1lbnRlclRvb2xzTW9kdWxlQ2FjaGUiLCJhbm5vdGF0ZWRTY2hlbWFzIiwiZ2V0QWxsU2NoZW1hc1dpdGhWYWx1ZXNBbmRTb3VyY2VzIiwiY29uZmlnc0FuZFNvdXJjZXMiLCJjIiwibW9kdWxlTmFtZXMiLCJTZXQiLCJyZXN1bHQiLCJhbm5vdGF0ZWRTY2hlbWEiLCJjb25maWdTbGljZXMiLCJzb3VyY2VzIiwic291cmNlIiwic2xpY2UiLCJpIiwibWVyZ2VkIiwidW5kZWZpbmVkIiwiY3JlYXRlVmFsdWVzQW5kU291cmNlc1RyZWUiLCJzY2hlbWFWYWx1ZXNBbmRTb3VyY2VzQ2FjaGUiLCJzY2hlbWFzIiwiYW5ub3RhdGVkIiwiZ2V0U2NoZW1hV2l0aFZhbHVlc0FuZFNvdXJjZXMiLCJpc09yZGluYXJ5T2JqZWN0Iiwib2JqIiwia2V5IiwiYWxsQ29uZmlncyIsInNsb3RDb25maWdQZXJNb2R1bGUiLCJ2YWxpZGF0ZUFsbEV4dGVuc2lvblNsb3RDb25maWdzIiwiY29uZmlndXJlQmxvY2tzIiwiY29uZmlnQnlTbG90TmFtZSIsIl9jb25maWd1cmVCbG9ja3MiLCJfc2xvdE5hbWUiLCJibG9ja3MiLCJjb25maWd1cmUiLCJ2YWxpZGF0ZUV4dGVuc2lvblNsb3RDb25maWciLCJrZXlQYXRoIiwiZXJyb3JQcmVmaXgiLCJpbnZhbGlkS2V5cyIsImsiLCJsb2dFcnJvciIsIm4iLCJ1cGRhdGVNZXNzYWdlIiwidGhpc0tleVBhdGgiLCJzY2hlbWFQYXJ0IiwiZWxlbWVudHMiLCJoYXNPYmplY3RTY2hlbWEiLCJ2YWx1ZVR5cGUiLCJpbnB1dENvbmZpZyIsImFsbENvbmZpZ3NGb3JNb2R1bGUiLCJhY2MiLCJ2YWx1ZSIsInZhbGlkYXRlQnJhbmNoU3RydWN0dXJlIiwiY2hlY2tUeXBlIiwidmFsaWRhdGVGcmVlZm9ybU9iamVjdFN0cnVjdHVyZSIsInZhbGlkYXRlQXJyYXlTdHJ1Y3R1cmUiLCJmcmVlZm9ybU9iamVjdFNjaGVtYSIsImFycmF5U2NoZW1hIiwidmFsaWRhdGVkQXNBcnJheSIsInJ1blZhbGlkYXRvcnMiLCJfdHlwZSIsInZhbGlkYXRvcnMiLCJyZXR1cm5WYWx1ZSIsInZhbGlkYXRvclJlc3VsdCIsIm1lc3NhZ2UiLCJzdHJ1Y3R1cmVkQ2xvbmUiLCJjb25maWdQYXJ0IiwiY29uZmlnV2l0aERlZmF1bHRzIiwiY29uZiIsIm9iamVjdEtleSIsInNlbGVjdGVkQ29uZmlnUGFydCIsImVsZW1lbnRzU2NoZW1hIiwiZGlzcGxheWVkVmFsaWRhdGlvbk1lc3NhZ2VzIiwiY2xlYXJDb25maWdFcnJvcnMiLCJyZXNldENvbmZpZ1N5c3RlbSIsIm8iLCJiYWRLZXlzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsNkJBQTZCLEdBQWlGO0FBQzNFO0FBQ3lFO0FBQ3JEO0FBQytSO0FB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\n//# sourceURL=webpack-internal:///../../framework/esm-config/dist/module-config/module-config.js\n\n}");
4525
4525
 
4526
4526
  },
4527
4527
  "../../framework/esm-config/dist/module-config/state.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -4696,7 +4696,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
4696
4696
  },
4697
4697
  "../../framework/esm-extensions/dist/extensions.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
4698
4698
  "use strict";
4699
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n attach: () => (attach),\n detach: () => (detach),\n detachAll: () => (detachAll),\n getAssignedExtensions: () => (getAssignedExtensions),\n getCandidateExtensions: () => (getCandidateExtensions),\n getExtensionNameFromId: () => (getExtensionNameFromId),\n getExtensionRegistration: () => (getExtensionRegistration),\n getExtensionRegistrationFrom: () => (getExtensionRegistrationFrom),\n registerExtension: () => (registerExtension),\n registerExtensionSlot: () => (registerExtensionSlot),\n reset: () => (reset)\n});\n/* import */ var _openmrs_esm_api__rspack_import_0 = __webpack_require__(\"../../framework/esm-api/dist/index.js\");\n/* import */ var _openmrs_esm_config__rspack_import_1 = __webpack_require__(\"../../framework/esm-config/dist/index.js\");\n/* import */ var _openmrs_esm_expression_evaluator__rspack_import_6 = __webpack_require__(\"../../framework/esm-expression-evaluator/dist/evaluator.js\");\n/* import */ var _openmrs_esm_feature_flags__rspack_import_2 = __webpack_require__(\"../../framework/esm-feature-flags/dist/index.js\");\n/* import */ var lodash_es__rspack_import_4 = __webpack_require__(\"../../../node_modules/lodash-es/isEqual.js\");\n/* import */ var lodash_es__rspack_import_5 = __webpack_require__(\"../../../node_modules/lodash-es/merge.js\");\n/* import */ var _store_js__rspack_import_3 = __webpack_require__(\"../../framework/esm-extensions/dist/store.js\");\n/** @module @category Extension */ /*\n * We have the following extension modes:\n *\n * - attached (set via code in form of: attach, detach, ...)\n * - configured (set via configuration in form of: added, removed, ...)\n * - assigned (computed from attached and configured)\n * - displayed (computed from assigned)\n */ \n\n\n\n\n\nconst extensionInternalStore = (0,_store_js__rspack_import_3.getExtensionInternalStore)();\nconst extensionStore = (0,_store_js__rspack_import_3.getExtensionStore)();\nconst slotsConfigStore = (0,_openmrs_esm_config__rspack_import_1.getExtensionSlotsConfigStore)();\nconst extensionsConfigStore = (0,_openmrs_esm_config__rspack_import_1.getExtensionsConfigStore)();\n/**\n * Slots whose derived state may have changed since the output store was last updated. `null`\n * stands for \"every slot\", and is used when an input changes that isn't scoped to one slot —\n * the session, a feature flag, connectivity, or a new extension registration.\n */ let dirtySlots = new Set();\nlet isRecomputingOutputStore = false;\nfunction markSlotsDirty(slots) {\n if (slots === null) {\n dirtySlots = null;\n } else if (dirtySlots !== null) {\n for (const slotName of slots){\n dirtySlots.add(slotName);\n }\n }\n (0,_store_js__rspack_import_3.scheduleRecomputation)(recomputeExtensionOutputStore);\n}\n/**\n * A subscriber that dirties a slot every time the output store is published would loop here for\n * ever, so the drain gives up after this many passes and leaves the rest for the next write. Any\n * real cascade settles in two or three.\n */ const maxRecomputationPasses = 20;\nfunction recomputeExtensionOutputStore() {\n // Publishing notifies subscribers synchronously, so one that dirties a slot re-enters here. The\n // loop below picks that work up; recursing instead would nest without bound.\n if (isRecomputingOutputStore) {\n return;\n }\n isRecomputingOutputStore = true;\n try {\n for(let pass = 1;; pass++){\n const slots = dirtySlots;\n if (slots !== null && slots.size === 0) {\n return;\n }\n // Taken before the work so that anything dirtied while it runs accumulates for the next pass\n // rather than being discarded when this one finishes.\n dirtySlots = new Set();\n try {\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__rspack_import_2.featureFlagsStore.getState(), _openmrs_esm_api__rspack_import_0.sessionStore.getState(), slots);\n } catch (e) {\n // Fold the work back in, so a failure leaves these slots marked for the next recomputation\n // instead of stranding them stale.\n dirtySlots = slots === null || dirtySlots === null ? null : new Set([\n ...slots,\n ...dirtySlots\n ]);\n throw e;\n }\n if (pass >= maxRecomputationPasses) {\n console.error(`The extension system stopped recomputing after ${maxRecomputationPasses} passes because ` + `something keeps invalidating slots in response to the extension store being written. ` + `Some slots are left stale until the next write.`);\n return;\n }\n }\n } finally{\n isRecomputingOutputStore = false;\n }\n}\n/**\n * Re-derives the output store from the extension system's inputs.\n *\n * Two things keep this cheap. `dirtySlotNames` limits which slots are recomputed at all; passing\n * `null` recomputes every slot. And slots whose derived value hasn't changed keep their existing\n * object, so that components subscribed to one slot don't re-render because a different slot\n * changed.\n */ function updateExtensionOutputStore(internalState, extensionSlotConfigs, extensionsConfigState, featureFlagState, sessionState, dirtySlotNames = null) {\n const previousSlots = extensionStore.getState().slots;\n const slots = {};\n let changed = false;\n const enabledFeatureFlags = Object.entries(featureFlagState.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n for (let [slotName, slot] of Object.entries(internalState.slots)){\n const previous = previousSlots[slotName];\n if (previous && dirtySlotNames && !dirtySlotNames.has(slotName)) {\n slots[slotName] = previous;\n continue;\n }\n const { config } = (0,_openmrs_esm_config__rspack_import_1.getExtensionSlotConfigFromStore)(extensionSlotConfigs, slot.name);\n const candidateExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigState, enabledFeatureFlags, sessionState.session);\n if (previous && previous.moduleName === slot.moduleName && (0,lodash_es__rspack_import_4[\"default\"])(previous.candidateExtensions, candidateExtensions)) {\n slots[slotName] = previous;\n } else {\n slots[slotName] = {\n moduleName: slot.moduleName,\n candidateExtensions\n };\n changed = true;\n }\n }\n if (changed || Object.keys(previousSlots).length !== Object.keys(slots).length) {\n extensionStore.setState({\n slots\n });\n }\n}\n/**\n * Returns the keys whose values differ between two records, including keys present in only one.\n */ function changedKeys(next, previous) {\n const changed = new Set();\n for (const key of Object.keys(next)){\n if (next[key] !== previous[key]) {\n changed.add(key);\n }\n }\n for (const key of Object.keys(previous)){\n if (!(key in next)) {\n changed.add(key);\n }\n }\n return changed;\n}\nextensionInternalStore.subscribe((state, previousState)=>{\n // A new or changed registration can affect any slot the extension might be assigned to. Every\n // other kind of change here — attaching, registering a slot — is scoped to the slots whose\n // entries actually changed.\n markSlotsDirty(state.extensions !== previousState.extensions ? null : changedKeys(state.slots, previousState.slots));\n});\n// Slot configs are per-slot, so a config change invalidates only the slots it names.\nslotsConfigStore.subscribe((state, previousState)=>{\n markSlotsDirty(changedKeys(state.slots, previousState.slots));\n});\n// Extension configs are keyed by slot too, and the config system hands back the same per-slot\n// object when nothing under it changed, so only the slots whose configs actually moved are dirtied.\nextensionsConfigStore.subscribe((state, previousState)=>{\n markSlotsDirty(changedKeys(state.configs, previousState.configs));\n});\n_openmrs_esm_feature_flags__rspack_import_2.featureFlagsStore.subscribe(()=>markSlotsDirty(null));\n_openmrs_esm_api__rspack_import_0.sessionStore.subscribe(()=>markSlotsDirty(null));\nfunction updateOutputStoreToCurrent() {\n markSlotsDirty(null);\n}\nupdateOutputStoreToCurrent();\nfunction createNewExtensionSlotInfo(slotName, moduleName) {\n return {\n moduleName,\n name: slotName,\n attachedIds: []\n };\n}\n/**\n * Given an extension ID, which is a string uniquely identifying\n * an instance of an extension within an extension slot, this\n * returns the extension name.\n *\n * @example\n * ```js\n * getExtensionNameFromId(\"foo#bar\")\n * --> \"foo\"\n * getExtensionNameFromId(\"baz\")\n * --> \"baz\"\n * ```\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\nfunction getExtensionRegistrationFrom(state, extensionId) {\n const name = getExtensionNameFromId(extensionId);\n return state.extensions[name];\n}\nfunction getExtensionRegistration(extensionId) {\n const state = extensionInternalStore.getState();\n return getExtensionRegistrationFrom(state, extensionId);\n}\n/**\n * Extensions must be registered in order to be rendered.\n * This is handled by the app shell, when extensions are provided\n * via the `routes.json` file and registered through `registerApp()`.\n * @internal\n */ const registerExtension = (extensionRegistration)=>(0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>({\n ...state,\n extensions: {\n ...state.extensions,\n [extensionRegistration.name]: {\n ...extensionRegistration\n }\n }\n }));\n/**\n * Attach an extension to an extension slot.\n *\n * This will cause the extension to be rendered into the specified\n * extension slot, unless it is removed by configuration. Using\n * `attach` is an alternative to specifying the `slot` or `slots`\n * in the extension declaration.\n *\n * It is particularly useful when creating a slot into which\n * you want to render an existing extension. This enables you\n * to do so without modifying the extension's declaration, which\n * may be impractical or inappropriate, for example if you are\n * writing a module for a specific implementation.\n *\n * @param slotName a name uniquely identifying the slot\n * @param extensionId an extension name, with an optional #-suffix\n * to distinguish it from other instances of the same extension\n * attached to the same slot.\n */ function attach(slotName, extensionId) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[slotName];\n if (!existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...createNewExtensionSlotInfo(slotName),\n attachedIds: [\n extensionId\n ]\n }\n }\n };\n } else {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...existingSlot,\n attachedIds: [\n ...existingSlot.attachedIds,\n extensionId\n ]\n }\n }\n };\n }\n });\n}\n/**\n * Detaches an extension from an extension slot.\n *\n * @param extensionSlotName The name of the extension slot to detach from.\n * @param extensionId The ID of the extension to detach.\n *\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detach(extensionSlotName, extensionId) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot && existingSlot.attachedIds.includes(extensionId)) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: existingSlot.attachedIds.filter((id)=>id !== extensionId)\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * Detaches all extensions from an extension slot.\n *\n * @param extensionSlotName The name of the extension slot to clear.\n *\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detachAll(extensionSlotName) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: []\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * Get an order index for the extension. This will\n * come from either its configured order, its registered order\n * parameter, or the order in which it happened to be attached.\n *\n * The four bands below keep the comparison a total order: every extension lands in exactly one, and\n * those with no ordering information share the last band rather than taking a sentinel that can't be\n * compared against itself.\n */ function getOrder(extensionId, configuredOrder, registeredOrderIndex, attachedOrder) {\n const configuredIndex = configuredOrder.indexOf(extensionId);\n if (configuredIndex !== -1) {\n return configuredIndex;\n } else if (registeredOrderIndex !== undefined) {\n // extensions that don't have a configured order should appear after those that do\n return 1000 + registeredOrderIndex;\n } else {\n const assignedIndex = attachedOrder.indexOf(extensionId);\n if (assignedIndex !== -1) {\n // extensions that have neither a configured nor registered order should appear\n // after all others\n return 2000 + assignedIndex;\n } else {\n // Added by configuration with no order of any kind — after everything else, and among\n // themselves in the order the configuration lists them.\n return 3000;\n }\n }\n}\nfunction getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags, session) {\n const attachedIds = internalState.slots[slotName].attachedIds;\n const assignedIds = calculateAssignedIds(config, attachedIds);\n const extensions = [];\n for (let id of assignedIds){\n const { config: rawExtensionConfig } = (0,_openmrs_esm_config__rspack_import_1.getExtensionConfigFromStore)(extensionConfigStoreState, slotName, id);\n const rawExtensionSlotExtensionConfig = (0,_openmrs_esm_config__rspack_import_1.getExtensionConfigFromExtensionSlotStore)(config, slotName, id);\n // `merge` mutates its first argument, and `rawExtensionConfig` belongs to the config store,\n // so never merge into it.\n const extensionConfig = rawExtensionSlotExtensionConfig ? (0,lodash_es__rspack_import_5[\"default\"])({}, rawExtensionConfig, rawExtensionSlotExtensionConfig) : rawExtensionConfig;\n const name = getExtensionNameFromId(id);\n const extension = internalState.extensions[name];\n // if the extension has not been registered yet, do not include it\n if (extension) {\n const requiredPrivileges = extensionConfig?.['Display conditions']?.privileges ?? extension.privileges ?? [];\n if (requiredPrivileges && (typeof requiredPrivileges === 'string' || Array.isArray(requiredPrivileges) && requiredPrivileges.length > 0)) {\n if (!session?.user) {\n continue;\n }\n if (!(0,_openmrs_esm_api__rspack_import_0.userHasAccess)(requiredPrivileges, session.user)) {\n continue;\n }\n }\n if (extension.featureFlag && !enabledFeatureFlags.includes(extension.featureFlag)) {\n continue;\n }\n extensions.push({\n id,\n name,\n moduleName: extension.moduleName,\n config: extensionConfig,\n featureFlag: extension.featureFlag,\n meta: extension.meta,\n displayConditionExpression: extensionConfig?.['Display conditions']?.expression || extension.displayExpression\n });\n }\n }\n return extensions;\n}\n/**\n * Narrows `extensions` to those whose display condition holds for one particular rendering of a\n * slot, evaluating each condition against `state`.\n *\n * An extension whose display condition throws is left out, on the grounds that a condition that cannot be\n * evaluated has not been met.\n *\n * @param extensions The extensions assigned to the slot, as the extension store holds them\n * @param state The state of this rendering of the slot\n * @param session The current session, which conditions may refer to as `session`\n * @param slotName The slot these were assigned to, used only to identify them if a condition throws\n * @returns Those of `extensions` that should be displayed, in the same order. Always a new array.\n */ function filterExtensionsByDisplayConditions(extensions, state, session = null, slotName) {\n // Built once for the whole slot rather than per extension: the context is the same for all of\n // them, and most slots have no conditions at all.\n let expressionContext;\n return extensions.filter((extension)=>{\n const expression = extension.displayConditionExpression;\n if (typeof expression !== 'string' || expression.trim().length === 0) {\n return true;\n }\n expressionContext ?? (expressionContext = state && typeof state === 'object' ? {\n session,\n ...state\n } : {\n session\n });\n try {\n return Boolean((0,_openmrs_esm_expression_evaluator__rspack_import_6.evaluateAsBoolean)(expression, expressionContext));\n } catch (e) {\n console.error(`Error while evaluating expression '${expression}' for ${extension.id}` + (slotName ? ` in ${slotName}` : ''), e);\n return false;\n }\n });\n}\n/**\n * Gets the extensions a given rendering of a slot should display, in order. This is the supported\n * way to ask what belongs in a slot; reading the extension store directly skips display conditions.\n *\n * Display conditions are evaluated against `state`, so pass whatever the slot is being rendered\n * for. The same slot can be rendered many times with different state — once per row of a table,\n * say — and each rendering can resolve to a different set of extensions. Omitting `state` hides\n * every extension whose condition refers to it, since the condition cannot be evaluated.\n *\n * @param slotName The slot to load the extensions for\n * @param state The state of the rendering of the slot the extensions will be displayed in\n * @returns Those extensions assigned to the slot whose display conditions hold\n */ function getAssignedExtensions(slotName, state) {\n return filterExtensionsByDisplayConditions(getCandidateExtensions(slotName), state, _openmrs_esm_api__rspack_import_0.sessionStore.getState().session, slotName);\n}\n/**\n * Gets everything assigned to a slot without evaluating any display condition, which\n * {@link getAssignedExtensions} cannot do without knowing the state of a particular rendering.\n *\n * This exists for tools that present a slot's configuration rather than render it — the UI editor\n * has to list an extension in order to let an implementer reorder or remove it, even where no\n * rendering would display it. Anything deciding what to render wants `getAssignedExtensions()`.\n *\n * @internal\n */ function getCandidateExtensions(slotName) {\n return extensionStore.getState().slots[slotName]?.candidateExtensions ?? [];\n}\nfunction calculateAssignedIds(config, attachedIds) {\n const addedIds = config.add || [];\n const removedIds = config.remove || [];\n const idOrder = config.order || [];\n const { extensions } = extensionInternalStore.getState();\n return [\n ...attachedIds,\n ...addedIds\n ].filter((id)=>!removedIds.includes(id)).sort((idA, idB)=>{\n const ai = getOrder(idA, idOrder, extensions[getExtensionNameFromId(idA)]?.order, attachedIds);\n const bi = getOrder(idB, idOrder, extensions[getExtensionNameFromId(idB)]?.order, attachedIds);\n // Ties keep their input order — `Array.prototype.sort` is stable, and the input is\n // `[...attachedIds, ...addedIds]`, so two extensions the ordering rules can't separate\n // come out in the order the code and the configuration declared them.\n return ai - bi;\n });\n}\n/**\n * Used by by extension slots at mount time.\n *\n * @param moduleName The name of the module that contains the extension slot\n * @param slotName The extension slot name that is actually used\n * @internal\n */ const registerExtensionSlot = (moduleName, slotName)=>extensionInternalStore.setState((currentState)=>{\n const existingModuleName = currentState.slots[slotName]?.moduleName;\n if (existingModuleName && existingModuleName != moduleName) {\n console.warn(`An extension slot with the name '${slotName}' already exists. Refusing to register the same slot name twice (in \"registerExtensionSlot\"). The existing one is from module ${existingModuleName}.`);\n return currentState;\n }\n if (existingModuleName && existingModuleName == moduleName) {\n // Re-rendering an existing slot\n return currentState;\n }\n if (currentState.slots[slotName]) {\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n moduleName\n }\n }\n };\n }\n const slot = createNewExtensionSlotInfo(slotName, moduleName);\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...slot\n }\n }\n };\n });\n/**\n * @internal\n * Just for testing.\n */ const reset = ()=>{\n // Invalidation is carried in module state, so it has to be reset too or it bleeds into the\n // next test as either a stale dirty set or a missing one.\n dirtySlots = null;\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)(()=>({\n slots: {},\n extensions: {}\n }));\n (0,_store_js__rspack_import_3.getExtensionRenderingsStore)().setState({\n renderings: new Map()\n });\n extensionStore.setState({\n slots: {}\n });\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcz84NWQ4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbW9kdWxlIEBjYXRlZ29yeSBFeHRlbnNpb24gKi8gLypcbiAqIFdlIGhhdmUgdGhlIGZvbGxvd2luZyBleHRlbnNpb24gbW9kZXM6XG4gKlxuICogLSBhdHRhY2hlZCAoc2V0IHZpYSBjb2RlIGluIGZvcm0gb2Y6IGF0dGFjaCwgZGV0YWNoLCAuLi4pXG4gKiAtIGNvbmZpZ3VyZWQgKHNldCB2aWEgY29uZmlndXJhdGlvbiBpbiBmb3JtIG9mOiBhZGRlZCwgcmVtb3ZlZCwgLi4uKVxuICogLSBhc3NpZ25lZCAoY29tcHV0ZWQgZnJvbSBhdHRhY2hlZCBhbmQgY29uZmlndXJlZClcbiAqIC0gZGlzcGxheWVkIChjb21wdXRlZCBmcm9tIGFzc2lnbmVkKVxuICovIGltcG9ydCB7IHNlc3Npb25TdG9yZSwgdXNlckhhc0FjY2VzcyB9IGZyb20gXCJAb3Blbm1ycy9lc20tYXBpXCI7XG5pbXBvcnQgeyBnZXRFeHRlbnNpb25Db25maWdGcm9tRXh0ZW5zaW9uU2xvdFN0b3JlLCBnZXRFeHRlbnNpb25Db25maWdGcm9tU3RvcmUsIGdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUsIGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUsIGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSB9IGZyb20gXCJAb3Blbm1ycy9lc20tY29uZmlnXCI7XG5pbXBvcnQgeyBldmFsdWF0ZUFzQm9vbGVhbiB9IGZyb20gXCJAb3Blbm1ycy9lc20tZXhwcmVzc2lvbi1ldmFsdWF0b3JcIjtcbmltcG9ydCB7IGZlYXR1cmVGbGFnc1N0b3JlIH0gZnJvbSBcIkBvcGVubXJzL2VzbS1mZWF0dXJlLWZsYWdzXCI7XG5pbXBvcnQgeyBpc0VxdWFsLCBtZXJnZSB9IGZyb20gXCJsb2Rhc2gtZXNcIjtcbmltcG9ydCB7IGdldEV4dGVuc2lvblJlbmRlcmluZ3NTdG9yZSwgZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSwgZ2V0RXh0ZW5zaW9uU3RvcmUsIHNjaGVkdWxlUmVjb21wdXRhdGlvbiwgdXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSB9IGZyb20gXCIuL3N0b3JlLmpzXCI7XG5jb25zdCBleHRlbnNpb25JbnRlcm5hbFN0b3JlID0gZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSgpO1xuY29uc3QgZXh0ZW5zaW9uU3RvcmUgPSBnZXRFeHRlbnNpb25TdG9yZSgpO1xuY29uc3Qgc2xvdHNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUoKTtcbmNvbnN0IGV4dGVuc2lvbnNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSgpO1xuLyoqXG4gKiBTbG90cyB3aG9zZSBkZXJpdmVkIHN0YXRlIG1heSBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIG91dHB1dCBzdG9yZSB3YXMgbGFzdCB1cGRhdGVkLiBgbnVsbGBcbiAqIHN0YW5kcyBmb3IgXCJldmVyeSBzbG90XCIsIGFuZCBpcyB1c2VkIHdoZW4gYW4gaW5wdXQgY2hhbmdlcyB0aGF0IGlzbid0IHNjb3BlZCB0byBvbmUgc2xvdCDigJRcbiAqIHRoZSBzZXNzaW9uLCBhIGZlYXR1cmUgZmxhZywgY29ubmVjdGl2aXR5LCBvciBhIG5ldyBleHRlbnNpb24gcmVnaXN0cmF0aW9uLlxuICovIGxldCBkaXJ0eVNsb3RzID0gbmV3IFNldCgpO1xubGV0IGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSA9IGZhbHNlO1xuZnVuY3Rpb24gbWFya1Nsb3RzRGlydHkoc2xvdHMpIHtcbiAgICBpZiAoc2xvdHMgPT09IG51bGwpIHtcbiAgICAgICAgZGlydHlTbG90cyA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChkaXJ0eVNsb3RzICE9PSBudWxsKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc2xvdE5hbWUgb2Ygc2xvdHMpe1xuICAgICAgICAgICAgZGlydHlTbG90cy5hZGQoc2xvdE5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNjaGVkdWxlUmVjb21wdXRhdGlvbihyZWNvbXB1dGVFeHRlbnNpb25PdXRwdXRTdG9yZSk7XG59XG4vKipcbiAqIEEgc3Vic2NyaWJlciB0aGF0IGRpcnRpZXMgYSBzbG90IGV2ZXJ5IHRpbWUgdGhlIG91dHB1dCBzdG9yZSBpcyBwdWJsaXNoZWQgd291bGQgbG9vcCBoZXJlIGZvclxuICogZXZlciwgc28gdGhlIGRyYWluIGdpdmVzIHVwIGFmdGVyIHRoaXMgbWFueSBwYXNzZXMgYW5kIGxlYXZlcyB0aGUgcmVzdCBmb3IgdGhlIG5leHQgd3JpdGUuIEFueVxuICogcmVhbCBjYXNjYWRlIHNldHRsZXMgaW4gdHdvIG9yIHRocmVlLlxuICovIGNvbnN0IG1heFJlY29tcHV0YXRpb25QYXNzZXMgPSAyMDtcbmZ1bmN0aW9uIHJlY29tcHV0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKCkge1xuICAgIC8vIFB1Ymxpc2hpbmcgbm90aWZpZXMgc3Vic2NyaWJlcnMgc3luY2hyb25vdXNseSwgc28gb25lIHRoYXQgZGlydGllcyBhIHNsb3QgcmUtZW50ZXJzIGhlcmUuIFRoZVxuICAgIC8vIGxvb3AgYmVsb3cgcGlja3MgdGhhdCB3b3JrIHVwOyByZWN1cnNpbmcgaW5zdGVhZCB3b3VsZCBuZXN0IHdpdGhvdXQgYm91bmQuXG4gICAgaWYgKGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgICAgZm9yKGxldCBwYXNzID0gMTs7IHBhc3MrKyl7XG4gICAgICAgICAgICBjb25zdCBzbG90cyA9IGRpcnR5U2xvdHM7XG4gICAgICAgICAgICBpZiAoc2xvdHMgIT09IG51bGwgJiYgc2xvdHMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRha2VuIGJlZm9yZSB0aGUgd29yayBzbyB0aGF0IGFueXRoaW5nIGRpcnRpZWQgd2hpbGUgaXQgcnVucyBhY2N1bXVsYXRlcyBmb3IgdGhlIG5leHQgcGFzc1xuICAgICAgICAgICAgLy8gcmF0aGVyIHRoYW4gYmVpbmcgZGlzY2FyZGVkIHdoZW4gdGhpcyBvbmUgZmluaXNoZXMuXG4gICAgICAgICAgICBkaXJ0eVNsb3RzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB1cGRhdGVFeHRlbnNpb25PdXRwdXRTdG9yZShleHRlbnNpb25JbnRlcm5hbFN0b3JlLmdldFN0YXRlKCksIHNsb3RzQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLCBzbG90cyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRm9sZCB0aGUgd29yayBiYWNrIGluLCBzbyBhIGZhaWx1cmUgbGVhdmVzIHRoZXNlIHNsb3RzIG1hcmtlZCBmb3IgdGhlIG5leHQgcmVjb21wdXRhdGlvblxuICAgICAgICAgICAgICAgIC8vIGluc3RlYWQgb2Ygc3RyYW5kaW5nIHRoZW0gc3RhbGUuXG4gICAgICAgICAgICAgICAgZGlydHlTbG90cyA9IHNsb3RzID09PSBudWxsIHx8IGRpcnR5U2xvdHMgPT09IG51bGwgPyBudWxsIDogbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAgIC4uLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICAuLi5kaXJ0eVNsb3RzXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXNzID49IG1heFJlY29tcHV0YXRpb25QYXNzZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUaGUgZXh0ZW5zaW9uIHN5c3RlbSBzdG9wcGVkIHJlY29tcHV0aW5nIGFmdGVyICR7bWF4UmVjb21wdXRhdGlvblBhc3Nlc30gcGFzc2VzIGJlY2F1c2UgYCArIGBzb21ldGhpbmcga2VlcHMgaW52YWxpZGF0aW5nIHNsb3RzIGluIHJlc3BvbnNlIHRvIHRoZSBleHRlbnNpb24gc3RvcmUgYmVpbmcgd3JpdHRlbi4gYCArIGBTb21lIHNsb3RzIGFyZSBsZWZ0IHN0YWxlIHVudGlsIHRoZSBuZXh0IHdyaXRlLmApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZmluYWxseXtcbiAgICAgICAgaXNSZWNvbXB1dGluZ091dHB1dFN0b3JlID0gZmFsc2U7XG4gICAgfVxufVxuLyoqXG4gKiBSZS1kZXJpdmVzIHRoZSBvdXRwdXQgc3RvcmUgZnJvbSB0aGUgZXh0ZW5zaW9uIHN5c3RlbSdzIGlucHV0cy5cbiAqXG4gKiBUd28gdGhpbmdzIGtlZXAgdGhpcyBjaGVhcC4gYGRpcnR5U2xvdE5hbWVzYCBsaW1pdHMgd2hpY2ggc2xvdHMgYXJlIHJlY29tcHV0ZWQgYXQgYWxsOyBwYXNzaW5nXG4gKiBgbnVsbGAgcmVjb21wdXRlcyBldmVyeSBzbG90LiBBbmQgc2xvdHMgd2hvc2UgZGVyaXZlZCB2YWx1ZSBoYXNuJ3QgY2hhbmdlZCBrZWVwIHRoZWlyIGV4aXN0aW5nXG4gKiBvYmplY3QsIHNvIHRoYXQgY29tcG9uZW50cyBzdWJzY3JpYmVkIHRvIG9uZSBzbG90IGRvbid0IHJlLXJlbmRlciBiZWNhdXNlIGEgZGlmZmVyZW50IHNsb3RcbiAqIGNoYW5nZWQuXG4gKi8gZnVuY3Rpb24gdXBkYXRlRXh0ZW5zaW9uT3V0cHV0U3RvcmUoaW50ZXJuYWxTdGF0ZSwgZXh0ZW5zaW9uU2xvdENvbmZpZ3MsIGV4dGVuc2lvbnNDb25maWdTdGF0ZSwgZmVhdHVyZUZsYWdTdGF0ZSwgc2Vzc2lvblN0YXRlLCBkaXJ0eVNsb3ROYW1lcyA9IG51bGwpIHtcbiAgICBjb25zdCBwcmV2aW91c1Nsb3RzID0gZXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKS5zbG90cztcbiAgICBjb25zdCBzbG90cyA9IHt9O1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgY29uc3QgZW5hYmxlZEZlYXR1cmVGbGFncyA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVGbGFnU3RhdGUuZmxhZ3MpLmZpbHRlcigoWywgeyBlbmFibGVkIH1dKT0+ZW5hYmxlZCkubWFwKChbbmFtZV0pPT5uYW1lKTtcbiAgICBmb3IgKGxldCBbc2xvdE5hbWUsIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKGludGVybmFsU3RhdGUuc2xvdHMpKXtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBwcmV2aW91c1Nsb3RzW3Nsb3ROYW1lXTtcbiAgICAgICAgaWYgKHByZXZpb3VzICYmIGRpcnR5U2xvdE5hbWVzICYmICFkaXJ0eVNsb3ROYW1lcy5oYXMoc2xvdE5hbWUpKSB7XG4gICAgICAgICAgICBzbG90c1tzbG90TmFtZV0gPSBwcmV2aW91cztcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSBnZXRFeHRlbnNpb25TbG90Q29uZmlnRnJvbVN0b3JlKGV4dGVuc2lvblNsb3RDb25maWdzLCBzbG90Lm5hbWUpO1xuICAgICAgICBjb25zdCBjYW5kaWRhdGVFeHRlbnNpb25zID0gZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhKHNsb3ROYW1lLCBpbnRlcm5hbFN0YXRlLCBjb25maWcsIGV4dGVuc2lvbnNDb25maWdTdGF0ZSwgZW5hYmxlZEZlYXR1cmVGbGFncywgc2Vzc2lvblN0YXRlLnNlc3Npb24pO1xuICAgICAgICBpZiAocHJldmlvdXMgJiYgcHJldmlvdXMubW9kdWxlTmFtZSA9PT0gc2xvdC5tb2R1bGVOYW1lICYmIGlzRXF1YWwocHJldmlvdXMuY2FuZGlkYXRlRXh0ZW5zaW9ucywgY2FuZGlkYXRlRXh0ZW5zaW9ucykpIHtcbiAgICAgICAgICAgIHNsb3RzW3Nsb3ROYW1lXSA9IHByZXZpb3VzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2xvdHNbc2xvdE5hbWVdID0ge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IHNsb3QubW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVFeHRlbnNpb25zXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNoYW5nZWQgfHwgT2JqZWN0LmtleXMocHJldmlvdXNTbG90cykubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhzbG90cykubGVuZ3RoKSB7XG4gICAgICAgIGV4dGVuc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNsb3RzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuICogUmV0dXJucyB0aGUga2V5cyB3aG9zZSB2YWx1ZXMgZGlmZmVyIGJldHdlZW4gdHdvIHJlY29yZHMsIGluY2x1ZGluZyBrZXlzIHByZXNlbnQgaW4gb25seSBvbmUuXG4gKi8gZnVuY3Rpb24gY2hhbmdlZEtleXMobmV4dCwgcHJldmlvdXMpIHtcbiAgICBjb25zdCBjaGFuZ2VkID0gbmV3IFNldCgpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG5leHQpKXtcbiAgICAgICAgaWYgKG5leHRba2V5XSAhPT0gcHJldmlvdXNba2V5XSkge1xuICAgICAgICAgICAgY2hhbmdlZC5hZGQoa2V5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhwcmV2aW91cykpe1xuICAgICAgICBpZiAoIShrZXkgaW4gbmV4dCkpIHtcbiAgICAgICAgICAgIGNoYW5nZWQuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNoYW5nZWQ7XG59XG5leHRlbnNpb25JbnRlcm5hbFN0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgLy8gQSBuZXcgb3IgY2hhbmdlZCByZWdpc3RyYXRpb24gY2FuIGFmZmVjdCBhbnkgc2xvdCB0aGUgZXh0ZW5zaW9uIG1pZ2h0IGJlIGFzc2lnbmVkIHRvLiBFdmVyeVxuICAgIC8vIG90aGVyIGtpbmQgb2YgY2hhbmdlIGhlcmUg4oCUIGF0dGFjaGluZywgcmVnaXN0ZXJpbmcgYSBzbG90IOKAlCBpcyBzY29wZWQgdG8gdGhlIHNsb3RzIHdob3NlXG4gICAgLy8gZW50cmllcyBhY3R1YWxseSBjaGFuZ2VkLlxuICAgIG1hcmtTbG90c0RpcnR5KHN0YXRlLmV4dGVuc2lvbnMgIT09IHByZXZpb3VzU3RhdGUuZXh0ZW5zaW9ucyA/IG51bGwgOiBjaGFuZ2VkS2V5cyhzdGF0ZS5zbG90cywgcHJldmlvdXNTdGF0ZS5zbG90cykpO1xufSk7XG4vLyBTbG90IGNvbmZpZ3MgYXJlIHBlci1zbG90LCBzbyBhIGNvbmZpZyBjaGFuZ2UgaW52YWxpZGF0ZXMgb25seSB0aGUgc2xvdHMgaXQgbmFtZXMuXG5zbG90c0NvbmZpZ1N0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgbWFya1Nsb3RzRGlydHkoY2hhbmdlZEtleXMoc3RhdGUuc2xvdHMsIHByZXZpb3VzU3RhdGUuc2xvdHMpKTtcbn0pO1xuLy8gRXh0ZW5zaW9uIGNvbmZpZ3MgYXJlIGtleWVkIGJ5IHNsb3QgdG9vLCBhbmQgdGhlIGNvbmZpZyBzeXN0ZW0gaGFuZHMgYmFjayB0aGUgc2FtZSBwZXItc2xvdFxuLy8gb2JqZWN0IHdoZW4gbm90aGluZyB1bmRlciBpdCBjaGFuZ2VkLCBzbyBvbmx5IHRoZSBzbG90cyB3aG9zZSBjb25maWdzIGFjdHVhbGx5IG1vdmVkIGFyZSBkaXJ0aWVkLlxuZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgbWFya1Nsb3RzRGlydHkoY2hhbmdlZEtleXMoc3RhdGUuY29uZmlncywgcHJldmlvdXNTdGF0ZS5jb25maWdzKSk7XG59KTtcbmZlYXR1cmVGbGFnc1N0b3JlLnN1YnNjcmliZSgoKT0+bWFya1Nsb3RzRGlydHkobnVsbCkpO1xuc2Vzc2lvblN0b3JlLnN1YnNjcmliZSgoKT0+bWFya1Nsb3RzRGlydHkobnVsbCkpO1xuZnVuY3Rpb24gdXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQoKSB7XG4gICAgbWFya1Nsb3RzRGlydHkobnVsbCk7XG59XG51cGRhdGVPdXRwdXRTdG9yZVRvQ3VycmVudCgpO1xuZnVuY3Rpb24gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2R1bGVOYW1lLFxuICAgICAgICBuYW1lOiBzbG90TmFtZSxcbiAgICAgICAgYXR0YWNoZWRJZHM6IFtdXG4gICAgfTtcbn1cbi8qKlxuICogR2l2ZW4gYW4gZXh0ZW5zaW9uIElELCB3aGljaCBpcyBhIHN0cmluZyB1bmlxdWVseSBpZGVudGlmeWluZ1xuICogYW4gaW5zdGFuY2Ugb2YgYW4gZXh0ZW5zaW9uIHdpdGhpbiBhbiBleHRlbnNpb24gc2xvdCwgdGhpc1xuICogcmV0dXJucyB0aGUgZXh0ZW5zaW9uIG5hbWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKFwiZm9vI2JhclwiKVxuICogIC0tPiBcImZvb1wiXG4gKiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKFwiYmF6XCIpXG4gKiAgLS0+IFwiYmF6XCJcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3QgW2V4dGVuc2lvbk5hbWVdID0gZXh0ZW5zaW9uSWQuc3BsaXQoJyMnKTtcbiAgICByZXR1cm4gZXh0ZW5zaW9uTmFtZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25SZWdpc3RyYXRpb25Gcm9tKHN0YXRlLCBleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IG5hbWUgPSBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKTtcbiAgICByZXR1cm4gc3RhdGUuZXh0ZW5zaW9uc1tuYW1lXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25SZWdpc3RyYXRpb24oZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICByZXR1cm4gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbShzdGF0ZSwgZXh0ZW5zaW9uSWQpO1xufVxuLyoqXG4gKiBFeHRlbnNpb25zIG11c3QgYmUgcmVnaXN0ZXJlZCBpbiBvcmRlciB0byBiZSByZW5kZXJlZC5cbiAqIFRoaXMgaXMgaGFuZGxlZCBieSB0aGUgYXBwIHNoZWxsLCB3aGVuIGV4dGVuc2lvbnMgYXJlIHByb3ZpZGVkXG4gKiB2aWEgdGhlIGByb3V0ZXMuanNvbmAgZmlsZSBhbmQgcmVnaXN0ZXJlZCB0aHJvdWdoIGByZWdpc3RlckFwcCgpYC5cbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBjb25zdCByZWdpc3RlckV4dGVuc2lvbiA9IChleHRlbnNpb25SZWdpc3RyYXRpb24pPT51cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZS5leHRlbnNpb25zLFxuICAgICAgICAgICAgICAgIFtleHRlbnNpb25SZWdpc3RyYXRpb24ubmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uZXh0ZW5zaW9uUmVnaXN0cmF0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4vKipcbiAqIEF0dGFjaCBhbiBleHRlbnNpb24gdG8gYW4gZXh0ZW5zaW9uIHNsb3QuXG4gKlxuICogVGhpcyB3aWxsIGNhdXNlIHRoZSBleHRlbnNpb24gdG8gYmUgcmVuZGVyZWQgaW50byB0aGUgc3BlY2lmaWVkXG4gKiBleHRlbnNpb24gc2xvdCwgdW5sZXNzIGl0IGlzIHJlbW92ZWQgYnkgY29uZmlndXJhdGlvbi4gVXNpbmdcbiAqIGBhdHRhY2hgIGlzIGFuIGFsdGVybmF0aXZlIHRvIHNwZWNpZnlpbmcgdGhlIGBzbG90YCBvciBgc2xvdHNgXG4gKiBpbiB0aGUgZXh0ZW5zaW9uIGRlY2xhcmF0aW9uLlxuICpcbiAqIEl0IGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiBjcmVhdGluZyBhIHNsb3QgaW50byB3aGljaFxuICogeW91IHdhbnQgdG8gcmVuZGVyIGFuIGV4aXN0aW5nIGV4dGVuc2lvbi4gVGhpcyBlbmFibGVzIHlvdVxuICogdG8gZG8gc28gd2l0aG91dCBtb2RpZnlpbmcgdGhlIGV4dGVuc2lvbidzIGRlY2xhcmF0aW9uLCB3aGljaFxuICogbWF5IGJlIGltcHJhY3RpY2FsIG9yIGluYXBwcm9wcmlhdGUsIGZvciBleGFtcGxlIGlmIHlvdSBhcmVcbiAqIHdyaXRpbmcgYSBtb2R1bGUgZm9yIGEgc3BlY2lmaWMgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHBhcmFtIHNsb3ROYW1lIGEgbmFtZSB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgc2xvdFxuICogQHBhcmFtIGV4dGVuc2lvbklkIGFuIGV4dGVuc2lvbiBuYW1lLCB3aXRoIGFuIG9wdGlvbmFsICMtc3VmZml4XG4gKiAgICB0byBkaXN0aW5ndWlzaCBpdCBmcm9tIG90aGVyIGluc3RhbmNlcyBvZiB0aGUgc2FtZSBleHRlbnNpb25cbiAqICAgIGF0dGFjaGVkIHRvIHRoZSBzYW1lIHNsb3QuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaChzbG90TmFtZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbc2xvdE5hbWVdO1xuICAgICAgICBpZiAoIWV4aXN0aW5nU2xvdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25JZFxuICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtzbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbklkXG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIERldGFjaGVzIGFuIGV4dGVuc2lvbiBmcm9tIGFuIGV4dGVuc2lvbiBzbG90LlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25TbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3QgdG8gZGV0YWNoIGZyb20uXG4gKiBAcGFyYW0gZXh0ZW5zaW9uSWQgVGhlIElEIG9mIHRoZSBleHRlbnNpb24gdG8gZGV0YWNoLlxuICpcbiAqIEBkZXByZWNhdGVkIEF2b2lkIHVzaW5nIHRoaXMuIEV4dGVuc2lvbiBhdHRhY2htZW50cyBzaG91bGQgYmUgY29uc2lkZXJlZCBkZWNsYXJhdGl2ZS5cbiAqLyBleHBvcnQgZnVuY3Rpb24gZGV0YWNoKGV4dGVuc2lvblNsb3ROYW1lLCBleHRlbnNpb25JZCkge1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKHN0YXRlKT0+e1xuICAgICAgICBjb25zdCBleGlzdGluZ1Nsb3QgPSBzdGF0ZS5zbG90c1tleHRlbnNpb25TbG90TmFtZV07XG4gICAgICAgIGlmIChleGlzdGluZ1Nsb3QgJiYgZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLmluY2x1ZGVzKGV4dGVuc2lvbklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW2V4dGVuc2lvblNsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IGV4aXN0aW5nU2xvdC5hdHRhY2hlZElkcy5maWx0ZXIoKGlkKT0+aWQgIT09IGV4dGVuc2lvbklkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBEZXRhY2hlcyBhbGwgZXh0ZW5zaW9ucyBmcm9tIGFuIGV4dGVuc2lvbiBzbG90LlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25TbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3QgdG8gY2xlYXIuXG4gKlxuICogQGRlcHJlY2F0ZWQgQXZvaWQgdXNpbmcgdGhpcy4gRXh0ZW5zaW9uIGF0dGFjaG1lbnRzIHNob3VsZCBiZSBjb25zaWRlcmVkIGRlY2xhcmF0aXZlLlxuICovIGV4cG9ydCBmdW5jdGlvbiBkZXRhY2hBbGwoZXh0ZW5zaW9uU2xvdE5hbWUpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbZXh0ZW5zaW9uU2xvdE5hbWVdO1xuICAgICAgICBpZiAoZXhpc3RpbmdTbG90KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbZXh0ZW5zaW9uU2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5leGlzdGluZ1Nsb3QsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2hlZElkczogW11cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogR2V0IGFuIG9yZGVyIGluZGV4IGZvciB0aGUgZXh0ZW5zaW9uLiBUaGlzIHdpbGxcbiAqIGNvbWUgZnJvbSBlaXRoZXIgaXRzIGNvbmZpZ3VyZWQgb3JkZXIsIGl0cyByZWdpc3RlcmVkIG9yZGVyXG4gKiBwYXJhbWV0ZXIsIG9yIHRoZSBvcmRlciBpbiB3aGljaCBpdCBoYXBwZW5lZCB0byBiZSBhdHRhY2hlZC5cbiAqXG4gKiBUaGUgZm91ciBiYW5kcyBiZWxvdyBrZWVwIHRoZSBjb21wYXJpc29uIGEgdG90YWwgb3JkZXI6IGV2ZXJ5IGV4dGVuc2lvbiBsYW5kcyBpbiBleGFjdGx5IG9uZSwgYW5kXG4gKiB0aG9zZSB3aXRoIG5vIG9yZGVyaW5nIGluZm9ybWF0aW9uIHNoYXJlIHRoZSBsYXN0IGJhbmQgcmF0aGVyIHRoYW4gdGFraW5nIGEgc2VudGluZWwgdGhhdCBjYW4ndCBiZVxuICogY29tcGFyZWQgYWdhaW5zdCBpdHNlbGYuXG4gKi8gZnVuY3Rpb24gZ2V0T3JkZXIoZXh0ZW5zaW9uSWQsIGNvbmZpZ3VyZWRPcmRlciwgcmVnaXN0ZXJlZE9yZGVySW5kZXgsIGF0dGFjaGVkT3JkZXIpIHtcbiAgICBjb25zdCBjb25maWd1cmVkSW5kZXggPSBjb25maWd1cmVkT3JkZXIuaW5kZXhPZihleHRlbnNpb25JZCk7XG4gICAgaWYgKGNvbmZpZ3VyZWRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgcmV0dXJuIGNvbmZpZ3VyZWRJbmRleDtcbiAgICB9IGVsc2UgaWYgKHJlZ2lzdGVyZWRPcmRlckluZGV4ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gZXh0ZW5zaW9ucyB0aGF0IGRvbid0IGhhdmUgYSBjb25maWd1cmVkIG9yZGVyIHNob3VsZCBhcHBlYXIgYWZ0ZXIgdGhvc2UgdGhhdCBkb1xuICAgICAgICByZXR1cm4gMTAwMCArIHJlZ2lzdGVyZWRPcmRlckluZGV4O1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGFzc2lnbmVkSW5kZXggPSBhdHRhY2hlZE9yZGVyLmluZGV4T2YoZXh0ZW5zaW9uSWQpO1xuICAgICAgICBpZiAoYXNzaWduZWRJbmRleCAhPT0gLTEpIHtcbiAgICAgICAgICAgIC8vIGV4dGVuc2lvbnMgdGhhdCBoYXZlIG5laXRoZXIgYSBjb25maWd1cmVkIG5vciByZWdpc3RlcmVkIG9yZGVyIHNob3VsZCBhcHBlYXJcbiAgICAgICAgICAgIC8vIGFmdGVyIGFsbCBvdGhlcnNcbiAgICAgICAgICAgIHJldHVybiAyMDAwICsgYXNzaWduZWRJbmRleDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEFkZGVkIGJ5IGNvbmZpZ3VyYXRpb24gd2l0aCBubyBvcmRlciBvZiBhbnkga2luZCDigJQgYWZ0ZXIgZXZlcnl0aGluZyBlbHNlLCBhbmQgYW1vbmdcbiAgICAgICAgICAgIC8vIHRoZW1zZWx2ZXMgaW4gdGhlIG9yZGVyIHRoZSBjb25maWd1cmF0aW9uIGxpc3RzIHRoZW0uXG4gICAgICAgICAgICByZXR1cm4gMzAwMDtcbiAgICAgICAgfVxuICAgIH1cbn1cbmZ1bmN0aW9uIGdldEFzc2lnbmVkRXh0ZW5zaW9uc0Zyb21TbG90RGF0YShzbG90TmFtZSwgaW50ZXJuYWxTdGF0ZSwgY29uZmlnLCBleHRlbnNpb25Db25maWdTdG9yZVN0YXRlLCBlbmFibGVkRmVhdHVyZUZsYWdzLCBzZXNzaW9uKSB7XG4gICAgY29uc3QgYXR0YWNoZWRJZHMgPSBpbnRlcm5hbFN0YXRlLnNsb3RzW3Nsb3ROYW1lXS5hdHRhY2hlZElkcztcbiAgICBjb25zdCBhc3NpZ25lZElkcyA9IGNhbGN1bGF0ZUFzc2lnbmVkSWRzKGNvbmZpZywgYXR0YWNoZWRJZHMpO1xuICAgIGNvbnN0IGV4dGVuc2lvbnMgPSBbXTtcbiAgICBmb3IgKGxldCBpZCBvZiBhc3NpZ25lZElkcyl7XG4gICAgICAgIGNvbnN0IHsgY29uZmlnOiByYXdFeHRlbnNpb25Db25maWcgfSA9IGdldEV4dGVuc2lvbkNvbmZpZ0Zyb21TdG9yZShleHRlbnNpb25Db25maWdTdG9yZVN0YXRlLCBzbG90TmFtZSwgaWQpO1xuICAgICAgICBjb25zdCByYXdFeHRlbnNpb25TbG90RXh0ZW5zaW9uQ29uZmlnID0gZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZShjb25maWcsIHNsb3ROYW1lLCBpZCk7XG4gICAgICAgIC8vIGBtZXJnZWAgbXV0YXRlcyBpdHMgZmlyc3QgYXJndW1lbnQsIGFuZCBgcmF3RXh0ZW5zaW9uQ29uZmlnYCBiZWxvbmdzIHRvIHRoZSBjb25maWcgc3RvcmUsXG4gICAgICAgIC8vIHNvIG5ldmVyIG1lcmdlIGludG8gaXQuXG4gICAgICAgIGNvbnN0IGV4dGVuc2lvbkNvbmZpZyA9IHJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWcgPyBtZXJnZSh7fSwgcmF3RXh0ZW5zaW9uQ29uZmlnLCByYXdFeHRlbnNpb25TbG90RXh0ZW5zaW9uQ29uZmlnKSA6IHJhd0V4dGVuc2lvbkNvbmZpZztcbiAgICAgICAgY29uc3QgbmFtZSA9IGdldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWQpO1xuICAgICAgICBjb25zdCBleHRlbnNpb24gPSBpbnRlcm5hbFN0YXRlLmV4dGVuc2lvbnNbbmFtZV07XG4gICAgICAgIC8vIGlmIHRoZSBleHRlbnNpb24gaGFzIG5vdCBiZWVuIHJlZ2lzdGVyZWQgeWV0LCBkbyBub3QgaW5jbHVkZSBpdFxuICAgICAgICBpZiAoZXh0ZW5zaW9uKSB7XG4gICAgICAgICAgICBjb25zdCByZXF1aXJlZFByaXZpbGVnZXMgPSBleHRlbnNpb25Db25maWc/LlsnRGlzcGxheSBjb25kaXRpb25zJ10/LnByaXZpbGVnZXMgPz8gZXh0ZW5zaW9uLnByaXZpbGVnZXMgPz8gW107XG4gICAgICAgICAgICBpZiAocmVxdWlyZWRQcml2aWxlZ2VzICYmICh0eXBlb2YgcmVxdWlyZWRQcml2aWxlZ2VzID09PSAnc3RyaW5nJyB8fCBBcnJheS5pc0FycmF5KHJlcXVpcmVkUHJpdmlsZWdlcykgJiYgcmVxdWlyZWRQcml2aWxlZ2VzLmxlbmd0aCA+IDApKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFzZXNzaW9uPy51c2VyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXVzZXJIYXNBY2Nlc3MocmVxdWlyZWRQcml2aWxlZ2VzLCBzZXNzaW9uLnVzZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChleHRlbnNpb24uZmVhdHVyZUZsYWcgJiYgIWVuYWJsZWRGZWF0dXJlRmxhZ3MuaW5jbHVkZXMoZXh0ZW5zaW9uLmZlYXR1cmVGbGFnKSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXh0ZW5zaW9ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZCxcbiAgICAgICAgICAgICAgICBuYW1lLFxuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IGV4dGVuc2lvbi5tb2R1bGVOYW1lLFxuICAgICAgICAgICAgICAgIGNvbmZpZzogZXh0ZW5zaW9uQ29uZmlnLFxuICAgICAgICAgICAgICAgIGZlYXR1cmVGbGFnOiBleHRlbnNpb24uZmVhdHVyZUZsYWcsXG4gICAgICAgICAgICAgICAgbWV0YTogZXh0ZW5zaW9uLm1ldGEsXG4gICAgICAgICAgICAgICAgZGlzcGxheUNvbmRpdGlvbkV4cHJlc3Npb246IGV4dGVuc2lvbkNvbmZpZz8uWydEaXNwbGF5IGNvbmRpdGlvbnMnXT8uZXhwcmVzc2lvbiB8fCBleHRlbnNpb24uZGlzcGxheUV4cHJlc3Npb25cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBleHRlbnNpb25zO1xufVxuLyoqXG4gKiBOYXJyb3dzIGBleHRlbnNpb25zYCB0byB0aG9zZSB3aG9zZSBkaXNwbGF5IGNvbmRpdGlvbiBob2xkcyBmb3Igb25lIHBhcnRpY3VsYXIgcmVuZGVyaW5nIG9mIGFcbiAqIHNsb3QsIGV2YWx1YXRpbmcgZWFjaCBjb25kaXRpb24gYWdhaW5zdCBgc3RhdGVgLlxuICpcbiAqIEFuIGV4dGVuc2lvbiB3aG9zZSBkaXNwbGF5IGNvbmRpdGlvbiB0aHJvd3MgaXMgbGVmdCBvdXQsIG9uIHRoZSBncm91bmRzIHRoYXQgYSBjb25kaXRpb24gdGhhdCBjYW5ub3QgYmVcbiAqIGV2YWx1YXRlZCBoYXMgbm90IGJlZW4gbWV0LlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25zIFRoZSBleHRlbnNpb25zIGFzc2lnbmVkIHRvIHRoZSBzbG90LCBhcyB0aGUgZXh0ZW5zaW9uIHN0b3JlIGhvbGRzIHRoZW1cbiAqIEBwYXJhbSBzdGF0ZSBUaGUgc3RhdGUgb2YgdGhpcyByZW5kZXJpbmcgb2YgdGhlIHNsb3RcbiAqIEBwYXJhbSBzZXNzaW9uIFRoZSBjdXJyZW50IHNlc3Npb24sIHdoaWNoIGNvbmRpdGlvbnMgbWF5IHJlZmVyIHRvIGFzIGBzZXNzaW9uYFxuICogQHBhcmFtIHNsb3ROYW1lIFRoZSBzbG90IHRoZXNlIHdlcmUgYXNzaWduZWQgdG8sIHVzZWQgb25seSB0byBpZGVudGlmeSB0aGVtIGlmIGEgY29uZGl0aW9uIHRocm93c1xuICogQHJldHVybnMgVGhvc2Ugb2YgYGV4dGVuc2lvbnNgIHRoYXQgc2hvdWxkIGJlIGRpc3BsYXllZCwgaW4gdGhlIHNhbWUgb3JkZXIuIEFsd2F5cyBhIG5ldyBhcnJheS5cbiAqLyBmdW5jdGlvbiBmaWx0ZXJFeHRlbnNpb25zQnlEaXNwbGF5Q29uZGl0aW9ucyhleHRlbnNpb25zLCBzdGF0ZSwgc2Vzc2lvbiA9IG51bGwsIHNsb3ROYW1lKSB7XG4gICAgLy8gQnVpbHQgb25jZSBmb3IgdGhlIHdob2xlIHNsb3QgcmF0aGVyIHRoYW4gcGVyIGV4dGVuc2lvbjogdGhlIGNvbnRleHQgaXMgdGhlIHNhbWUgZm9yIGFsbCBvZlxuICAgIC8vIHRoZW0sIGFuZCBtb3N0IHNsb3RzIGhhdmUgbm8gY29uZGl0aW9ucyBhdCBhbGwuXG4gICAgbGV0IGV4cHJlc3Npb25Db250ZXh0O1xuICAgIHJldHVybiBleHRlbnNpb25zLmZpbHRlcigoZXh0ZW5zaW9uKT0+e1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gZXh0ZW5zaW9uLmRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uO1xuICAgICAgICBpZiAodHlwZW9mIGV4cHJlc3Npb24gIT09ICdzdHJpbmcnIHx8IGV4cHJlc3Npb24udHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZXhwcmVzc2lvbkNvbnRleHQgPz8gKGV4cHJlc3Npb25Db250ZXh0ID0gc3RhdGUgJiYgdHlwZW9mIHN0YXRlID09PSAnb2JqZWN0JyA/IHtcbiAgICAgICAgICAgIHNlc3Npb24sXG4gICAgICAgICAgICAuLi5zdGF0ZVxuICAgICAgICB9IDoge1xuICAgICAgICAgICAgc2Vzc2lvblxuICAgICAgICB9KTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiBCb29sZWFuKGV2YWx1YXRlQXNCb29sZWFuKGV4cHJlc3Npb24sIGV4cHJlc3Npb25Db250ZXh0KSk7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYEVycm9yIHdoaWxlIGV2YWx1YXRpbmcgZXhwcmVzc2lvbiAnJHtleHByZXNzaW9ufScgZm9yICR7ZXh0ZW5zaW9uLmlkfWAgKyAoc2xvdE5hbWUgPyBgIGluICR7c2xvdE5hbWV9YCA6ICcnKSwgZSk7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKlxuICogR2V0cyB0aGUgZXh0ZW5zaW9ucyBhIGdpdmVuIHJlbmRlcmluZyBvZiBhIHNsb3Qgc2hvdWxkIGRpc3BsYXksIGluIG9yZGVyLiBUaGlzIGlzIHRoZSBzdXBwb3J0ZWRcbiAqIHdheSB0byBhc2sgd2hhdCBiZWxvbmdzIGluIGEgc2xvdDsgcmVhZGluZyB0aGUgZXh0ZW5zaW9uIHN0b3JlIGRpcmVjdGx5IHNraXBzIGRpc3BsYXkgY29uZGl0aW9ucy5cbiAqXG4gKiBEaXNwbGF5IGNvbmRpdGlvbnMgYXJlIGV2YWx1YXRlZCBhZ2FpbnN0IGBzdGF0ZWAsIHNvIHBhc3Mgd2hhdGV2ZXIgdGhlIHNsb3QgaXMgYmVpbmcgcmVuZGVyZWRcbiAqIGZvci4gVGhlIHNhbWUgc2xvdCBjYW4gYmUgcmVuZGVyZWQgbWFueSB0aW1lcyB3aXRoIGRpZmZlcmVudCBzdGF0ZSDigJQgb25jZSBwZXIgcm93IG9mIGEgdGFibGUsXG4gKiBzYXkg4oCUIGFuZCBlYWNoIHJlbmRlcmluZyBjYW4gcmVzb2x2ZSB0byBhIGRpZmZlcmVudCBzZXQgb2YgZXh0ZW5zaW9ucy4gT21pdHRpbmcgYHN0YXRlYCBoaWRlc1xuICogZXZlcnkgZXh0ZW5zaW9uIHdob3NlIGNvbmRpdGlvbiByZWZlcnMgdG8gaXQsIHNpbmNlIHRoZSBjb25kaXRpb24gY2Fubm90IGJlIGV2YWx1YXRlZC5cbiAqXG4gKiBAcGFyYW0gc2xvdE5hbWUgVGhlIHNsb3QgdG8gbG9hZCB0aGUgZXh0ZW5zaW9ucyBmb3JcbiAqIEBwYXJhbSBzdGF0ZSBUaGUgc3RhdGUgb2YgdGhlIHJlbmRlcmluZyBvZiB0aGUgc2xvdCB0aGUgZXh0ZW5zaW9ucyB3aWxsIGJlIGRpc3BsYXllZCBpblxuICogQHJldHVybnMgVGhvc2UgZXh0ZW5zaW9ucyBhc3NpZ25lZCB0byB0aGUgc2xvdCB3aG9zZSBkaXNwbGF5IGNvbmRpdGlvbnMgaG9sZFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRBc3NpZ25lZEV4dGVuc2lvbnMoc2xvdE5hbWUsIHN0YXRlKSB7XG4gICAgcmV0dXJuIGZpbHRlckV4dGVuc2lvbnNCeURpc3BsYXlDb25kaXRpb25zKGdldENhbmRpZGF0ZUV4dGVuc2lvbnMoc2xvdE5hbWUpLCBzdGF0ZSwgc2Vzc2lvblN0b3JlLmdldFN0YXRlKCkuc2Vzc2lvbiwgc2xvdE5hbWUpO1xufVxuLyoqXG4gKiBHZXRzIGV2ZXJ5dGhpbmcgYXNzaWduZWQgdG8gYSBzbG90IHdpdGhvdXQgZXZhbHVhdGluZyBhbnkgZGlzcGxheSBjb25kaXRpb24sIHdoaWNoXG4gKiB7QGxpbmsgZ2V0QXNzaWduZWRFeHRlbnNpb25zfSBjYW5ub3QgZG8gd2l0aG91dCBrbm93aW5nIHRoZSBzdGF0ZSBvZiBhIHBhcnRpY3VsYXIgcmVuZGVyaW5nLlxuICpcbiAqIFRoaXMgZXhpc3RzIGZvciB0b29scyB0aGF0IHByZXNlbnQgYSBzbG90J3MgY29uZmlndXJhdGlvbiByYXRoZXIgdGhhbiByZW5kZXIgaXQg4oCUIHRoZSBVSSBlZGl0b3JcbiAqIGhhcyB0byBsaXN0IGFuIGV4dGVuc2lvbiBpbiBvcmRlciB0byBsZXQgYW4gaW1wbGVtZW50ZXIgcmVvcmRlciBvciByZW1vdmUgaXQsIGV2ZW4gd2hlcmUgbm9cbiAqIHJlbmRlcmluZyB3b3VsZCBkaXNwbGF5IGl0LiBBbnl0aGluZyBkZWNpZGluZyB3aGF0IHRvIHJlbmRlciB3YW50cyBgZ2V0QXNzaWduZWRFeHRlbnNpb25zKClgLlxuICpcbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRDYW5kaWRhdGVFeHRlbnNpb25zKHNsb3ROYW1lKSB7XG4gICAgcmV0dXJuIGV4dGVuc2lvblN0b3JlLmdldFN0YXRlKCkuc2xvdHNbc2xvdE5hbWVdPy5jYW5kaWRhdGVFeHRlbnNpb25zID8/IFtdO1xufVxuZnVuY3Rpb24gY2FsY3VsYXRlQXNzaWduZWRJZHMoY29uZmlnLCBhdHRhY2hlZElkcykge1xuICAgIGNvbnN0IGFkZGVkSWRzID0gY29uZmlnLmFkZCB8fCBbXTtcbiAgICBjb25zdCByZW1vdmVkSWRzID0gY29uZmlnLnJlbW92ZSB8fCBbXTtcbiAgICBjb25zdCBpZE9yZGVyID0gY29uZmlnLm9yZGVyIHx8IFtdO1xuICAgIGNvbnN0IHsgZXh0ZW5zaW9ucyB9ID0gZXh0ZW5zaW9uSW50ZXJuYWxTdG9yZS5nZXRTdGF0ZSgpO1xuICAgIHJldHVybiBbXG4gICAgICAgIC4uLmF0dGFjaGVkSWRzLFxuICAgICAgICAuLi5hZGRlZElkc1xuICAgIF0uZmlsdGVyKChpZCk9PiFyZW1vdmVkSWRzLmluY2x1ZGVzKGlkKSkuc29ydCgoaWRBLCBpZEIpPT57XG4gICAgICAgIGNvbnN0IGFpID0gZ2V0T3JkZXIoaWRBLCBpZE9yZGVyLCBleHRlbnNpb25zW2dldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWRBKV0/Lm9yZGVyLCBhdHRhY2hlZElkcyk7XG4gICAgICAgIGNvbnN0IGJpID0gZ2V0T3JkZXIoaWRCLCBpZE9yZGVyLCBleHRlbnNpb25zW2dldEV4dGVuc2lvbk5hbWVGcm9tSWQoaWRCKV0/Lm9yZGVyLCBhdHRhY2hlZElkcyk7XG4gICAgICAgIC8vIFRpZXMga2VlcCB0aGVpciBpbnB1dCBvcmRlciDigJQgYEFycmF5LnByb3RvdHlwZS5zb3J0YCBpcyBzdGFibGUsIGFuZCB0aGUgaW5wdXQgaXNcbiAgICAgICAgLy8gYFsuLi5hdHRhY2hlZElkcywgLi4uYWRkZWRJZHNdYCwgc28gdHdvIGV4dGVuc2lvbnMgdGhlIG9yZGVyaW5nIHJ1bGVzIGNhbid0IHNlcGFyYXRlXG4gICAgICAgIC8vIGNvbWUgb3V0IGluIHRoZSBvcmRlciB0aGUgY29kZSBhbmQgdGhlIGNvbmZpZ3VyYXRpb24gZGVjbGFyZWQgdGhlbS5cbiAgICAgICAgcmV0dXJuIGFpIC0gYmk7XG4gICAgfSk7XG59XG4vKipcbiAqIFVzZWQgYnkgYnkgZXh0ZW5zaW9uIHNsb3RzIGF0IG1vdW50IHRpbWUuXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0aGF0IGNvbnRhaW5zIHRoZSBleHRlbnNpb24gc2xvdFxuICogQHBhcmFtIHNsb3ROYW1lIFRoZSBleHRlbnNpb24gc2xvdCBuYW1lIHRoYXQgaXMgYWN0dWFsbHkgdXNlZFxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGNvbnN0IHJlZ2lzdGVyRXh0ZW5zaW9uU2xvdCA9IChtb2R1bGVOYW1lLCBzbG90TmFtZSk9PmV4dGVuc2lvbkludGVybmFsU3RvcmUuc2V0U3RhdGUoKGN1cnJlbnRTdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdNb2R1bGVOYW1lID0gY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXT8ubW9kdWxlTmFtZTtcbiAgICAgICAgaWYgKGV4aXN0aW5nTW9kdWxlTmFtZSAmJiBleGlzdGluZ01vZHVsZU5hbWUgIT0gbW9kdWxlTmFtZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBBbiBleHRlbnNpb24gc2xvdCB3aXRoIHRoZSBuYW1lICcke3Nsb3ROYW1lfScgYWxyZWFkeSBleGlzdHMuIFJlZnVzaW5nIHRvIHJlZ2lzdGVyIHRoZSBzYW1lIHNsb3QgbmFtZSB0d2ljZSAoaW4gXCJyZWdpc3RlckV4dGVuc2lvblNsb3RcIikuIFRoZSBleGlzdGluZyBvbmUgaXMgZnJvbSBtb2R1bGUgJHtleGlzdGluZ01vZHVsZU5hbWV9LmApO1xuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhpc3RpbmdNb2R1bGVOYW1lICYmIGV4aXN0aW5nTW9kdWxlTmFtZSA9PSBtb2R1bGVOYW1lKSB7XG4gICAgICAgICAgICAvLyBSZS1yZW5kZXJpbmcgYW4gZXhpc3Rpbmcgc2xvdFxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzbG90ID0gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLFxuICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAuLi5zbG90XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIEp1c3QgZm9yIHRlc3RpbmcuXG4gKi8gZXhwb3J0IGNvbnN0IHJlc2V0ID0gKCk9PntcbiAgICAvLyBJbnZhbGlkYXRpb24gaXMgY2FycmllZCBpbiBtb2R1bGUgc3RhdGUsIHNvIGl0IGhhcyB0byBiZSByZXNldCB0b28gb3IgaXQgYmxlZWRzIGludG8gdGhlXG4gICAgLy8gbmV4dCB0ZXN0IGFzIGVpdGhlciBhIHN0YWxlIGRpcnR5IHNldCBvciBhIG1pc3Npbmcgb25lLlxuICAgIGRpcnR5U2xvdHMgPSBudWxsO1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKCk9Pih7XG4gICAgICAgICAgICBzbG90czoge30sXG4gICAgICAgICAgICBleHRlbnNpb25zOiB7fVxuICAgICAgICB9KSk7XG4gICAgZ2V0RXh0ZW5zaW9uUmVuZGVyaW5nc1N0b3JlKCkuc2V0U3RhdGUoe1xuICAgICAgICByZW5kZXJpbmdzOiBuZXcgTWFwKClcbiAgICB9KTtcbiAgICBleHRlbnNpb25TdG9yZS5zZXRTdGF0ZSh7XG4gICAgICAgIHNsb3RzOiB7fVxuICAgIH0pO1xufTtcbiJdLCJuYW1lcyI6WyJzZXNzaW9uU3RvcmUiLCJ1c2VySGFzQWNjZXNzIiwiZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZSIsImdldEV4dGVuc2lvbkNvbmZpZ0Zyb21TdG9yZSIsImdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUiLCJnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlIiwiZ2V0RXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiZXZhbHVhdGVBc0Jvb2xlYW4iLCJmZWF0dXJlRmxhZ3NTdG9yZSIsImlzRXF1YWwiLCJtZXJnZSIsImdldEV4dGVuc2lvblJlbmRlcmluZ3NTdG9yZSIsImdldEV4dGVuc2lvbkludGVybmFsU3RvcmUiLCJnZXRFeHRlbnNpb25TdG9yZSIsInNjaGVkdWxlUmVjb21wdXRhdGlvbiIsInVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUiLCJleHRlbnNpb25JbnRlcm5hbFN0b3JlIiwiZXh0ZW5zaW9uU3RvcmUiLCJzbG90c0NvbmZpZ1N0b3JlIiwiZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiZGlydHlTbG90cyIsIlNldCIsImlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSIsIm1hcmtTbG90c0RpcnR5Iiwic2xvdHMiLCJzbG90TmFtZSIsInJlY29tcHV0ZUV4dGVuc2lvbk91dHB1dFN0b3JlIiwibWF4UmVjb21wdXRhdGlvblBhc3NlcyIsInBhc3MiLCJ1cGRhdGVFeHRlbnNpb25PdXRwdXRTdG9yZSIsImUiLCJjb25zb2xlIiwiaW50ZXJuYWxTdGF0ZSIsImV4dGVuc2lvblNsb3RDb25maWdzIiwiZXh0ZW5zaW9uc0NvbmZpZ1N0YXRlIiwiZmVhdHVyZUZsYWdTdGF0ZSIsInNlc3Npb25TdGF0ZSIsImRpcnR5U2xvdE5hbWVzIiwicHJldmlvdXNTbG90cyIsImNoYW5nZWQiLCJlbmFibGVkRmVhdHVyZUZsYWdzIiwiT2JqZWN0IiwiZW5hYmxlZCIsIm5hbWUiLCJzbG90IiwicHJldmlvdXMiLCJjb25maWciLCJjYW5kaWRhdGVFeHRlbnNpb25zIiwiZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhIiwiY2hhbmdlZEtleXMiLCJuZXh0Iiwia2V5Iiwic3RhdGUiLCJwcmV2aW91c1N0YXRlIiwidXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQiLCJjcmVhdGVOZXdFeHRlbnNpb25TbG90SW5mbyIsIm1vZHVsZU5hbWUiLCJnZXRFeHRlbnNpb25OYW1lRnJvbUlkIiwiZXh0ZW5zaW9uSWQiLCJleHRlbnNpb25OYW1lIiwiZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbSIsImdldEV4dGVuc2lvblJlZ2lzdHJhdGlvbiIsInJlZ2lzdGVyRXh0ZW5zaW9uIiwiZXh0ZW5zaW9uUmVnaXN0cmF0aW9uIiwiYXR0YWNoIiwiZXhpc3RpbmdTbG90IiwiZGV0YWNoIiwiZXh0ZW5zaW9uU2xvdE5hbWUiLCJpZCIsImRldGFjaEFsbCIsImdldE9yZGVyIiwiY29uZmlndXJlZE9yZGVyIiwicmVnaXN0ZXJlZE9yZGVySW5kZXgiLCJhdHRhY2hlZE9yZGVyIiwiY29uZmlndXJlZEluZGV4IiwidW5kZWZpbmVkIiwiYXNzaWduZWRJbmRleCIsImV4dGVuc2lvbkNvbmZpZ1N0b3JlU3RhdGUiLCJzZXNzaW9uIiwiYXR0YWNoZWRJZHMiLCJhc3NpZ25lZElkcyIsImNhbGN1bGF0ZUFzc2lnbmVkSWRzIiwiZXh0ZW5zaW9ucyIsInJhd0V4dGVuc2lvbkNvbmZpZyIsInJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWciLCJleHRlbnNpb25Db25maWciLCJleHRlbnNpb24iLCJyZXF1aXJlZFByaXZpbGVnZXMiLCJBcnJheSIsImZpbHRlckV4dGVuc2lvbnNCeURpc3BsYXlDb25kaXRpb25zIiwiZXhwcmVzc2lvbkNvbnRleHQiLCJleHByZXNzaW9uIiwiQm9vbGVhbiIsImdldEFzc2lnbmVkRXh0ZW5zaW9ucyIsImdldENhbmRpZGF0ZUV4dGVuc2lvbnMiLCJhZGRlZElkcyIsInJlbW92ZWRJZHMiLCJpZE9yZGVyIiwiaWRBIiwiaWRCIiwiYWkiLCJiaSIsInJlZ2lzdGVyRXh0ZW5zaW9uU2xvdCIsImN1cnJlbnRTdGF0ZSIsImV4aXN0aW5nTW9kdWxlTmFtZSIsInJlc2V0IiwiTWFwIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnQ0FBZ0MsR0FBRzs7Ozs7OztDQU9sQyxHQUFrRTtBQUNrSTtBQUMvSDtBQUNQO0FBQ3BCO0FBQ2lIO0FBQzVKLE1BQU1nQix5QkFBeUJKLHdEQUF5QkE7QUFDeEQsTUFBTUssaUJBQWlCSixnREFBaUJBO0FBQ3hDLE1BQU1LLG1CQUFtQmIscUVBQTRCQTtBQUNyRCxNQUFNYyx3QkFBd0JiLGlFQUF3QkE7QUFDdEQ7Ozs7Q0FJQyxHQUFHLElBQUljLGFBQWEsSUFBSUM7QUFDekIsSUFBSUMsMkJBQTJCO0FBQy9CLFNBQVNDLGVBQWVDLEtBQUs7SUFDekIsSUFBSUEsVUFBVSxNQUFNO1FBQ2hCSixhQUFhO0lBQ2pCLE9BQU8sSUFBSUEsZUFBZSxNQUFNO1FBQzVCLEtBQUssTUFBTUssWUFBWUQsTUFBTTtZQUN6QkosV0FBVyxHQUFHLENBQUNLO1FBQ25CO0lBQ0o7SUFDQVgsb0RBQXFCQSxDQUFDWTtBQUMxQjtBQUNBOzs7O0NBSUMsR0FBRyxNQUFNQyx5QkFBeUI7QUFDbkMsU0FBU0Q7SUFDTCxnR0FBZ0c7SUFDaEcsNkVBQTZFO0lBQzdFLElBQUlKLDBCQUEwQjtRQUMxQjtJQUNKO0lBQ0FBLDJCQUEyQjtJQUMzQixJQUFJO1FBQ0EsSUFBSSxJQUFJTSxPQUFPLElBQUlBLE9BQU87WUFDdEIsTUFBTUosUUFBUUo7WUFDZCxJQUFJSSxVQUFVLFFBQVFBLE1BQU0sSUFBSSxL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\n//# sourceURL=webpack-internal:///../../framework/esm-extensions/dist/extensions.js\n\n}");
4699
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n attach: () => (attach),\n detach: () => (detach),\n detachAll: () => (detachAll),\n getAssignedExtensions: () => (getAssignedExtensions),\n getCandidateExtensions: () => (getCandidateExtensions),\n getExtensionNameFromId: () => (getExtensionNameFromId),\n getExtensionRegistration: () => (getExtensionRegistration),\n getExtensionRegistrationFrom: () => (getExtensionRegistrationFrom),\n registerExtension: () => (registerExtension),\n registerExtensionSlot: () => (registerExtensionSlot),\n reset: () => (reset)\n});\n/* import */ var _openmrs_esm_api__rspack_import_0 = __webpack_require__(\"../../framework/esm-api/dist/index.js\");\n/* import */ var _openmrs_esm_config__rspack_import_1 = __webpack_require__(\"../../framework/esm-config/dist/index.js\");\n/* import */ var _openmrs_esm_expression_evaluator__rspack_import_6 = __webpack_require__(\"../../framework/esm-expression-evaluator/dist/evaluator.js\");\n/* import */ var _openmrs_esm_feature_flags__rspack_import_2 = __webpack_require__(\"../../framework/esm-feature-flags/dist/index.js\");\n/* import */ var lodash_es__rspack_import_4 = __webpack_require__(\"../../../node_modules/lodash-es/isEqual.js\");\n/* import */ var lodash_es__rspack_import_5 = __webpack_require__(\"../../../node_modules/lodash-es/merge.js\");\n/* import */ var _store_js__rspack_import_3 = __webpack_require__(\"../../framework/esm-extensions/dist/store.js\");\n/** @module @category Extension */ /*\n * We have the following extension modes:\n *\n * - attached (set via code in form of: attach, detach, ...)\n * - configured (set via configuration in form of: added, removed, ...)\n * - assigned (computed from attached and configured)\n * - displayed (computed from assigned)\n */ \n\n\n\n\n\nconst extensionInternalStore = (0,_store_js__rspack_import_3.getExtensionInternalStore)();\nconst extensionStore = (0,_store_js__rspack_import_3.getExtensionStore)();\nconst slotsConfigStore = (0,_openmrs_esm_config__rspack_import_1.getExtensionSlotsConfigStore)();\nconst extensionsConfigStore = (0,_openmrs_esm_config__rspack_import_1.getExtensionsConfigStore)();\n/**\n * Slots whose derived state may have changed since the output store was last updated. `null`\n * stands for \"every slot\", and is used when an input changes that isn't scoped to one slot —\n * the session, a feature flag, connectivity, or a new extension registration.\n */ let dirtySlots = new Set();\nlet isRecomputingOutputStore = false;\nfunction markSlotsDirty(slots) {\n if (slots === null) {\n dirtySlots = null;\n } else if (dirtySlots !== null) {\n for (const slotName of slots){\n dirtySlots.add(slotName);\n }\n }\n (0,_store_js__rspack_import_3.scheduleRecomputation)(recomputeExtensionOutputStore);\n}\n/**\n * A subscriber that dirties a slot every time the output store is published would loop here for\n * ever, so the drain gives up after this many passes and leaves the rest for the next write. Any\n * real cascade settles in two or three.\n */ const maxRecomputationPasses = 20;\nfunction recomputeExtensionOutputStore() {\n // Publishing notifies subscribers synchronously, so one that dirties a slot re-enters here. The\n // loop below picks that work up; recursing instead would nest without bound.\n if (isRecomputingOutputStore) {\n return;\n }\n isRecomputingOutputStore = true;\n try {\n for(let pass = 1;; pass++){\n const slots = dirtySlots;\n if (slots !== null && slots.size === 0) {\n return;\n }\n // Taken before the work so that anything dirtied while it runs accumulates for the next pass\n // rather than being discarded when this one finishes.\n dirtySlots = new Set();\n try {\n updateExtensionOutputStore(extensionInternalStore.getState(), slotsConfigStore.getState(), extensionsConfigStore.getState(), _openmrs_esm_feature_flags__rspack_import_2.featureFlagsStore.getState(), _openmrs_esm_api__rspack_import_0.sessionStore.getState(), slots);\n } catch (e) {\n // Fold the work back in, so a failure leaves these slots marked for the next recomputation\n // instead of stranding them stale.\n dirtySlots = slots === null || dirtySlots === null ? null : new Set([\n ...slots,\n ...dirtySlots\n ]);\n throw e;\n }\n if (pass >= maxRecomputationPasses) {\n console.error(`The extension system stopped recomputing after ${maxRecomputationPasses} passes because ` + `something keeps invalidating slots in response to the extension store being written. ` + `Some slots are left stale until the next write.`);\n return;\n }\n }\n } finally{\n isRecomputingOutputStore = false;\n }\n}\n/**\n * Re-derives the output store from the extension system's inputs.\n *\n * Two things keep this cheap. `dirtySlotNames` limits which slots are recomputed at all; passing\n * `null` recomputes every slot. And slots whose derived value hasn't changed keep their existing\n * object, so that components subscribed to one slot don't re-render because a different slot\n * changed.\n */ function updateExtensionOutputStore(internalState, extensionSlotConfigs, extensionsConfigState, featureFlagState, sessionState, dirtySlotNames = null) {\n const previousSlots = extensionStore.getState().slots;\n const slots = {};\n let changed = false;\n const enabledFeatureFlags = Object.entries(featureFlagState.flags).filter(([, { enabled }])=>enabled).map(([name])=>name);\n for (let [slotName, slot] of Object.entries(internalState.slots)){\n const previous = previousSlots[slotName];\n if (previous && dirtySlotNames && !dirtySlotNames.has(slotName)) {\n slots[slotName] = previous;\n continue;\n }\n const { config } = (0,_openmrs_esm_config__rspack_import_1.getExtensionSlotConfigFromStore)(extensionSlotConfigs, slot.name);\n const candidateExtensions = getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionsConfigState, enabledFeatureFlags, sessionState.session);\n if (previous && previous.moduleName === slot.moduleName && (0,lodash_es__rspack_import_4[\"default\"])(previous.candidateExtensions, candidateExtensions)) {\n slots[slotName] = previous;\n } else {\n slots[slotName] = {\n moduleName: slot.moduleName,\n candidateExtensions\n };\n changed = true;\n }\n }\n if (changed || Object.keys(previousSlots).length !== Object.keys(slots).length) {\n extensionStore.setState({\n slots\n });\n }\n}\n/**\n * Returns the keys whose values differ between two records, including keys present in only one.\n */ function changedKeys(next, previous) {\n const changed = new Set();\n for (const key of Object.keys(next)){\n if (next[key] !== previous[key]) {\n changed.add(key);\n }\n }\n for (const key of Object.keys(previous)){\n if (!(key in next)) {\n changed.add(key);\n }\n }\n return changed;\n}\nextensionInternalStore.subscribe((state, previousState)=>{\n // A new or changed registration can affect any slot the extension might be assigned to. Every\n // other kind of change here — attaching, registering a slot — is scoped to the slots whose\n // entries actually changed.\n markSlotsDirty(state.extensions !== previousState.extensions ? null : changedKeys(state.slots, previousState.slots));\n});\n// Slot configs are per-slot, so a config change invalidates only the slots it names.\nslotsConfigStore.subscribe((state, previousState)=>{\n markSlotsDirty(changedKeys(state.slots, previousState.slots));\n});\n// Extension configs are keyed by slot too, and the config system hands back the same per-slot\n// object when nothing under it changed, so only the slots whose configs actually moved are dirtied.\nextensionsConfigStore.subscribe((state, previousState)=>{\n markSlotsDirty(changedKeys(state.configs, previousState.configs));\n});\n_openmrs_esm_feature_flags__rspack_import_2.featureFlagsStore.subscribe(()=>markSlotsDirty(null));\n_openmrs_esm_api__rspack_import_0.sessionStore.subscribe(()=>markSlotsDirty(null));\nfunction updateOutputStoreToCurrent() {\n markSlotsDirty(null);\n}\nupdateOutputStoreToCurrent();\nfunction createNewExtensionSlotInfo(slotName, moduleName) {\n return {\n moduleName,\n name: slotName,\n attachedIds: []\n };\n}\n/**\n * Given an extension ID, which is a string uniquely identifying\n * an instance of an extension within an extension slot, this\n * returns the extension name.\n *\n * @example\n * ```js\n * getExtensionNameFromId(\"foo#bar\")\n * --> \"foo\"\n * getExtensionNameFromId(\"baz\")\n * --> \"baz\"\n * ```\n */ function getExtensionNameFromId(extensionId) {\n const [extensionName] = extensionId.split('#');\n return extensionName;\n}\nfunction getExtensionRegistrationFrom(state, extensionId) {\n const name = getExtensionNameFromId(extensionId);\n return state.extensions[name];\n}\nfunction getExtensionRegistration(extensionId) {\n const state = extensionInternalStore.getState();\n return getExtensionRegistrationFrom(state, extensionId);\n}\n/**\n * Extensions must be registered in order to be rendered.\n * This is handled by the app shell, when extensions are provided\n * via the `routes.json` file and registered through `registerApp()`.\n * @internal\n */ const registerExtension = (extensionRegistration)=>(0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>({\n ...state,\n extensions: {\n ...state.extensions,\n [extensionRegistration.name]: {\n ...extensionRegistration\n }\n }\n }));\n/**\n * Attach an extension to an extension slot.\n *\n * This will cause the extension to be rendered into the specified\n * extension slot, unless it is removed by configuration. Using\n * `attach` is an alternative to specifying the `slot` or `slots`\n * in the extension declaration.\n *\n * It is particularly useful when creating a slot into which\n * you want to render an existing extension. This enables you\n * to do so without modifying the extension's declaration, which\n * may be impractical or inappropriate, for example if you are\n * writing a module for a specific implementation.\n *\n * @param slotName a name uniquely identifying the slot\n * @param extensionId an extension name, with an optional #-suffix\n * to distinguish it from other instances of the same extension\n * attached to the same slot.\n */ function attach(slotName, extensionId) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[slotName];\n if (!existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...createNewExtensionSlotInfo(slotName),\n attachedIds: [\n extensionId\n ]\n }\n }\n };\n } else {\n return {\n ...state,\n slots: {\n ...state.slots,\n [slotName]: {\n ...existingSlot,\n attachedIds: [\n ...existingSlot.attachedIds,\n extensionId\n ]\n }\n }\n };\n }\n });\n}\n/**\n * Detaches an extension from an extension slot.\n *\n * @param extensionSlotName The name of the extension slot to detach from.\n * @param extensionId The ID of the extension to detach.\n *\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detach(extensionSlotName, extensionId) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot && existingSlot.attachedIds.includes(extensionId)) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: existingSlot.attachedIds.filter((id)=>id !== extensionId)\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/**\n * Detaches all extensions from an extension slot.\n *\n * @param extensionSlotName The name of the extension slot to clear.\n *\n * @deprecated Avoid using this. Extension attachments should be considered declarative.\n */ function detachAll(extensionSlotName) {\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)((state)=>{\n const existingSlot = state.slots[extensionSlotName];\n if (existingSlot) {\n return {\n ...state,\n slots: {\n ...state.slots,\n [extensionSlotName]: {\n ...existingSlot,\n attachedIds: []\n }\n }\n };\n } else {\n return state;\n }\n });\n}\n/** Maps each ID to the index of its first occurrence, matching `Array.prototype.indexOf`. */ function indexById(ids) {\n const index = new Map();\n ids.forEach((id, i)=>{\n if (!index.has(id)) {\n index.set(id, i);\n }\n });\n return index;\n}\n/**\n * Get an order index for the extension. This will\n * come from either its configured order, its registered order\n * parameter, or the order in which it happened to be attached.\n *\n * The four bands below keep the comparison a total order: every extension lands in exactly one, and\n * those with no ordering information share the last band rather than taking a sentinel that can't be\n * compared against itself.\n */ function getOrder(extensionId, configuredOrder, registeredOrderIndex, attachedOrder) {\n const configuredIndex = configuredOrder.get(extensionId);\n if (configuredIndex !== undefined) {\n return configuredIndex;\n } else if (registeredOrderIndex !== undefined) {\n // extensions that don't have a configured order should appear after those that do\n return 1000 + registeredOrderIndex;\n } else {\n const assignedIndex = attachedOrder.get(extensionId);\n if (assignedIndex !== undefined) {\n // extensions that have neither a configured nor registered order should appear\n // after all others\n return 2000 + assignedIndex;\n } else {\n // Added by configuration with no order of any kind — after everything else, and among\n // themselves in the order the configuration lists them.\n return 3000;\n }\n }\n}\nfunction getAssignedExtensionsFromSlotData(slotName, internalState, config, extensionConfigStoreState, enabledFeatureFlags, session) {\n const attachedIds = internalState.slots[slotName].attachedIds;\n const assignedIds = calculateAssignedIds(config, attachedIds);\n const extensions = [];\n for (let id of assignedIds){\n const { config: rawExtensionConfig } = (0,_openmrs_esm_config__rspack_import_1.getExtensionConfigFromStore)(extensionConfigStoreState, slotName, id);\n const rawExtensionSlotExtensionConfig = (0,_openmrs_esm_config__rspack_import_1.getExtensionConfigFromExtensionSlotStore)(config, slotName, id);\n // `merge` mutates its first argument, and `rawExtensionConfig` belongs to the config store,\n // so never merge into it.\n const extensionConfig = rawExtensionSlotExtensionConfig ? (0,lodash_es__rspack_import_5[\"default\"])({}, rawExtensionConfig, rawExtensionSlotExtensionConfig) : rawExtensionConfig;\n const name = getExtensionNameFromId(id);\n const extension = internalState.extensions[name];\n // if the extension has not been registered yet, do not include it\n if (extension) {\n const requiredPrivileges = extensionConfig?.['Display conditions']?.privileges ?? extension.privileges ?? [];\n if (requiredPrivileges && (typeof requiredPrivileges === 'string' || Array.isArray(requiredPrivileges) && requiredPrivileges.length > 0)) {\n if (!session?.user) {\n continue;\n }\n if (!(0,_openmrs_esm_api__rspack_import_0.userHasAccess)(requiredPrivileges, session.user)) {\n continue;\n }\n }\n if (extension.featureFlag && !enabledFeatureFlags.includes(extension.featureFlag)) {\n continue;\n }\n extensions.push({\n id,\n name,\n moduleName: extension.moduleName,\n config: extensionConfig,\n featureFlag: extension.featureFlag,\n meta: extension.meta,\n displayConditionExpression: extensionConfig?.['Display conditions']?.expression || extension.displayExpression\n });\n }\n }\n return extensions;\n}\n/**\n * Narrows `extensions` to those whose display condition holds for one particular rendering of a\n * slot, evaluating each condition against `state`.\n *\n * An extension whose display condition throws is left out, on the grounds that a condition that cannot be\n * evaluated has not been met.\n *\n * @param extensions The extensions assigned to the slot, as the extension store holds them\n * @param state The state of this rendering of the slot\n * @param session The current session, which conditions may refer to as `session`\n * @param slotName The slot these were assigned to, used only to identify them if a condition throws\n * @returns Those of `extensions` that should be displayed, in the same order. Always a new array.\n */ function filterExtensionsByDisplayConditions(extensions, state, session = null, slotName) {\n // Built once for the whole slot rather than per extension: the context is the same for all of\n // them, and most slots have no conditions at all.\n let expressionContext;\n return extensions.filter((extension)=>{\n const expression = extension.displayConditionExpression;\n if (typeof expression !== 'string' || expression.trim().length === 0) {\n return true;\n }\n expressionContext ?? (expressionContext = state && typeof state === 'object' ? {\n session,\n ...state\n } : {\n session\n });\n try {\n return Boolean((0,_openmrs_esm_expression_evaluator__rspack_import_6.evaluateAsBoolean)(expression, expressionContext));\n } catch (e) {\n console.error(`Error while evaluating expression '${expression}' for ${extension.id}` + (slotName ? ` in ${slotName}` : ''), e);\n return false;\n }\n });\n}\n/**\n * Gets the extensions a given rendering of a slot should display, in order. This is the supported\n * way to ask what belongs in a slot; reading the extension store directly skips display conditions.\n *\n * Display conditions are evaluated against `state`, so pass whatever the slot is being rendered\n * for. The same slot can be rendered many times with different state — once per row of a table,\n * say — and each rendering can resolve to a different set of extensions. Omitting `state` hides\n * every extension whose condition refers to it, since the condition cannot be evaluated.\n *\n * @param slotName The slot to load the extensions for\n * @param state The state of the rendering of the slot the extensions will be displayed in\n * @returns Those extensions assigned to the slot whose display conditions hold\n */ function getAssignedExtensions(slotName, state) {\n return filterExtensionsByDisplayConditions(getCandidateExtensions(slotName), state, _openmrs_esm_api__rspack_import_0.sessionStore.getState().session, slotName);\n}\n/**\n * Gets everything assigned to a slot without evaluating any display condition, which\n * {@link getAssignedExtensions} cannot do without knowing the state of a particular rendering.\n *\n * This exists for tools that present a slot's configuration rather than render it — the UI editor\n * has to list an extension in order to let an implementer reorder or remove it, even where no\n * rendering would display it. Anything deciding what to render wants `getAssignedExtensions()`.\n *\n * @internal\n */ function getCandidateExtensions(slotName) {\n return extensionStore.getState().slots[slotName]?.candidateExtensions ?? [];\n}\nfunction calculateAssignedIds(config, attachedIds) {\n const addedIds = config.add || [];\n const removedIds = config.remove || [];\n const idOrder = config.order || [];\n const { extensions } = extensionInternalStore.getState();\n const removed = new Set(removedIds);\n const ids = [\n ...attachedIds,\n ...addedIds\n ].filter((id)=>!removed.has(id));\n const configuredIndex = indexById(idOrder);\n const attachedIndex = indexById(attachedIds);\n // Computed once per ID: calling `getOrder` from the comparator makes the sort quadratic.\n const order = new Map(ids.map((id)=>[\n id,\n getOrder(id, configuredIndex, extensions[getExtensionNameFromId(id)]?.order, attachedIndex)\n ]));\n // Ties keep their input order — `Array.prototype.sort` is stable, and the input is\n // `[...attachedIds, ...addedIds]`, so two extensions the ordering rules can't separate\n // come out in the order the code and the configuration declared them.\n return ids.sort((idA, idB)=>order.get(idA) - order.get(idB));\n}\n/**\n * Used by by extension slots at mount time.\n *\n * @param moduleName The name of the module that contains the extension slot\n * @param slotName The extension slot name that is actually used\n * @internal\n */ const registerExtensionSlot = (moduleName, slotName)=>extensionInternalStore.setState((currentState)=>{\n const existingModuleName = currentState.slots[slotName]?.moduleName;\n if (existingModuleName && existingModuleName != moduleName) {\n console.warn(`An extension slot with the name '${slotName}' already exists. Refusing to register the same slot name twice (in \"registerExtensionSlot\"). The existing one is from module ${existingModuleName}.`);\n return currentState;\n }\n if (existingModuleName && existingModuleName == moduleName) {\n // Re-rendering an existing slot\n return currentState;\n }\n if (currentState.slots[slotName]) {\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...currentState.slots[slotName],\n moduleName\n }\n }\n };\n }\n const slot = createNewExtensionSlotInfo(slotName, moduleName);\n return {\n ...currentState,\n slots: {\n ...currentState.slots,\n [slotName]: {\n ...slot\n }\n }\n };\n });\n/**\n * @internal\n * Just for testing.\n */ const reset = ()=>{\n // Invalidation is carried in module state, so it has to be reset too or it bleeds into the\n // next test as either a stale dirty set or a missing one.\n dirtySlots = null;\n (0,_store_js__rspack_import_3.updateInternalExtensionStore)(()=>({\n slots: {},\n extensions: {}\n }));\n (0,_store_js__rspack_import_3.getExtensionRenderingsStore)().setState({\n renderings: new Map()\n });\n extensionStore.setState({\n slots: {}\n });\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcyIsInNvdXJjZXMiOlsid2VicGFjazovL0BvcGVubXJzL2VzbS1hcHAtc2hlbGwvLi4vLi4vZnJhbWV3b3JrL2VzbS1leHRlbnNpb25zL2Rpc3QvZXh0ZW5zaW9ucy5qcz84NWQ4Il0sInNvdXJjZXNDb250ZW50IjpbIi8qKiBAbW9kdWxlIEBjYXRlZ29yeSBFeHRlbnNpb24gKi8gLypcbiAqIFdlIGhhdmUgdGhlIGZvbGxvd2luZyBleHRlbnNpb24gbW9kZXM6XG4gKlxuICogLSBhdHRhY2hlZCAoc2V0IHZpYSBjb2RlIGluIGZvcm0gb2Y6IGF0dGFjaCwgZGV0YWNoLCAuLi4pXG4gKiAtIGNvbmZpZ3VyZWQgKHNldCB2aWEgY29uZmlndXJhdGlvbiBpbiBmb3JtIG9mOiBhZGRlZCwgcmVtb3ZlZCwgLi4uKVxuICogLSBhc3NpZ25lZCAoY29tcHV0ZWQgZnJvbSBhdHRhY2hlZCBhbmQgY29uZmlndXJlZClcbiAqIC0gZGlzcGxheWVkIChjb21wdXRlZCBmcm9tIGFzc2lnbmVkKVxuICovIGltcG9ydCB7IHNlc3Npb25TdG9yZSwgdXNlckhhc0FjY2VzcyB9IGZyb20gXCJAb3Blbm1ycy9lc20tYXBpXCI7XG5pbXBvcnQgeyBnZXRFeHRlbnNpb25Db25maWdGcm9tRXh0ZW5zaW9uU2xvdFN0b3JlLCBnZXRFeHRlbnNpb25Db25maWdGcm9tU3RvcmUsIGdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUsIGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUsIGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSB9IGZyb20gXCJAb3Blbm1ycy9lc20tY29uZmlnXCI7XG5pbXBvcnQgeyBldmFsdWF0ZUFzQm9vbGVhbiB9IGZyb20gXCJAb3Blbm1ycy9lc20tZXhwcmVzc2lvbi1ldmFsdWF0b3JcIjtcbmltcG9ydCB7IGZlYXR1cmVGbGFnc1N0b3JlIH0gZnJvbSBcIkBvcGVubXJzL2VzbS1mZWF0dXJlLWZsYWdzXCI7XG5pbXBvcnQgeyBpc0VxdWFsLCBtZXJnZSB9IGZyb20gXCJsb2Rhc2gtZXNcIjtcbmltcG9ydCB7IGdldEV4dGVuc2lvblJlbmRlcmluZ3NTdG9yZSwgZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSwgZ2V0RXh0ZW5zaW9uU3RvcmUsIHNjaGVkdWxlUmVjb21wdXRhdGlvbiwgdXBkYXRlSW50ZXJuYWxFeHRlbnNpb25TdG9yZSB9IGZyb20gXCIuL3N0b3JlLmpzXCI7XG5jb25zdCBleHRlbnNpb25JbnRlcm5hbFN0b3JlID0gZ2V0RXh0ZW5zaW9uSW50ZXJuYWxTdG9yZSgpO1xuY29uc3QgZXh0ZW5zaW9uU3RvcmUgPSBnZXRFeHRlbnNpb25TdG9yZSgpO1xuY29uc3Qgc2xvdHNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvblNsb3RzQ29uZmlnU3RvcmUoKTtcbmNvbnN0IGV4dGVuc2lvbnNDb25maWdTdG9yZSA9IGdldEV4dGVuc2lvbnNDb25maWdTdG9yZSgpO1xuLyoqXG4gKiBTbG90cyB3aG9zZSBkZXJpdmVkIHN0YXRlIG1heSBoYXZlIGNoYW5nZWQgc2luY2UgdGhlIG91dHB1dCBzdG9yZSB3YXMgbGFzdCB1cGRhdGVkLiBgbnVsbGBcbiAqIHN0YW5kcyBmb3IgXCJldmVyeSBzbG90XCIsIGFuZCBpcyB1c2VkIHdoZW4gYW4gaW5wdXQgY2hhbmdlcyB0aGF0IGlzbid0IHNjb3BlZCB0byBvbmUgc2xvdCDigJRcbiAqIHRoZSBzZXNzaW9uLCBhIGZlYXR1cmUgZmxhZywgY29ubmVjdGl2aXR5LCBvciBhIG5ldyBleHRlbnNpb24gcmVnaXN0cmF0aW9uLlxuICovIGxldCBkaXJ0eVNsb3RzID0gbmV3IFNldCgpO1xubGV0IGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSA9IGZhbHNlO1xuZnVuY3Rpb24gbWFya1Nsb3RzRGlydHkoc2xvdHMpIHtcbiAgICBpZiAoc2xvdHMgPT09IG51bGwpIHtcbiAgICAgICAgZGlydHlTbG90cyA9IG51bGw7XG4gICAgfSBlbHNlIGlmIChkaXJ0eVNsb3RzICE9PSBudWxsKSB7XG4gICAgICAgIGZvciAoY29uc3Qgc2xvdE5hbWUgb2Ygc2xvdHMpe1xuICAgICAgICAgICAgZGlydHlTbG90cy5hZGQoc2xvdE5hbWUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHNjaGVkdWxlUmVjb21wdXRhdGlvbihyZWNvbXB1dGVFeHRlbnNpb25PdXRwdXRTdG9yZSk7XG59XG4vKipcbiAqIEEgc3Vic2NyaWJlciB0aGF0IGRpcnRpZXMgYSBzbG90IGV2ZXJ5IHRpbWUgdGhlIG91dHB1dCBzdG9yZSBpcyBwdWJsaXNoZWQgd291bGQgbG9vcCBoZXJlIGZvclxuICogZXZlciwgc28gdGhlIGRyYWluIGdpdmVzIHVwIGFmdGVyIHRoaXMgbWFueSBwYXNzZXMgYW5kIGxlYXZlcyB0aGUgcmVzdCBmb3IgdGhlIG5leHQgd3JpdGUuIEFueVxuICogcmVhbCBjYXNjYWRlIHNldHRsZXMgaW4gdHdvIG9yIHRocmVlLlxuICovIGNvbnN0IG1heFJlY29tcHV0YXRpb25QYXNzZXMgPSAyMDtcbmZ1bmN0aW9uIHJlY29tcHV0ZUV4dGVuc2lvbk91dHB1dFN0b3JlKCkge1xuICAgIC8vIFB1Ymxpc2hpbmcgbm90aWZpZXMgc3Vic2NyaWJlcnMgc3luY2hyb25vdXNseSwgc28gb25lIHRoYXQgZGlydGllcyBhIHNsb3QgcmUtZW50ZXJzIGhlcmUuIFRoZVxuICAgIC8vIGxvb3AgYmVsb3cgcGlja3MgdGhhdCB3b3JrIHVwOyByZWN1cnNpbmcgaW5zdGVhZCB3b3VsZCBuZXN0IHdpdGhvdXQgYm91bmQuXG4gICAgaWYgKGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIGlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgICAgZm9yKGxldCBwYXNzID0gMTs7IHBhc3MrKyl7XG4gICAgICAgICAgICBjb25zdCBzbG90cyA9IGRpcnR5U2xvdHM7XG4gICAgICAgICAgICBpZiAoc2xvdHMgIT09IG51bGwgJiYgc2xvdHMuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIFRha2VuIGJlZm9yZSB0aGUgd29yayBzbyB0aGF0IGFueXRoaW5nIGRpcnRpZWQgd2hpbGUgaXQgcnVucyBhY2N1bXVsYXRlcyBmb3IgdGhlIG5leHQgcGFzc1xuICAgICAgICAgICAgLy8gcmF0aGVyIHRoYW4gYmVpbmcgZGlzY2FyZGVkIHdoZW4gdGhpcyBvbmUgZmluaXNoZXMuXG4gICAgICAgICAgICBkaXJ0eVNsb3RzID0gbmV3IFNldCgpO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB1cGRhdGVFeHRlbnNpb25PdXRwdXRTdG9yZShleHRlbnNpb25JbnRlcm5hbFN0b3JlLmdldFN0YXRlKCksIHNsb3RzQ29uZmlnU3RvcmUuZ2V0U3RhdGUoKSwgZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLmdldFN0YXRlKCksIGZlYXR1cmVGbGFnc1N0b3JlLmdldFN0YXRlKCksIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLCBzbG90cyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgLy8gRm9sZCB0aGUgd29yayBiYWNrIGluLCBzbyBhIGZhaWx1cmUgbGVhdmVzIHRoZXNlIHNsb3RzIG1hcmtlZCBmb3IgdGhlIG5leHQgcmVjb21wdXRhdGlvblxuICAgICAgICAgICAgICAgIC8vIGluc3RlYWQgb2Ygc3RyYW5kaW5nIHRoZW0gc3RhbGUuXG4gICAgICAgICAgICAgICAgZGlydHlTbG90cyA9IHNsb3RzID09PSBudWxsIHx8IGRpcnR5U2xvdHMgPT09IG51bGwgPyBudWxsIDogbmV3IFNldChbXG4gICAgICAgICAgICAgICAgICAgIC4uLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICAuLi5kaXJ0eVNsb3RzXG4gICAgICAgICAgICAgICAgXSk7XG4gICAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChwYXNzID49IG1heFJlY29tcHV0YXRpb25QYXNzZXMpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBUaGUgZXh0ZW5zaW9uIHN5c3RlbSBzdG9wcGVkIHJlY29tcHV0aW5nIGFmdGVyICR7bWF4UmVjb21wdXRhdGlvblBhc3Nlc30gcGFzc2VzIGJlY2F1c2UgYCArIGBzb21ldGhpbmcga2VlcHMgaW52YWxpZGF0aW5nIHNsb3RzIGluIHJlc3BvbnNlIHRvIHRoZSBleHRlbnNpb24gc3RvcmUgYmVpbmcgd3JpdHRlbi4gYCArIGBTb21lIHNsb3RzIGFyZSBsZWZ0IHN0YWxlIHVudGlsIHRoZSBuZXh0IHdyaXRlLmApO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH0gZmluYWxseXtcbiAgICAgICAgaXNSZWNvbXB1dGluZ091dHB1dFN0b3JlID0gZmFsc2U7XG4gICAgfVxufVxuLyoqXG4gKiBSZS1kZXJpdmVzIHRoZSBvdXRwdXQgc3RvcmUgZnJvbSB0aGUgZXh0ZW5zaW9uIHN5c3RlbSdzIGlucHV0cy5cbiAqXG4gKiBUd28gdGhpbmdzIGtlZXAgdGhpcyBjaGVhcC4gYGRpcnR5U2xvdE5hbWVzYCBsaW1pdHMgd2hpY2ggc2xvdHMgYXJlIHJlY29tcHV0ZWQgYXQgYWxsOyBwYXNzaW5nXG4gKiBgbnVsbGAgcmVjb21wdXRlcyBldmVyeSBzbG90LiBBbmQgc2xvdHMgd2hvc2UgZGVyaXZlZCB2YWx1ZSBoYXNuJ3QgY2hhbmdlZCBrZWVwIHRoZWlyIGV4aXN0aW5nXG4gKiBvYmplY3QsIHNvIHRoYXQgY29tcG9uZW50cyBzdWJzY3JpYmVkIHRvIG9uZSBzbG90IGRvbid0IHJlLXJlbmRlciBiZWNhdXNlIGEgZGlmZmVyZW50IHNsb3RcbiAqIGNoYW5nZWQuXG4gKi8gZnVuY3Rpb24gdXBkYXRlRXh0ZW5zaW9uT3V0cHV0U3RvcmUoaW50ZXJuYWxTdGF0ZSwgZXh0ZW5zaW9uU2xvdENvbmZpZ3MsIGV4dGVuc2lvbnNDb25maWdTdGF0ZSwgZmVhdHVyZUZsYWdTdGF0ZSwgc2Vzc2lvblN0YXRlLCBkaXJ0eVNsb3ROYW1lcyA9IG51bGwpIHtcbiAgICBjb25zdCBwcmV2aW91c1Nsb3RzID0gZXh0ZW5zaW9uU3RvcmUuZ2V0U3RhdGUoKS5zbG90cztcbiAgICBjb25zdCBzbG90cyA9IHt9O1xuICAgIGxldCBjaGFuZ2VkID0gZmFsc2U7XG4gICAgY29uc3QgZW5hYmxlZEZlYXR1cmVGbGFncyA9IE9iamVjdC5lbnRyaWVzKGZlYXR1cmVGbGFnU3RhdGUuZmxhZ3MpLmZpbHRlcigoWywgeyBlbmFibGVkIH1dKT0+ZW5hYmxlZCkubWFwKChbbmFtZV0pPT5uYW1lKTtcbiAgICBmb3IgKGxldCBbc2xvdE5hbWUsIHNsb3RdIG9mIE9iamVjdC5lbnRyaWVzKGludGVybmFsU3RhdGUuc2xvdHMpKXtcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBwcmV2aW91c1Nsb3RzW3Nsb3ROYW1lXTtcbiAgICAgICAgaWYgKHByZXZpb3VzICYmIGRpcnR5U2xvdE5hbWVzICYmICFkaXJ0eVNsb3ROYW1lcy5oYXMoc2xvdE5hbWUpKSB7XG4gICAgICAgICAgICBzbG90c1tzbG90TmFtZV0gPSBwcmV2aW91cztcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHsgY29uZmlnIH0gPSBnZXRFeHRlbnNpb25TbG90Q29uZmlnRnJvbVN0b3JlKGV4dGVuc2lvblNsb3RDb25maWdzLCBzbG90Lm5hbWUpO1xuICAgICAgICBjb25zdCBjYW5kaWRhdGVFeHRlbnNpb25zID0gZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhKHNsb3ROYW1lLCBpbnRlcm5hbFN0YXRlLCBjb25maWcsIGV4dGVuc2lvbnNDb25maWdTdGF0ZSwgZW5hYmxlZEZlYXR1cmVGbGFncywgc2Vzc2lvblN0YXRlLnNlc3Npb24pO1xuICAgICAgICBpZiAocHJldmlvdXMgJiYgcHJldmlvdXMubW9kdWxlTmFtZSA9PT0gc2xvdC5tb2R1bGVOYW1lICYmIGlzRXF1YWwocHJldmlvdXMuY2FuZGlkYXRlRXh0ZW5zaW9ucywgY2FuZGlkYXRlRXh0ZW5zaW9ucykpIHtcbiAgICAgICAgICAgIHNsb3RzW3Nsb3ROYW1lXSA9IHByZXZpb3VzO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc2xvdHNbc2xvdE5hbWVdID0ge1xuICAgICAgICAgICAgICAgIG1vZHVsZU5hbWU6IHNsb3QubW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgICBjYW5kaWRhdGVFeHRlbnNpb25zXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKGNoYW5nZWQgfHwgT2JqZWN0LmtleXMocHJldmlvdXNTbG90cykubGVuZ3RoICE9PSBPYmplY3Qua2V5cyhzbG90cykubGVuZ3RoKSB7XG4gICAgICAgIGV4dGVuc2lvblN0b3JlLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHNsb3RzXG4gICAgICAgIH0pO1xuICAgIH1cbn1cbi8qKlxuICogUmV0dXJucyB0aGUga2V5cyB3aG9zZSB2YWx1ZXMgZGlmZmVyIGJldHdlZW4gdHdvIHJlY29yZHMsIGluY2x1ZGluZyBrZXlzIHByZXNlbnQgaW4gb25seSBvbmUuXG4gKi8gZnVuY3Rpb24gY2hhbmdlZEtleXMobmV4dCwgcHJldmlvdXMpIHtcbiAgICBjb25zdCBjaGFuZ2VkID0gbmV3IFNldCgpO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG5leHQpKXtcbiAgICAgICAgaWYgKG5leHRba2V5XSAhPT0gcHJldmlvdXNba2V5XSkge1xuICAgICAgICAgICAgY2hhbmdlZC5hZGQoa2V5KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhwcmV2aW91cykpe1xuICAgICAgICBpZiAoIShrZXkgaW4gbmV4dCkpIHtcbiAgICAgICAgICAgIGNoYW5nZWQuYWRkKGtleSk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNoYW5nZWQ7XG59XG5leHRlbnNpb25JbnRlcm5hbFN0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgLy8gQSBuZXcgb3IgY2hhbmdlZCByZWdpc3RyYXRpb24gY2FuIGFmZmVjdCBhbnkgc2xvdCB0aGUgZXh0ZW5zaW9uIG1pZ2h0IGJlIGFzc2lnbmVkIHRvLiBFdmVyeVxuICAgIC8vIG90aGVyIGtpbmQgb2YgY2hhbmdlIGhlcmUg4oCUIGF0dGFjaGluZywgcmVnaXN0ZXJpbmcgYSBzbG90IOKAlCBpcyBzY29wZWQgdG8gdGhlIHNsb3RzIHdob3NlXG4gICAgLy8gZW50cmllcyBhY3R1YWxseSBjaGFuZ2VkLlxuICAgIG1hcmtTbG90c0RpcnR5KHN0YXRlLmV4dGVuc2lvbnMgIT09IHByZXZpb3VzU3RhdGUuZXh0ZW5zaW9ucyA/IG51bGwgOiBjaGFuZ2VkS2V5cyhzdGF0ZS5zbG90cywgcHJldmlvdXNTdGF0ZS5zbG90cykpO1xufSk7XG4vLyBTbG90IGNvbmZpZ3MgYXJlIHBlci1zbG90LCBzbyBhIGNvbmZpZyBjaGFuZ2UgaW52YWxpZGF0ZXMgb25seSB0aGUgc2xvdHMgaXQgbmFtZXMuXG5zbG90c0NvbmZpZ1N0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgbWFya1Nsb3RzRGlydHkoY2hhbmdlZEtleXMoc3RhdGUuc2xvdHMsIHByZXZpb3VzU3RhdGUuc2xvdHMpKTtcbn0pO1xuLy8gRXh0ZW5zaW9uIGNvbmZpZ3MgYXJlIGtleWVkIGJ5IHNsb3QgdG9vLCBhbmQgdGhlIGNvbmZpZyBzeXN0ZW0gaGFuZHMgYmFjayB0aGUgc2FtZSBwZXItc2xvdFxuLy8gb2JqZWN0IHdoZW4gbm90aGluZyB1bmRlciBpdCBjaGFuZ2VkLCBzbyBvbmx5IHRoZSBzbG90cyB3aG9zZSBjb25maWdzIGFjdHVhbGx5IG1vdmVkIGFyZSBkaXJ0aWVkLlxuZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlLnN1YnNjcmliZSgoc3RhdGUsIHByZXZpb3VzU3RhdGUpPT57XG4gICAgbWFya1Nsb3RzRGlydHkoY2hhbmdlZEtleXMoc3RhdGUuY29uZmlncywgcHJldmlvdXNTdGF0ZS5jb25maWdzKSk7XG59KTtcbmZlYXR1cmVGbGFnc1N0b3JlLnN1YnNjcmliZSgoKT0+bWFya1Nsb3RzRGlydHkobnVsbCkpO1xuc2Vzc2lvblN0b3JlLnN1YnNjcmliZSgoKT0+bWFya1Nsb3RzRGlydHkobnVsbCkpO1xuZnVuY3Rpb24gdXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQoKSB7XG4gICAgbWFya1Nsb3RzRGlydHkobnVsbCk7XG59XG51cGRhdGVPdXRwdXRTdG9yZVRvQ3VycmVudCgpO1xuZnVuY3Rpb24gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICBtb2R1bGVOYW1lLFxuICAgICAgICBuYW1lOiBzbG90TmFtZSxcbiAgICAgICAgYXR0YWNoZWRJZHM6IFtdXG4gICAgfTtcbn1cbi8qKlxuICogR2l2ZW4gYW4gZXh0ZW5zaW9uIElELCB3aGljaCBpcyBhIHN0cmluZyB1bmlxdWVseSBpZGVudGlmeWluZ1xuICogYW4gaW5zdGFuY2Ugb2YgYW4gZXh0ZW5zaW9uIHdpdGhpbiBhbiBleHRlbnNpb24gc2xvdCwgdGhpc1xuICogcmV0dXJucyB0aGUgZXh0ZW5zaW9uIG5hbWUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYGpzXG4gKiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKFwiZm9vI2JhclwiKVxuICogIC0tPiBcImZvb1wiXG4gKiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKFwiYmF6XCIpXG4gKiAgLS0+IFwiYmF6XCJcbiAqIGBgYFxuICovIGV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKSB7XG4gICAgY29uc3QgW2V4dGVuc2lvbk5hbWVdID0gZXh0ZW5zaW9uSWQuc3BsaXQoJyMnKTtcbiAgICByZXR1cm4gZXh0ZW5zaW9uTmFtZTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25SZWdpc3RyYXRpb25Gcm9tKHN0YXRlLCBleHRlbnNpb25JZCkge1xuICAgIGNvbnN0IG5hbWUgPSBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGV4dGVuc2lvbklkKTtcbiAgICByZXR1cm4gc3RhdGUuZXh0ZW5zaW9uc1tuYW1lXTtcbn1cbmV4cG9ydCBmdW5jdGlvbiBnZXRFeHRlbnNpb25SZWdpc3RyYXRpb24oZXh0ZW5zaW9uSWQpIHtcbiAgICBjb25zdCBzdGF0ZSA9IGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICByZXR1cm4gZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbShzdGF0ZSwgZXh0ZW5zaW9uSWQpO1xufVxuLyoqXG4gKiBFeHRlbnNpb25zIG11c3QgYmUgcmVnaXN0ZXJlZCBpbiBvcmRlciB0byBiZSByZW5kZXJlZC5cbiAqIFRoaXMgaXMgaGFuZGxlZCBieSB0aGUgYXBwIHNoZWxsLCB3aGVuIGV4dGVuc2lvbnMgYXJlIHByb3ZpZGVkXG4gKiB2aWEgdGhlIGByb3V0ZXMuanNvbmAgZmlsZSBhbmQgcmVnaXN0ZXJlZCB0aHJvdWdoIGByZWdpc3RlckFwcCgpYC5cbiAqIEBpbnRlcm5hbFxuICovIGV4cG9ydCBjb25zdCByZWdpc3RlckV4dGVuc2lvbiA9IChleHRlbnNpb25SZWdpc3RyYXRpb24pPT51cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9Pih7XG4gICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgIGV4dGVuc2lvbnM6IHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZS5leHRlbnNpb25zLFxuICAgICAgICAgICAgICAgIFtleHRlbnNpb25SZWdpc3RyYXRpb24ubmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uZXh0ZW5zaW9uUmVnaXN0cmF0aW9uXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KSk7XG4vKipcbiAqIEF0dGFjaCBhbiBleHRlbnNpb24gdG8gYW4gZXh0ZW5zaW9uIHNsb3QuXG4gKlxuICogVGhpcyB3aWxsIGNhdXNlIHRoZSBleHRlbnNpb24gdG8gYmUgcmVuZGVyZWQgaW50byB0aGUgc3BlY2lmaWVkXG4gKiBleHRlbnNpb24gc2xvdCwgdW5sZXNzIGl0IGlzIHJlbW92ZWQgYnkgY29uZmlndXJhdGlvbi4gVXNpbmdcbiAqIGBhdHRhY2hgIGlzIGFuIGFsdGVybmF0aXZlIHRvIHNwZWNpZnlpbmcgdGhlIGBzbG90YCBvciBgc2xvdHNgXG4gKiBpbiB0aGUgZXh0ZW5zaW9uIGRlY2xhcmF0aW9uLlxuICpcbiAqIEl0IGlzIHBhcnRpY3VsYXJseSB1c2VmdWwgd2hlbiBjcmVhdGluZyBhIHNsb3QgaW50byB3aGljaFxuICogeW91IHdhbnQgdG8gcmVuZGVyIGFuIGV4aXN0aW5nIGV4dGVuc2lvbi4gVGhpcyBlbmFibGVzIHlvdVxuICogdG8gZG8gc28gd2l0aG91dCBtb2RpZnlpbmcgdGhlIGV4dGVuc2lvbidzIGRlY2xhcmF0aW9uLCB3aGljaFxuICogbWF5IGJlIGltcHJhY3RpY2FsIG9yIGluYXBwcm9wcmlhdGUsIGZvciBleGFtcGxlIGlmIHlvdSBhcmVcbiAqIHdyaXRpbmcgYSBtb2R1bGUgZm9yIGEgc3BlY2lmaWMgaW1wbGVtZW50YXRpb24uXG4gKlxuICogQHBhcmFtIHNsb3ROYW1lIGEgbmFtZSB1bmlxdWVseSBpZGVudGlmeWluZyB0aGUgc2xvdFxuICogQHBhcmFtIGV4dGVuc2lvbklkIGFuIGV4dGVuc2lvbiBuYW1lLCB3aXRoIGFuIG9wdGlvbmFsICMtc3VmZml4XG4gKiAgICB0byBkaXN0aW5ndWlzaCBpdCBmcm9tIG90aGVyIGluc3RhbmNlcyBvZiB0aGUgc2FtZSBleHRlbnNpb25cbiAqICAgIGF0dGFjaGVkIHRvIHRoZSBzYW1lIHNsb3QuXG4gKi8gZXhwb3J0IGZ1bmN0aW9uIGF0dGFjaChzbG90TmFtZSwgZXh0ZW5zaW9uSWQpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbc2xvdE5hbWVdO1xuICAgICAgICBpZiAoIWV4aXN0aW5nU2xvdCkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUpLFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleHRlbnNpb25JZFxuICAgICAgICAgICAgICAgICAgICAgICAgXVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uc3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgICAgIFtzbG90TmFtZV06IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmV4aXN0aW5nU2xvdCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaGVkSWRzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4dGVuc2lvbklkXG4gICAgICAgICAgICAgICAgICAgICAgICBdXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIERldGFjaGVzIGFuIGV4dGVuc2lvbiBmcm9tIGFuIGV4dGVuc2lvbiBzbG90LlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25TbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3QgdG8gZGV0YWNoIGZyb20uXG4gKiBAcGFyYW0gZXh0ZW5zaW9uSWQgVGhlIElEIG9mIHRoZSBleHRlbnNpb24gdG8gZGV0YWNoLlxuICpcbiAqIEBkZXByZWNhdGVkIEF2b2lkIHVzaW5nIHRoaXMuIEV4dGVuc2lvbiBhdHRhY2htZW50cyBzaG91bGQgYmUgY29uc2lkZXJlZCBkZWNsYXJhdGl2ZS5cbiAqLyBleHBvcnQgZnVuY3Rpb24gZGV0YWNoKGV4dGVuc2lvblNsb3ROYW1lLCBleHRlbnNpb25JZCkge1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKHN0YXRlKT0+e1xuICAgICAgICBjb25zdCBleGlzdGluZ1Nsb3QgPSBzdGF0ZS5zbG90c1tleHRlbnNpb25TbG90TmFtZV07XG4gICAgICAgIGlmIChleGlzdGluZ1Nsb3QgJiYgZXhpc3RpbmdTbG90LmF0dGFjaGVkSWRzLmluY2x1ZGVzKGV4dGVuc2lvbklkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5zdGF0ZSxcbiAgICAgICAgICAgICAgICBzbG90czoge1xuICAgICAgICAgICAgICAgICAgICAuLi5zdGF0ZS5zbG90cyxcbiAgICAgICAgICAgICAgICAgICAgW2V4dGVuc2lvblNsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAgICAgLi4uZXhpc3RpbmdTbG90LFxuICAgICAgICAgICAgICAgICAgICAgICAgYXR0YWNoZWRJZHM6IGV4aXN0aW5nU2xvdC5hdHRhY2hlZElkcy5maWx0ZXIoKGlkKT0+aWQgIT09IGV4dGVuc2lvbklkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBzdGF0ZTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuLyoqXG4gKiBEZXRhY2hlcyBhbGwgZXh0ZW5zaW9ucyBmcm9tIGFuIGV4dGVuc2lvbiBzbG90LlxuICpcbiAqIEBwYXJhbSBleHRlbnNpb25TbG90TmFtZSBUaGUgbmFtZSBvZiB0aGUgZXh0ZW5zaW9uIHNsb3QgdG8gY2xlYXIuXG4gKlxuICogQGRlcHJlY2F0ZWQgQXZvaWQgdXNpbmcgdGhpcy4gRXh0ZW5zaW9uIGF0dGFjaG1lbnRzIHNob3VsZCBiZSBjb25zaWRlcmVkIGRlY2xhcmF0aXZlLlxuICovIGV4cG9ydCBmdW5jdGlvbiBkZXRhY2hBbGwoZXh0ZW5zaW9uU2xvdE5hbWUpIHtcbiAgICB1cGRhdGVJbnRlcm5hbEV4dGVuc2lvblN0b3JlKChzdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdTbG90ID0gc3RhdGUuc2xvdHNbZXh0ZW5zaW9uU2xvdE5hbWVdO1xuICAgICAgICBpZiAoZXhpc3RpbmdTbG90KSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIC4uLnN0YXRlLFxuICAgICAgICAgICAgICAgIHNsb3RzOiB7XG4gICAgICAgICAgICAgICAgICAgIC4uLnN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbZXh0ZW5zaW9uU2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5leGlzdGluZ1Nsb3QsXG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2hlZElkczogW11cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gc3RhdGU7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbi8qKiBNYXBzIGVhY2ggSUQgdG8gdGhlIGluZGV4IG9mIGl0cyBmaXJzdCBvY2N1cnJlbmNlLCBtYXRjaGluZyBgQXJyYXkucHJvdG90eXBlLmluZGV4T2ZgLiAqLyBmdW5jdGlvbiBpbmRleEJ5SWQoaWRzKSB7XG4gICAgY29uc3QgaW5kZXggPSBuZXcgTWFwKCk7XG4gICAgaWRzLmZvckVhY2goKGlkLCBpKT0+e1xuICAgICAgICBpZiAoIWluZGV4LmhhcyhpZCkpIHtcbiAgICAgICAgICAgIGluZGV4LnNldChpZCwgaSk7XG4gICAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaW5kZXg7XG59XG4vKipcbiAqIEdldCBhbiBvcmRlciBpbmRleCBmb3IgdGhlIGV4dGVuc2lvbi4gVGhpcyB3aWxsXG4gKiBjb21lIGZyb20gZWl0aGVyIGl0cyBjb25maWd1cmVkIG9yZGVyLCBpdHMgcmVnaXN0ZXJlZCBvcmRlclxuICogcGFyYW1ldGVyLCBvciB0aGUgb3JkZXIgaW4gd2hpY2ggaXQgaGFwcGVuZWQgdG8gYmUgYXR0YWNoZWQuXG4gKlxuICogVGhlIGZvdXIgYmFuZHMgYmVsb3cga2VlcCB0aGUgY29tcGFyaXNvbiBhIHRvdGFsIG9yZGVyOiBldmVyeSBleHRlbnNpb24gbGFuZHMgaW4gZXhhY3RseSBvbmUsIGFuZFxuICogdGhvc2Ugd2l0aCBubyBvcmRlcmluZyBpbmZvcm1hdGlvbiBzaGFyZSB0aGUgbGFzdCBiYW5kIHJhdGhlciB0aGFuIHRha2luZyBhIHNlbnRpbmVsIHRoYXQgY2FuJ3QgYmVcbiAqIGNvbXBhcmVkIGFnYWluc3QgaXRzZWxmLlxuICovIGZ1bmN0aW9uIGdldE9yZGVyKGV4dGVuc2lvbklkLCBjb25maWd1cmVkT3JkZXIsIHJlZ2lzdGVyZWRPcmRlckluZGV4LCBhdHRhY2hlZE9yZGVyKSB7XG4gICAgY29uc3QgY29uZmlndXJlZEluZGV4ID0gY29uZmlndXJlZE9yZGVyLmdldChleHRlbnNpb25JZCk7XG4gICAgaWYgKGNvbmZpZ3VyZWRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBjb25maWd1cmVkSW5kZXg7XG4gICAgfSBlbHNlIGlmIChyZWdpc3RlcmVkT3JkZXJJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIC8vIGV4dGVuc2lvbnMgdGhhdCBkb24ndCBoYXZlIGEgY29uZmlndXJlZCBvcmRlciBzaG91bGQgYXBwZWFyIGFmdGVyIHRob3NlIHRoYXQgZG9cbiAgICAgICAgcmV0dXJuIDEwMDAgKyByZWdpc3RlcmVkT3JkZXJJbmRleDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBhc3NpZ25lZEluZGV4ID0gYXR0YWNoZWRPcmRlci5nZXQoZXh0ZW5zaW9uSWQpO1xuICAgICAgICBpZiAoYXNzaWduZWRJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAvLyBleHRlbnNpb25zIHRoYXQgaGF2ZSBuZWl0aGVyIGEgY29uZmlndXJlZCBub3IgcmVnaXN0ZXJlZCBvcmRlciBzaG91bGQgYXBwZWFyXG4gICAgICAgICAgICAvLyBhZnRlciBhbGwgb3RoZXJzXG4gICAgICAgICAgICByZXR1cm4gMjAwMCArIGFzc2lnbmVkSW5kZXg7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBBZGRlZCBieSBjb25maWd1cmF0aW9uIHdpdGggbm8gb3JkZXIgb2YgYW55IGtpbmQg4oCUIGFmdGVyIGV2ZXJ5dGhpbmcgZWxzZSwgYW5kIGFtb25nXG4gICAgICAgICAgICAvLyB0aGVtc2VsdmVzIGluIHRoZSBvcmRlciB0aGUgY29uZmlndXJhdGlvbiBsaXN0cyB0aGVtLlxuICAgICAgICAgICAgcmV0dXJuIDMwMDA7XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBnZXRBc3NpZ25lZEV4dGVuc2lvbnNGcm9tU2xvdERhdGEoc2xvdE5hbWUsIGludGVybmFsU3RhdGUsIGNvbmZpZywgZXh0ZW5zaW9uQ29uZmlnU3RvcmVTdGF0ZSwgZW5hYmxlZEZlYXR1cmVGbGFncywgc2Vzc2lvbikge1xuICAgIGNvbnN0IGF0dGFjaGVkSWRzID0gaW50ZXJuYWxTdGF0ZS5zbG90c1tzbG90TmFtZV0uYXR0YWNoZWRJZHM7XG4gICAgY29uc3QgYXNzaWduZWRJZHMgPSBjYWxjdWxhdGVBc3NpZ25lZElkcyhjb25maWcsIGF0dGFjaGVkSWRzKTtcbiAgICBjb25zdCBleHRlbnNpb25zID0gW107XG4gICAgZm9yIChsZXQgaWQgb2YgYXNzaWduZWRJZHMpe1xuICAgICAgICBjb25zdCB7IGNvbmZpZzogcmF3RXh0ZW5zaW9uQ29uZmlnIH0gPSBnZXRFeHRlbnNpb25Db25maWdGcm9tU3RvcmUoZXh0ZW5zaW9uQ29uZmlnU3RvcmVTdGF0ZSwgc2xvdE5hbWUsIGlkKTtcbiAgICAgICAgY29uc3QgcmF3RXh0ZW5zaW9uU2xvdEV4dGVuc2lvbkNvbmZpZyA9IGdldEV4dGVuc2lvbkNvbmZpZ0Zyb21FeHRlbnNpb25TbG90U3RvcmUoY29uZmlnLCBzbG90TmFtZSwgaWQpO1xuICAgICAgICAvLyBgbWVyZ2VgIG11dGF0ZXMgaXRzIGZpcnN0IGFyZ3VtZW50LCBhbmQgYHJhd0V4dGVuc2lvbkNvbmZpZ2AgYmVsb25ncyB0byB0aGUgY29uZmlnIHN0b3JlLFxuICAgICAgICAvLyBzbyBuZXZlciBtZXJnZSBpbnRvIGl0LlxuICAgICAgICBjb25zdCBleHRlbnNpb25Db25maWcgPSByYXdFeHRlbnNpb25TbG90RXh0ZW5zaW9uQ29uZmlnID8gbWVyZ2Uoe30sIHJhd0V4dGVuc2lvbkNvbmZpZywgcmF3RXh0ZW5zaW9uU2xvdEV4dGVuc2lvbkNvbmZpZykgOiByYXdFeHRlbnNpb25Db25maWc7XG4gICAgICAgIGNvbnN0IG5hbWUgPSBnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGlkKTtcbiAgICAgICAgY29uc3QgZXh0ZW5zaW9uID0gaW50ZXJuYWxTdGF0ZS5leHRlbnNpb25zW25hbWVdO1xuICAgICAgICAvLyBpZiB0aGUgZXh0ZW5zaW9uIGhhcyBub3QgYmVlbiByZWdpc3RlcmVkIHlldCwgZG8gbm90IGluY2x1ZGUgaXRcbiAgICAgICAgaWYgKGV4dGVuc2lvbikge1xuICAgICAgICAgICAgY29uc3QgcmVxdWlyZWRQcml2aWxlZ2VzID0gZXh0ZW5zaW9uQ29uZmlnPy5bJ0Rpc3BsYXkgY29uZGl0aW9ucyddPy5wcml2aWxlZ2VzID8/IGV4dGVuc2lvbi5wcml2aWxlZ2VzID8/IFtdO1xuICAgICAgICAgICAgaWYgKHJlcXVpcmVkUHJpdmlsZWdlcyAmJiAodHlwZW9mIHJlcXVpcmVkUHJpdmlsZWdlcyA9PT0gJ3N0cmluZycgfHwgQXJyYXkuaXNBcnJheShyZXF1aXJlZFByaXZpbGVnZXMpICYmIHJlcXVpcmVkUHJpdmlsZWdlcy5sZW5ndGggPiAwKSkge1xuICAgICAgICAgICAgICAgIGlmICghc2Vzc2lvbj8udXNlcikge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCF1c2VySGFzQWNjZXNzKHJlcXVpcmVkUHJpdmlsZWdlcywgc2Vzc2lvbi51c2VyKSkge1xuICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoZXh0ZW5zaW9uLmZlYXR1cmVGbGFnICYmICFlbmFibGVkRmVhdHVyZUZsYWdzLmluY2x1ZGVzKGV4dGVuc2lvbi5mZWF0dXJlRmxhZykpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGV4dGVuc2lvbnMucHVzaCh7XG4gICAgICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICAgICAgbmFtZSxcbiAgICAgICAgICAgICAgICBtb2R1bGVOYW1lOiBleHRlbnNpb24ubW9kdWxlTmFtZSxcbiAgICAgICAgICAgICAgICBjb25maWc6IGV4dGVuc2lvbkNvbmZpZyxcbiAgICAgICAgICAgICAgICBmZWF0dXJlRmxhZzogZXh0ZW5zaW9uLmZlYXR1cmVGbGFnLFxuICAgICAgICAgICAgICAgIG1ldGE6IGV4dGVuc2lvbi5tZXRhLFxuICAgICAgICAgICAgICAgIGRpc3BsYXlDb25kaXRpb25FeHByZXNzaW9uOiBleHRlbnNpb25Db25maWc/LlsnRGlzcGxheSBjb25kaXRpb25zJ10/LmV4cHJlc3Npb24gfHwgZXh0ZW5zaW9uLmRpc3BsYXlFeHByZXNzaW9uXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZXh0ZW5zaW9ucztcbn1cbi8qKlxuICogTmFycm93cyBgZXh0ZW5zaW9uc2AgdG8gdGhvc2Ugd2hvc2UgZGlzcGxheSBjb25kaXRpb24gaG9sZHMgZm9yIG9uZSBwYXJ0aWN1bGFyIHJlbmRlcmluZyBvZiBhXG4gKiBzbG90LCBldmFsdWF0aW5nIGVhY2ggY29uZGl0aW9uIGFnYWluc3QgYHN0YXRlYC5cbiAqXG4gKiBBbiBleHRlbnNpb24gd2hvc2UgZGlzcGxheSBjb25kaXRpb24gdGhyb3dzIGlzIGxlZnQgb3V0LCBvbiB0aGUgZ3JvdW5kcyB0aGF0IGEgY29uZGl0aW9uIHRoYXQgY2Fubm90IGJlXG4gKiBldmFsdWF0ZWQgaGFzIG5vdCBiZWVuIG1ldC5cbiAqXG4gKiBAcGFyYW0gZXh0ZW5zaW9ucyBUaGUgZXh0ZW5zaW9ucyBhc3NpZ25lZCB0byB0aGUgc2xvdCwgYXMgdGhlIGV4dGVuc2lvbiBzdG9yZSBob2xkcyB0aGVtXG4gKiBAcGFyYW0gc3RhdGUgVGhlIHN0YXRlIG9mIHRoaXMgcmVuZGVyaW5nIG9mIHRoZSBzbG90XG4gKiBAcGFyYW0gc2Vzc2lvbiBUaGUgY3VycmVudCBzZXNzaW9uLCB3aGljaCBjb25kaXRpb25zIG1heSByZWZlciB0byBhcyBgc2Vzc2lvbmBcbiAqIEBwYXJhbSBzbG90TmFtZSBUaGUgc2xvdCB0aGVzZSB3ZXJlIGFzc2lnbmVkIHRvLCB1c2VkIG9ubHkgdG8gaWRlbnRpZnkgdGhlbSBpZiBhIGNvbmRpdGlvbiB0aHJvd3NcbiAqIEByZXR1cm5zIFRob3NlIG9mIGBleHRlbnNpb25zYCB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQsIGluIHRoZSBzYW1lIG9yZGVyLiBBbHdheXMgYSBuZXcgYXJyYXkuXG4gKi8gZnVuY3Rpb24gZmlsdGVyRXh0ZW5zaW9uc0J5RGlzcGxheUNvbmRpdGlvbnMoZXh0ZW5zaW9ucywgc3RhdGUsIHNlc3Npb24gPSBudWxsLCBzbG90TmFtZSkge1xuICAgIC8vIEJ1aWx0IG9uY2UgZm9yIHRoZSB3aG9sZSBzbG90IHJhdGhlciB0aGFuIHBlciBleHRlbnNpb246IHRoZSBjb250ZXh0IGlzIHRoZSBzYW1lIGZvciBhbGwgb2ZcbiAgICAvLyB0aGVtLCBhbmQgbW9zdCBzbG90cyBoYXZlIG5vIGNvbmRpdGlvbnMgYXQgYWxsLlxuICAgIGxldCBleHByZXNzaW9uQ29udGV4dDtcbiAgICByZXR1cm4gZXh0ZW5zaW9ucy5maWx0ZXIoKGV4dGVuc2lvbik9PntcbiAgICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IGV4dGVuc2lvbi5kaXNwbGF5Q29uZGl0aW9uRXhwcmVzc2lvbjtcbiAgICAgICAgaWYgKHR5cGVvZiBleHByZXNzaW9uICE9PSAnc3RyaW5nJyB8fCBleHByZXNzaW9uLnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGV4cHJlc3Npb25Db250ZXh0ID8/IChleHByZXNzaW9uQ29udGV4dCA9IHN0YXRlICYmIHR5cGVvZiBzdGF0ZSA9PT0gJ29iamVjdCcgPyB7XG4gICAgICAgICAgICBzZXNzaW9uLFxuICAgICAgICAgICAgLi4uc3RhdGVcbiAgICAgICAgfSA6IHtcbiAgICAgICAgICAgIHNlc3Npb25cbiAgICAgICAgfSk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gQm9vbGVhbihldmFsdWF0ZUFzQm9vbGVhbihleHByZXNzaW9uLCBleHByZXNzaW9uQ29udGV4dCkpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciB3aGlsZSBldmFsdWF0aW5nIGV4cHJlc3Npb24gJyR7ZXhwcmVzc2lvbn0nIGZvciAke2V4dGVuc2lvbi5pZH1gICsgKHNsb3ROYW1lID8gYCBpbiAke3Nsb3ROYW1lfWAgOiAnJyksIGUpO1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSk7XG59XG4vKipcbiAqIEdldHMgdGhlIGV4dGVuc2lvbnMgYSBnaXZlbiByZW5kZXJpbmcgb2YgYSBzbG90IHNob3VsZCBkaXNwbGF5LCBpbiBvcmRlci4gVGhpcyBpcyB0aGUgc3VwcG9ydGVkXG4gKiB3YXkgdG8gYXNrIHdoYXQgYmVsb25ncyBpbiBhIHNsb3Q7IHJlYWRpbmcgdGhlIGV4dGVuc2lvbiBzdG9yZSBkaXJlY3RseSBza2lwcyBkaXNwbGF5IGNvbmRpdGlvbnMuXG4gKlxuICogRGlzcGxheSBjb25kaXRpb25zIGFyZSBldmFsdWF0ZWQgYWdhaW5zdCBgc3RhdGVgLCBzbyBwYXNzIHdoYXRldmVyIHRoZSBzbG90IGlzIGJlaW5nIHJlbmRlcmVkXG4gKiBmb3IuIFRoZSBzYW1lIHNsb3QgY2FuIGJlIHJlbmRlcmVkIG1hbnkgdGltZXMgd2l0aCBkaWZmZXJlbnQgc3RhdGUg4oCUIG9uY2UgcGVyIHJvdyBvZiBhIHRhYmxlLFxuICogc2F5IOKAlCBhbmQgZWFjaCByZW5kZXJpbmcgY2FuIHJlc29sdmUgdG8gYSBkaWZmZXJlbnQgc2V0IG9mIGV4dGVuc2lvbnMuIE9taXR0aW5nIGBzdGF0ZWAgaGlkZXNcbiAqIGV2ZXJ5IGV4dGVuc2lvbiB3aG9zZSBjb25kaXRpb24gcmVmZXJzIHRvIGl0LCBzaW5jZSB0aGUgY29uZGl0aW9uIGNhbm5vdCBiZSBldmFsdWF0ZWQuXG4gKlxuICogQHBhcmFtIHNsb3ROYW1lIFRoZSBzbG90IHRvIGxvYWQgdGhlIGV4dGVuc2lvbnMgZm9yXG4gKiBAcGFyYW0gc3RhdGUgVGhlIHN0YXRlIG9mIHRoZSByZW5kZXJpbmcgb2YgdGhlIHNsb3QgdGhlIGV4dGVuc2lvbnMgd2lsbCBiZSBkaXNwbGF5ZWQgaW5cbiAqIEByZXR1cm5zIFRob3NlIGV4dGVuc2lvbnMgYXNzaWduZWQgdG8gdGhlIHNsb3Qgd2hvc2UgZGlzcGxheSBjb25kaXRpb25zIGhvbGRcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0QXNzaWduZWRFeHRlbnNpb25zKHNsb3ROYW1lLCBzdGF0ZSkge1xuICAgIHJldHVybiBmaWx0ZXJFeHRlbnNpb25zQnlEaXNwbGF5Q29uZGl0aW9ucyhnZXRDYW5kaWRhdGVFeHRlbnNpb25zKHNsb3ROYW1lKSwgc3RhdGUsIHNlc3Npb25TdG9yZS5nZXRTdGF0ZSgpLnNlc3Npb24sIHNsb3ROYW1lKTtcbn1cbi8qKlxuICogR2V0cyBldmVyeXRoaW5nIGFzc2lnbmVkIHRvIGEgc2xvdCB3aXRob3V0IGV2YWx1YXRpbmcgYW55IGRpc3BsYXkgY29uZGl0aW9uLCB3aGljaFxuICoge0BsaW5rIGdldEFzc2lnbmVkRXh0ZW5zaW9uc30gY2Fubm90IGRvIHdpdGhvdXQga25vd2luZyB0aGUgc3RhdGUgb2YgYSBwYXJ0aWN1bGFyIHJlbmRlcmluZy5cbiAqXG4gKiBUaGlzIGV4aXN0cyBmb3IgdG9vbHMgdGhhdCBwcmVzZW50IGEgc2xvdCdzIGNvbmZpZ3VyYXRpb24gcmF0aGVyIHRoYW4gcmVuZGVyIGl0IOKAlCB0aGUgVUkgZWRpdG9yXG4gKiBoYXMgdG8gbGlzdCBhbiBleHRlbnNpb24gaW4gb3JkZXIgdG8gbGV0IGFuIGltcGxlbWVudGVyIHJlb3JkZXIgb3IgcmVtb3ZlIGl0LCBldmVuIHdoZXJlIG5vXG4gKiByZW5kZXJpbmcgd291bGQgZGlzcGxheSBpdC4gQW55dGhpbmcgZGVjaWRpbmcgd2hhdCB0byByZW5kZXIgd2FudHMgYGdldEFzc2lnbmVkRXh0ZW5zaW9ucygpYC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqLyBleHBvcnQgZnVuY3Rpb24gZ2V0Q2FuZGlkYXRlRXh0ZW5zaW9ucyhzbG90TmFtZSkge1xuICAgIHJldHVybiBleHRlbnNpb25TdG9yZS5nZXRTdGF0ZSgpLnNsb3RzW3Nsb3ROYW1lXT8uY2FuZGlkYXRlRXh0ZW5zaW9ucyA/PyBbXTtcbn1cbmZ1bmN0aW9uIGNhbGN1bGF0ZUFzc2lnbmVkSWRzKGNvbmZpZywgYXR0YWNoZWRJZHMpIHtcbiAgICBjb25zdCBhZGRlZElkcyA9IGNvbmZpZy5hZGQgfHwgW107XG4gICAgY29uc3QgcmVtb3ZlZElkcyA9IGNvbmZpZy5yZW1vdmUgfHwgW107XG4gICAgY29uc3QgaWRPcmRlciA9IGNvbmZpZy5vcmRlciB8fCBbXTtcbiAgICBjb25zdCB7IGV4dGVuc2lvbnMgfSA9IGV4dGVuc2lvbkludGVybmFsU3RvcmUuZ2V0U3RhdGUoKTtcbiAgICBjb25zdCByZW1vdmVkID0gbmV3IFNldChyZW1vdmVkSWRzKTtcbiAgICBjb25zdCBpZHMgPSBbXG4gICAgICAgIC4uLmF0dGFjaGVkSWRzLFxuICAgICAgICAuLi5hZGRlZElkc1xuICAgIF0uZmlsdGVyKChpZCk9PiFyZW1vdmVkLmhhcyhpZCkpO1xuICAgIGNvbnN0IGNvbmZpZ3VyZWRJbmRleCA9IGluZGV4QnlJZChpZE9yZGVyKTtcbiAgICBjb25zdCBhdHRhY2hlZEluZGV4ID0gaW5kZXhCeUlkKGF0dGFjaGVkSWRzKTtcbiAgICAvLyBDb21wdXRlZCBvbmNlIHBlciBJRDogY2FsbGluZyBgZ2V0T3JkZXJgIGZyb20gdGhlIGNvbXBhcmF0b3IgbWFrZXMgdGhlIHNvcnQgcXVhZHJhdGljLlxuICAgIGNvbnN0IG9yZGVyID0gbmV3IE1hcChpZHMubWFwKChpZCk9PltcbiAgICAgICAgICAgIGlkLFxuICAgICAgICAgICAgZ2V0T3JkZXIoaWQsIGNvbmZpZ3VyZWRJbmRleCwgZXh0ZW5zaW9uc1tnZXRFeHRlbnNpb25OYW1lRnJvbUlkKGlkKV0/Lm9yZGVyLCBhdHRhY2hlZEluZGV4KVxuICAgICAgICBdKSk7XG4gICAgLy8gVGllcyBrZWVwIHRoZWlyIGlucHV0IG9yZGVyIOKAlCBgQXJyYXkucHJvdG90eXBlLnNvcnRgIGlzIHN0YWJsZSwgYW5kIHRoZSBpbnB1dCBpc1xuICAgIC8vIGBbLi4uYXR0YWNoZWRJZHMsIC4uLmFkZGVkSWRzXWAsIHNvIHR3byBleHRlbnNpb25zIHRoZSBvcmRlcmluZyBydWxlcyBjYW4ndCBzZXBhcmF0ZVxuICAgIC8vIGNvbWUgb3V0IGluIHRoZSBvcmRlciB0aGUgY29kZSBhbmQgdGhlIGNvbmZpZ3VyYXRpb24gZGVjbGFyZWQgdGhlbS5cbiAgICByZXR1cm4gaWRzLnNvcnQoKGlkQSwgaWRCKT0+b3JkZXIuZ2V0KGlkQSkgLSBvcmRlci5nZXQoaWRCKSk7XG59XG4vKipcbiAqIFVzZWQgYnkgYnkgZXh0ZW5zaW9uIHNsb3RzIGF0IG1vdW50IHRpbWUuXG4gKlxuICogQHBhcmFtIG1vZHVsZU5hbWUgVGhlIG5hbWUgb2YgdGhlIG1vZHVsZSB0aGF0IGNvbnRhaW5zIHRoZSBleHRlbnNpb24gc2xvdFxuICogQHBhcmFtIHNsb3ROYW1lIFRoZSBleHRlbnNpb24gc2xvdCBuYW1lIHRoYXQgaXMgYWN0dWFsbHkgdXNlZFxuICogQGludGVybmFsXG4gKi8gZXhwb3J0IGNvbnN0IHJlZ2lzdGVyRXh0ZW5zaW9uU2xvdCA9IChtb2R1bGVOYW1lLCBzbG90TmFtZSk9PmV4dGVuc2lvbkludGVybmFsU3RvcmUuc2V0U3RhdGUoKGN1cnJlbnRTdGF0ZSk9PntcbiAgICAgICAgY29uc3QgZXhpc3RpbmdNb2R1bGVOYW1lID0gY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXT8ubW9kdWxlTmFtZTtcbiAgICAgICAgaWYgKGV4aXN0aW5nTW9kdWxlTmFtZSAmJiBleGlzdGluZ01vZHVsZU5hbWUgIT0gbW9kdWxlTmFtZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBBbiBleHRlbnNpb24gc2xvdCB3aXRoIHRoZSBuYW1lICcke3Nsb3ROYW1lfScgYWxyZWFkeSBleGlzdHMuIFJlZnVzaW5nIHRvIHJlZ2lzdGVyIHRoZSBzYW1lIHNsb3QgbmFtZSB0d2ljZSAoaW4gXCJyZWdpc3RlckV4dGVuc2lvblNsb3RcIikuIFRoZSBleGlzdGluZyBvbmUgaXMgZnJvbSBtb2R1bGUgJHtleGlzdGluZ01vZHVsZU5hbWV9LmApO1xuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXhpc3RpbmdNb2R1bGVOYW1lICYmIGV4aXN0aW5nTW9kdWxlTmFtZSA9PSBtb2R1bGVOYW1lKSB7XG4gICAgICAgICAgICAvLyBSZS1yZW5kZXJpbmcgYW4gZXhpc3Rpbmcgc2xvdFxuICAgICAgICAgICAgcmV0dXJuIGN1cnJlbnRTdGF0ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY3VycmVudFN0YXRlLnNsb3RzW3Nsb3ROYW1lXSkge1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUsXG4gICAgICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLnNsb3RzLFxuICAgICAgICAgICAgICAgICAgICBbc2xvdE5hbWVdOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHNbc2xvdE5hbWVdLFxuICAgICAgICAgICAgICAgICAgICAgICAgbW9kdWxlTmFtZVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBzbG90ID0gY3JlYXRlTmV3RXh0ZW5zaW9uU2xvdEluZm8oc2xvdE5hbWUsIG1vZHVsZU5hbWUpO1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgLi4uY3VycmVudFN0YXRlLFxuICAgICAgICAgICAgc2xvdHM6IHtcbiAgICAgICAgICAgICAgICAuLi5jdXJyZW50U3RhdGUuc2xvdHMsXG4gICAgICAgICAgICAgICAgW3Nsb3ROYW1lXToge1xuICAgICAgICAgICAgICAgICAgICAuLi5zbG90XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH0pO1xuLyoqXG4gKiBAaW50ZXJuYWxcbiAqIEp1c3QgZm9yIHRlc3RpbmcuXG4gKi8gZXhwb3J0IGNvbnN0IHJlc2V0ID0gKCk9PntcbiAgICAvLyBJbnZhbGlkYXRpb24gaXMgY2FycmllZCBpbiBtb2R1bGUgc3RhdGUsIHNvIGl0IGhhcyB0byBiZSByZXNldCB0b28gb3IgaXQgYmxlZWRzIGludG8gdGhlXG4gICAgLy8gbmV4dCB0ZXN0IGFzIGVpdGhlciBhIHN0YWxlIGRpcnR5IHNldCBvciBhIG1pc3Npbmcgb25lLlxuICAgIGRpcnR5U2xvdHMgPSBudWxsO1xuICAgIHVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUoKCk9Pih7XG4gICAgICAgICAgICBzbG90czoge30sXG4gICAgICAgICAgICBleHRlbnNpb25zOiB7fVxuICAgICAgICB9KSk7XG4gICAgZ2V0RXh0ZW5zaW9uUmVuZGVyaW5nc1N0b3JlKCkuc2V0U3RhdGUoe1xuICAgICAgICByZW5kZXJpbmdzOiBuZXcgTWFwKClcbiAgICB9KTtcbiAgICBleHRlbnNpb25TdG9yZS5zZXRTdGF0ZSh7XG4gICAgICAgIHNsb3RzOiB7fVxuICAgIH0pO1xufTtcbiJdLCJuYW1lcyI6WyJzZXNzaW9uU3RvcmUiLCJ1c2VySGFzQWNjZXNzIiwiZ2V0RXh0ZW5zaW9uQ29uZmlnRnJvbUV4dGVuc2lvblNsb3RTdG9yZSIsImdldEV4dGVuc2lvbkNvbmZpZ0Zyb21TdG9yZSIsImdldEV4dGVuc2lvblNsb3RDb25maWdGcm9tU3RvcmUiLCJnZXRFeHRlbnNpb25TbG90c0NvbmZpZ1N0b3JlIiwiZ2V0RXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiZXZhbHVhdGVBc0Jvb2xlYW4iLCJmZWF0dXJlRmxhZ3NTdG9yZSIsImlzRXF1YWwiLCJtZXJnZSIsImdldEV4dGVuc2lvblJlbmRlcmluZ3NTdG9yZSIsImdldEV4dGVuc2lvbkludGVybmFsU3RvcmUiLCJnZXRFeHRlbnNpb25TdG9yZSIsInNjaGVkdWxlUmVjb21wdXRhdGlvbiIsInVwZGF0ZUludGVybmFsRXh0ZW5zaW9uU3RvcmUiLCJleHRlbnNpb25JbnRlcm5hbFN0b3JlIiwiZXh0ZW5zaW9uU3RvcmUiLCJzbG90c0NvbmZpZ1N0b3JlIiwiZXh0ZW5zaW9uc0NvbmZpZ1N0b3JlIiwiZGlydHlTbG90cyIsIlNldCIsImlzUmVjb21wdXRpbmdPdXRwdXRTdG9yZSIsIm1hcmtTbG90c0RpcnR5Iiwic2xvdHMiLCJzbG90TmFtZSIsInJlY29tcHV0ZUV4dGVuc2lvbk91dHB1dFN0b3JlIiwibWF4UmVjb21wdXRhdGlvblBhc3NlcyIsInBhc3MiLCJ1cGRhdGVFeHRlbnNpb25PdXRwdXRTdG9yZSIsImUiLCJjb25zb2xlIiwiaW50ZXJuYWxTdGF0ZSIsImV4dGVuc2lvblNsb3RDb25maWdzIiwiZXh0ZW5zaW9uc0NvbmZpZ1N0YXRlIiwiZmVhdHVyZUZsYWdTdGF0ZSIsInNlc3Npb25TdGF0ZSIsImRpcnR5U2xvdE5hbWVzIiwicHJldmlvdXNTbG90cyIsImNoYW5nZWQiLCJlbmFibGVkRmVhdHVyZUZsYWdzIiwiT2JqZWN0IiwiZW5hYmxlZCIsIm5hbWUiLCJzbG90IiwicHJldmlvdXMiLCJjb25maWciLCJjYW5kaWRhdGVFeHRlbnNpb25zIiwiZ2V0QXNzaWduZWRFeHRlbnNpb25zRnJvbVNsb3REYXRhIiwiY2hhbmdlZEtleXMiLCJuZXh0Iiwia2V5Iiwic3RhdGUiLCJwcmV2aW91c1N0YXRlIiwidXBkYXRlT3V0cHV0U3RvcmVUb0N1cnJlbnQiLCJjcmVhdGVOZXdFeHRlbnNpb25TbG90SW5mbyIsIm1vZHVsZU5hbWUiLCJnZXRFeHRlbnNpb25OYW1lRnJvbUlkIiwiZXh0ZW5zaW9uSWQiLCJleHRlbnNpb25OYW1lIiwiZ2V0RXh0ZW5zaW9uUmVnaXN0cmF0aW9uRnJvbSIsImdldEV4dGVuc2lvblJlZ2lzdHJhdGlvbiIsInJlZ2lzdGVyRXh0ZW5zaW9uIiwiZXh0ZW5zaW9uUmVnaXN0cmF0aW9uIiwiYXR0YWNoIiwiZXhpc3RpbmdTbG90IiwiZGV0YWNoIiwiZXh0ZW5zaW9uU2xvdE5hbWUiLCJpZCIsImRldGFjaEFsbCIsImluZGV4QnlJZCIsImlkcyIsImluZGV4IiwiTWFwIiwiaSIsImdldE9yZGVyIiwiY29uZmlndXJlZE9yZGVyIiwicmVnaXN0ZXJlZE9yZGVySW5kZXgiLCJhdHRhY2hlZE9yZGVyIiwiY29uZmlndXJlZEluZGV4IiwidW5kZWZpbmVkIiwiYXNzaWduZWRJbmRleCIsImV4dGVuc2lvbkNvbmZpZ1N0b3JlU3RhdGUiLCJzZXNzaW9uIiwiYXR0YWNoZWRJZHMiLCJhc3NpZ25lZElkcyIsImNhbGN1bGF0ZUFzc2lnbmVkSWRzIiwiZXh0ZW5zaW9ucyIsInJhd0V4dGVuc2lvbkNvbmZpZyIsInJhd0V4dGVuc2lvblNsb3RFeHRlbnNpb25Db25maWciLCJleHRlbnNpb25Db25maWciLCJleHRlbnNpb24iLCJyZXF1aXJlZFByaXZpbGVnZXMiLCJBcnJheSIsImZpbHRlckV4dGVuc2lvbnNCeURpc3BsYXlDb25kaXRpb25zIiwiZXhwcmVzc2lvbkNvbnRleHQiLCJleHByZXNzaW9uIiwiQm9vbGVhbiIsImdldEFzc2lnbmVkRXh0ZW5zaW9ucyIsImdldENhbmRpZGF0ZUV4dGVuc2lvbnMiLCJhZGRlZElkcyIsInJlbW92ZWRJZHMiLCJpZE9yZGVyIiwicmVtb3ZlZCIsImF0dGFjaGVkSW5kZXgiLCJvcmRlciIsImlkQSIsImlkQiIsInJlZ2lzdGVyRXh0ZW5zaW9uU2xvdCIsImN1cnJlbnRTdGF0ZSIsImV4aXN0aW5nTW9kdWxlTmFtZSIsInJlc2V0Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnQ0FBZ0MsR0FBRzs7Ozs7OztDQU9sQyxHQUFrRTtBQUNrSTtBQUMvSDtBQUNQO0FBQ3BCO0FB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\n//# sourceURL=webpack-internal:///../../framework/esm-extensions/dist/extensions.js\n\n}");
4700
4700
 
4701
4701
  },
4702
4702
  "../../framework/esm-extensions/dist/index.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
@@ -5126,7 +5126,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webp
5126
5126
  },
5127
5127
  "../../framework/esm-translations/dist/translations.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
5128
5128
  "use strict";
5129
- eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n coreTranslations: () => (coreTranslations)\n});\n/** Please keep these alphabetized */ const addressFields = {\n address1: 'Address line 1',\n address2: 'Address line 2',\n address3: 'Address line 3',\n address4: 'Address line 4',\n address5: 'Address line 5',\n address6: 'Address line 6',\n city: 'City',\n cityVillage: 'City',\n country: 'Country',\n countyDistrict: 'District',\n district: 'District',\n postalCode: 'Postal code',\n state: 'State',\n stateProvince: 'State'\n};\nconst workspaceTranslations = {\n closeAllOpenedWorkspaces: 'Discard changes in {{count}} workspaces',\n closingAllWorkspacesPromptBody: 'There may be unsaved changes in the following workspaces. Do you want to discard changes in the following workspaces? {{workspaceNames}}',\n closingAllWorkspacesPromptTitle: 'You have unsaved changes',\n discard: 'Discard',\n hide: 'Hide',\n maximize: 'Maximize',\n minimize: 'Minimize',\n openAnyway: 'Open anyway',\n unsavedChangesInOpenedWorkspace: 'You may have unsaved changes in the opened workspace. Do you want to discard these changes?',\n unsavedChangesInWorkspace: 'There may be unsaved changes in \"{{workspaceName}}\". Please save them before opening another workspace.',\n unsavedChangesTitleText: 'Unsaved changes',\n workspaceHeader: 'Workspace header'\n};\nconst workspace2Translations = {\n discardUnsavedChangesPromptBodyMultiple: '{{count}} workspaces have unsaved changes. Closing them will discard the changes:',\n discardUnsavedChangesPromptBodySingle: '<strong>{{workspaceTitle}}</strong> has unsaved changes. Closing it will discard them.',\n discardUnsavedChangesPromptTitle: 'Discard unsaved changes?',\n keepEditing: 'Keep editing'\n};\nconst coreTranslations = {\n ...addressFields,\n ...workspaceTranslations,\n ...workspace2Translations,\n abnormalValue: 'Abnormal value',\n actions: 'Actions',\n actionableNotification: 'Actionable notification',\n address: 'Address',\n age: 'Age',\n batchActionItemSelected: '{{totalSelected}} item selected',\n batchActionsItemsSelected: '{{totalSelected}} items selected',\n cancel: 'Cancel',\n change: 'Change',\n // Default value for the implementationName config property\n Clinic: 'Clinic',\n close: 'Close',\n closesActionableNotification: 'Close actionable notification',\n closeSnackbar: 'Close snackbar',\n confirm: 'Confirm',\n contactAdministratorIfIssuePersists: 'Contact your system administrator if the problem persists.',\n contactDetails: 'Contact details',\n delete: 'Delete',\n discardChanges: 'Discard changes',\n edit: 'Edit',\n emptyStateText: 'There are no {{displayText}} to display',\n error: 'Error',\n errorCopy: 'Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.',\n errorLoadingLoginLocations: 'Unable to load login locations. Please try again or contact support if the problem persists.',\n female: 'Female',\n leftNavigation: 'Left navigation',\n loading: 'Loading',\n localVersion: 'Local Build',\n male: 'Male',\n navigateNonHttp: 'Could not navigate to the requested page as it is not a safe URL',\n noResultsToDisplay: 'No results to display',\n notAvailable: 'Not available',\n other: 'Other',\n paginationItemsCount: '{{pageItemsCount}} / {{totalItems}} items',\n paginationOfPages: 'of {{count}} pages',\n patientAvatarAlt: 'Avatar for {{patientName}}',\n patientIdentifierSticker: 'Patient identifier sticker',\n patientLists: 'Patient lists',\n patientPhotoAlt: 'Profile photo of {{patientName}}',\n patientPhotoPlaceholder: 'Photo placeholder for {{patientName}}',\n prereleaseVersion: 'Prerelease',\n print: 'Print',\n printError: 'Print error',\n printErrorExplainer: 'An error occurred in {{errorLocation}}',\n printIdentifierSticker: 'Print identifier sticker',\n printing: 'Printing',\n recordNewEntry: 'Record {{displayText}}',\n relationships: 'Relationships',\n resetOverrides: 'Reset overrides',\n save: 'Save',\n scriptLoadingFailed: 'Error: Script failed to load',\n scriptLoadingError: 'Failed to load overridden script from {{url}}. Please check that the bundled script is available at the expected URL. Click the button below to reset all import map overrides.',\n searchForLocation: 'Search for a location',\n seeAll: 'See all',\n seeMoreLists: 'See {{count}} more lists',\n selectAll: 'Select all',\n sex: 'Sex',\n showLess: 'Show less',\n showMore: 'Show more',\n snackbarNotification: 'Snackbar notification',\n toggleDevTools: 'Toggle dev tools',\n unknown: 'Unknown',\n yearAbbreviation: 'yr',\n yearsAbbreviation: 'yrs'\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS10cmFuc2xhdGlvbnMvZGlzdC90cmFuc2xhdGlvbnMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tdHJhbnNsYXRpb25zL2Rpc3QvdHJhbnNsYXRpb25zLmpzPzkwZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIFBsZWFzZSBrZWVwIHRoZXNlIGFscGhhYmV0aXplZCAqLyBjb25zdCBhZGRyZXNzRmllbGRzID0ge1xuICAgIGFkZHJlc3MxOiAnQWRkcmVzcyBsaW5lIDEnLFxuICAgIGFkZHJlc3MyOiAnQWRkcmVzcyBsaW5lIDInLFxuICAgIGFkZHJlc3MzOiAnQWRkcmVzcyBsaW5lIDMnLFxuICAgIGFkZHJlc3M0OiAnQWRkcmVzcyBsaW5lIDQnLFxuICAgIGFkZHJlc3M1OiAnQWRkcmVzcyBsaW5lIDUnLFxuICAgIGFkZHJlc3M2OiAnQWRkcmVzcyBsaW5lIDYnLFxuICAgIGNpdHk6ICdDaXR5JyxcbiAgICBjaXR5VmlsbGFnZTogJ0NpdHknLFxuICAgIGNvdW50cnk6ICdDb3VudHJ5JyxcbiAgICBjb3VudHlEaXN0cmljdDogJ0Rpc3RyaWN0JyxcbiAgICBkaXN0cmljdDogJ0Rpc3RyaWN0JyxcbiAgICBwb3N0YWxDb2RlOiAnUG9zdGFsIGNvZGUnLFxuICAgIHN0YXRlOiAnU3RhdGUnLFxuICAgIHN0YXRlUHJvdmluY2U6ICdTdGF0ZSdcbn07XG5jb25zdCB3b3Jrc3BhY2VUcmFuc2xhdGlvbnMgPSB7XG4gICAgY2xvc2VBbGxPcGVuZWRXb3Jrc3BhY2VzOiAnRGlzY2FyZCBjaGFuZ2VzIGluIHt7Y291bnR9fSB3b3Jrc3BhY2VzJyxcbiAgICBjbG9zaW5nQWxsV29ya3NwYWNlc1Byb21wdEJvZHk6ICdUaGVyZSBtYXkgYmUgdW5zYXZlZCBjaGFuZ2VzIGluIHRoZSBmb2xsb3dpbmcgd29ya3NwYWNlcy4gRG8geW91IHdhbnQgdG8gZGlzY2FyZCBjaGFuZ2VzIGluIHRoZSBmb2xsb3dpbmcgd29ya3NwYWNlcz8ge3t3b3Jrc3BhY2VOYW1lc319JyxcbiAgICBjbG9zaW5nQWxsV29ya3NwYWNlc1Byb21wdFRpdGxlOiAnWW91IGhhdmUgdW5zYXZlZCBjaGFuZ2VzJyxcbiAgICBkaXNjYXJkOiAnRGlzY2FyZCcsXG4gICAgaGlkZTogJ0hpZGUnLFxuICAgIG1heGltaXplOiAnTWF4aW1pemUnLFxuICAgIG1pbmltaXplOiAnTWluaW1pemUnLFxuICAgIG9wZW5Bbnl3YXk6ICdPcGVuIGFueXdheScsXG4gICAgdW5zYXZlZENoYW5nZXNJbk9wZW5lZFdvcmtzcGFjZTogJ1lvdSBtYXkgaGF2ZSB1bnNhdmVkIGNoYW5nZXMgaW4gdGhlIG9wZW5lZCB3b3Jrc3BhY2UuIERvIHlvdSB3YW50IHRvIGRpc2NhcmQgdGhlc2UgY2hhbmdlcz8nLFxuICAgIHVuc2F2ZWRDaGFuZ2VzSW5Xb3Jrc3BhY2U6ICdUaGVyZSBtYXkgYmUgdW5zYXZlZCBjaGFuZ2VzIGluIFwie3t3b3Jrc3BhY2VOYW1lfX1cIi4gUGxlYXNlIHNhdmUgdGhlbSBiZWZvcmUgb3BlbmluZyBhbm90aGVyIHdvcmtzcGFjZS4nLFxuICAgIHVuc2F2ZWRDaGFuZ2VzVGl0bGVUZXh0OiAnVW5zYXZlZCBjaGFuZ2VzJyxcbiAgICB3b3Jrc3BhY2VIZWFkZXI6ICdXb3Jrc3BhY2UgaGVhZGVyJ1xufTtcbmNvbnN0IHdvcmtzcGFjZTJUcmFuc2xhdGlvbnMgPSB7XG4gICAgZGlzY2FyZFVuc2F2ZWRDaGFuZ2VzUHJvbXB0Qm9keU11bHRpcGxlOiAne3tjb3VudH19IHdvcmtzcGFjZXMgaGF2ZSB1bnNhdmVkIGNoYW5nZXMuIENsb3NpbmcgdGhlbSB3aWxsIGRpc2NhcmQgdGhlIGNoYW5nZXM6JyxcbiAgICBkaXNjYXJkVW5zYXZlZENoYW5nZXNQcm9tcHRCb2R5U2luZ2xlOiAnPHN0cm9uZz57e3dvcmtzcGFjZVRpdGxlfX08L3N0cm9uZz4gaGFzIHVuc2F2ZWQgY2hhbmdlcy4gQ2xvc2luZyBpdCB3aWxsIGRpc2NhcmQgdGhlbS4nLFxuICAgIGRpc2NhcmRVbnNhdmVkQ2hhbmdlc1Byb21wdFRpdGxlOiAnRGlzY2FyZCB1bnNhdmVkIGNoYW5nZXM/JyxcbiAgICBrZWVwRWRpdGluZzogJ0tlZXAgZWRpdGluZydcbn07XG5leHBvcnQgY29uc3QgY29yZVRyYW5zbGF0aW9ucyA9IHtcbiAgICAuLi5hZGRyZXNzRmllbGRzLFxuICAgIC4uLndvcmtzcGFjZVRyYW5zbGF0aW9ucyxcbiAgICAuLi53b3Jrc3BhY2UyVHJhbnNsYXRpb25zLFxuICAgIGFibm9ybWFsVmFsdWU6ICdBYm5vcm1hbCB2YWx1ZScsXG4gICAgYWN0aW9uczogJ0FjdGlvbnMnLFxuICAgIGFjdGlvbmFibGVOb3RpZmljYXRpb246ICdBY3Rpb25hYmxlIG5vdGlmaWNhdGlvbicsXG4gICAgYWRkcmVzczogJ0FkZHJlc3MnLFxuICAgIGFnZTogJ0FnZScsXG4gICAgYmF0Y2hBY3Rpb25JdGVtU2VsZWN0ZWQ6ICd7e3RvdGFsU2VsZWN0ZWR9fSBpdGVtIHNlbGVjdGVkJyxcbiAgICBiYXRjaEFjdGlvbnNJdGVtc1NlbGVjdGVkOiAne3t0b3RhbFNlbGVjdGVkfX0gaXRlbXMgc2VsZWN0ZWQnLFxuICAgIGNhbmNlbDogJ0NhbmNlbCcsXG4gICAgY2hhbmdlOiAnQ2hhbmdlJyxcbiAgICAvLyBEZWZhdWx0IHZhbHVlIGZvciB0aGUgaW1wbGVtZW50YXRpb25OYW1lIGNvbmZpZyBwcm9wZXJ0eVxuICAgIENsaW5pYzogJ0NsaW5pYycsXG4gICAgY2xvc2U6ICdDbG9zZScsXG4gICAgY2xvc2VzQWN0aW9uYWJsZU5vdGlmaWNhdGlvbjogJ0Nsb3NlIGFjdGlvbmFibGUgbm90aWZpY2F0aW9uJyxcbiAgICBjbG9zZVNuYWNrYmFyOiAnQ2xvc2Ugc25hY2tiYXInLFxuICAgIGNvbmZpcm06ICdDb25maXJtJyxcbiAgICBjb250YWN0QWRtaW5pc3RyYXRvcklmSXNzdWVQZXJzaXN0czogJ0NvbnRhY3QgeW91ciBzeXN0ZW0gYWRtaW5pc3RyYXRvciBpZiB0aGUgcHJvYmxlbSBwZXJzaXN0cy4nLFxuICAgIGNvbnRhY3REZXRhaWxzOiAnQ29udGFjdCBkZXRhaWxzJyxcbiAgICBkZWxldGU6ICdEZWxldGUnLFxuICAgIGRpc2NhcmRDaGFuZ2VzOiAnRGlzY2FyZCBjaGFuZ2VzJyxcbiAgICBlZGl0OiAnRWRpdCcsXG4gICAgZW1wdHlTdGF0ZVRleHQ6ICdUaGVyZSBhcmUgbm8ge3tkaXNwbGF5VGV4dH19IHRvIGRpc3BsYXknLFxuICAgIGVycm9yOiAnRXJyb3InLFxuICAgIGVycm9yQ29weTogJ1NvcnJ5LCB0aGVyZSB3YXMgYSBwcm9ibGVtIGRpc3BsYXlpbmcgdGhpcyBpbmZvcm1hdGlvbi4gWW91IGNhbiB0cnkgdG8gcmVsb2FkIHRoaXMgcGFnZSwgb3IgY29udGFjdCB0aGUgc2l0ZSBhZG1pbmlzdHJhdG9yIGFuZCBxdW90ZSB0aGUgZXJyb3IgY29kZSBhYm92ZS4nLFxuICAgIGVycm9yTG9hZGluZ0xvZ2luTG9jYXRpb25zOiAnVW5hYmxlIHRvIGxvYWQgbG9naW4gbG9jYXRpb25zLiBQbGVhc2UgdHJ5IGFnYWluIG9yIGNvbnRhY3Qgc3VwcG9ydCBpZiB0aGUgcHJvYmxlbSBwZXJzaXN0cy4nLFxuICAgIGZlbWFsZTogJ0ZlbWFsZScsXG4gICAgbGVmdE5hdmlnYXRpb246ICdMZWZ0IG5hdmlnYXRpb24nLFxuICAgIGxvYWRpbmc6ICdMb2FkaW5nJyxcbiAgICBsb2NhbFZlcnNpb246ICdMb2NhbCBCdWlsZCcsXG4gICAgbWFsZTogJ01hbGUnLFxuICAgIG5hdmlnYXRlTm9uSHR0cDogJ0NvdWxkIG5vdCBuYXZpZ2F0ZSB0byB0aGUgcmVxdWVzdGVkIHBhZ2UgYXMgaXQgaXMgbm90IGEgc2FmZSBVUkwnLFxuICAgIG5vUmVzdWx0c1RvRGlzcGxheTogJ05vIHJlc3VsdHMgdG8gZGlzcGxheScsXG4gICAgbm90QXZhaWxhYmxlOiAnTm90IGF2YWlsYWJsZScsXG4gICAgb3RoZXI6ICdPdGhlcicsXG4gICAgcGFnaW5hdGlvbkl0ZW1zQ291bnQ6ICd7e3BhZ2VJdGVtc0NvdW50fX0gLyB7e3RvdGFsSXRlbXN9fSBpdGVtcycsXG4gICAgcGFnaW5hdGlvbk9mUGFnZXM6ICdvZiB7e2NvdW50fX0gcGFnZXMnLFxuICAgIHBhdGllbnRBdmF0YXJBbHQ6ICdBdmF0YXIgZm9yIHt7cGF0aWVudE5hbWV9fScsXG4gICAgcGF0aWVudElkZW50aWZpZXJTdGlja2VyOiAnUGF0aWVudCBpZGVudGlmaWVyIHN0aWNrZXInLFxuICAgIHBhdGllbnRMaXN0czogJ1BhdGllbnQgbGlzdHMnLFxuICAgIHBhdGllbnRQaG90b0FsdDogJ1Byb2ZpbGUgcGhvdG8gb2Yge3twYXRpZW50TmFtZX19JyxcbiAgICBwYXRpZW50UGhvdG9QbGFjZWhvbGRlcjogJ1Bob3RvIHBsYWNlaG9sZGVyIGZvciB7e3BhdGllbnROYW1lfX0nLFxuICAgIHByZXJlbGVhc2VWZXJzaW9uOiAnUHJlcmVsZWFzZScsXG4gICAgcHJpbnQ6ICdQcmludCcsXG4gICAgcHJpbnRFcnJvcjogJ1ByaW50IGVycm9yJyxcbiAgICBwcmludEVycm9yRXhwbGFpbmVyOiAnQW4gZXJyb3Igb2NjdXJyZWQgaW4ge3tlcnJvckxvY2F0aW9ufX0nLFxuICAgIHByaW50SWRlbnRpZmllclN0aWNrZXI6ICdQcmludCBpZGVudGlmaWVyIHN0aWNrZXInLFxuICAgIHByaW50aW5nOiAnUHJpbnRpbmcnLFxuICAgIHJlY29yZE5ld0VudHJ5OiAnUmVjb3JkIHt7ZGlzcGxheVRleHR9fScsXG4gICAgcmVsYXRpb25zaGlwczogJ1JlbGF0aW9uc2hpcHMnLFxuICAgIHJlc2V0T3ZlcnJpZGVzOiAnUmVzZXQgb3ZlcnJpZGVzJyxcbiAgICBzYXZlOiAnU2F2ZScsXG4gICAgc2NyaXB0TG9hZGluZ0ZhaWxlZDogJ0Vycm9yOiBTY3JpcHQgZmFpbGVkIHRvIGxvYWQnLFxuICAgIHNjcmlwdExvYWRpbmdFcnJvcjogJ0ZhaWxlZCB0byBsb2FkIG92ZXJyaWRkZW4gc2NyaXB0IGZyb20ge3t1cmx9fS4gUGxlYXNlIGNoZWNrIHRoYXQgdGhlIGJ1bmRsZWQgc2NyaXB0IGlzIGF2YWlsYWJsZSBhdCB0aGUgZXhwZWN0ZWQgVVJMLiBDbGljayB0aGUgYnV0dG9uIGJlbG93IHRvIHJlc2V0IGFsbCBpbXBvcnQgbWFwIG92ZXJyaWRlcy4nLFxuICAgIHNlYXJjaEZvckxvY2F0aW9uOiAnU2VhcmNoIGZvciBhIGxvY2F0aW9uJyxcbiAgICBzZWVBbGw6ICdTZWUgYWxsJyxcbiAgICBzZWVNb3JlTGlzdHM6ICdTZWUge3tjb3VudH19IG1vcmUgbGlzdHMnLFxuICAgIHNlbGVjdEFsbDogJ1NlbGVjdCBhbGwnLFxuICAgIHNleDogJ1NleCcsXG4gICAgc2hvd0xlc3M6ICdTaG93IGxlc3MnLFxuICAgIHNob3dNb3JlOiAnU2hvdyBtb3JlJyxcbiAgICBzbmFja2Jhck5vdGlmaWNhdGlvbjogJ1NuYWNrYmFyIG5vdGlmaWNhdGlvbicsXG4gICAgdG9nZ2xlRGV2VG9vbHM6ICdUb2dnbGUgZGV2IHRvb2xzJyxcbiAgICB1bmtub3duOiAnVW5rbm93bicsXG4gICAgeWVhckFiYnJldmlhdGlvbjogJ3lyJyxcbiAgICB5ZWFyc0FiYnJldmlhdGlvbjogJ3lycydcbn07XG4iXSwibmFtZXMiOlsiYWRkcmVzc0ZpZWxkcyIsIndvcmtzcGFjZVRyYW5zbGF0aW9ucyIsIndvcmtzcGFjZTJUcmFuc2xhdGlvbnMiLCJjb3JlVHJhbnNsYXRpb25zIl0sIm1hcHBpbmdzIjoiOzs7O0FBQUEsbUNBQW1DLEdBQUcsTUFBTUEsZ0JBQWdCO0lBQ3hELFVBQVU7SUFDVixVQUFVO0lBQ1YsVUFBVTtJQUNWLFVBQVU7SUFDVixVQUFVO0lBQ1YsVUFBVTtJQUNWLE1BQU07SUFDTixhQUFhO0lBQ2IsU0FBUztJQUNULGdCQUFnQjtJQUNoQixVQUFVO0lBQ1YsWUFBWTtJQUNaLE9BQU87SUFDUCxlQUFlO0FBQ25CO0FBQ0EsTUFBTUMsd0JBQXdCO0lBQzFCLDBCQUEwQjtJQUMxQixnQ0FBZ0M7SUFDaEMsaUNBQWlDO0lBQ2pDLFNBQVM7SUFDVCxNQUFNO0lBQ04sVUFBVTtJQUNWLFVBQVU7SUFDVixZQUFZO0lBQ1osaUNBQWlDO0lBQ2pDLDJCQUEyQjtJQUMzQix5QkFBeUI7SUFDekIsaUJBQWlCO0FBQ3JCO0FBQ0EsTUFBTUMseUJBQXlCO0lBQzNCLHlDQUF5QztJQUN6Qyx1Q0FBdUM7SUFDdkMsa0NBQWtDO0lBQ2xDLGFBQWE7QUFDakI7QUFDTyxNQUFNQyxtQkFBbUI7SUFDNUIsR0FBR0gsYUFBYTtJQUNoQixHQUFHQyxxQkFBcUI7SUFDeEIsR0FBR0Msc0JBQXNCO0lBQ3pCLGVBQWU7SUFDZixTQUFTO0lBQ1Qsd0JBQXdCO0lBQ3hCLFNBQVM7SUFDVCxLQUFLO0lBQ0wseUJBQXlCO0lBQ3pCLDJCQUEyQjtJQUMzQixRQUFRO0lBQ1IsUUFBUTtJQUNSLDJEQUEyRDtJQUMzRCxRQUFRO0lBQ1IsT0FBTztJQUNQLDhCQUE4QjtJQUM5QixlQUFlO0lBQ2YsU0FBUztJQUNULHFDQUFxQztJQUNyQyxnQkFBZ0I7SUFDaEIsUUFBUTtJQUNSLGdCQUFnQjtJQUNoQixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxXQUFXO0lBQ1gsNEJBQTRCO0lBQzVCLFFBQVE7SUFDUixnQkFBZ0I7SUFDaEIsU0FBUztJQUNULGNBQWM7SUFDZCxNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixjQUFjO0lBQ2QsT0FBTztJQUNQLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsa0JBQWtCO0lBQ2xCLDBCQUEwQjtJQUMxQixjQUFjO0lBQ2QsaUJBQWlCO0lBQ2pCLHlCQUF5QjtJQUN6QixtQkFBbUI7SUFDbkIsT0FBTztJQUNQLFlBQVk7SUFDWixxQkFBcUI7SUFDckIsd0JBQXdCO0lBQ3hCLFVBQVU7SUFDVixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLGdCQUFnQjtJQUNoQixNQUFNO0lBQ04scUJBQXFCO0lBQ3JCLG9CQUFvQjtJQUNwQixtQkFBbUI7SUFDbkIsUUFBUTtJQUNSLGNBQWM7SUFDZCxXQUFXO0lBQ1gsS0FBSztJQUNMLFVBQVU7SUFDVixVQUFVO0lBQ1Ysc0JBQXNCO0lBQ3RCLGdCQUFnQjtJQUNoQixTQUFTO0lBQ1Qsa0JBQWtCO0lBQ2xCLG1CQUFtQjtBQUN2QixFQUFFIn0=\n//# sourceURL=webpack-internal:///../../framework/esm-translations/dist/translations.js\n\n}");
5129
+ eval("{__webpack_require__.r(__webpack_exports__);\n__webpack_require__.d(__webpack_exports__, {\n coreTranslations: () => (coreTranslations)\n});\n/** Please keep these alphabetized */ const addressFields = {\n address1: 'Address line 1',\n address2: 'Address line 2',\n address3: 'Address line 3',\n address4: 'Address line 4',\n address5: 'Address line 5',\n address6: 'Address line 6',\n city: 'City',\n cityVillage: 'City',\n country: 'Country',\n countyDistrict: 'District',\n district: 'District',\n postalCode: 'Postal code',\n state: 'State',\n stateProvince: 'State'\n};\nconst workspaceTranslations = {\n closeAllOpenedWorkspaces: 'Discard changes in {{count}} workspaces',\n closingAllWorkspacesPromptBody: 'There may be unsaved changes in the following workspaces. Do you want to discard changes in the following workspaces? {{workspaceNames}}',\n closingAllWorkspacesPromptTitle: 'You have unsaved changes',\n discard: 'Discard',\n hide: 'Hide',\n maximize: 'Maximize',\n minimize: 'Minimize',\n openAnyway: 'Open anyway',\n unsavedChangesInOpenedWorkspace: 'You may have unsaved changes in the opened workspace. Do you want to discard these changes?',\n unsavedChangesInWorkspace: 'There may be unsaved changes in \"{{workspaceName}}\". Please save them before opening another workspace.',\n unsavedChangesTitleText: 'Unsaved changes',\n workspaceHeader: 'Workspace header'\n};\nconst workspace2Translations = {\n discardUnsavedChangesPromptBodyMultiple: '{{count}} workspaces have unsaved changes. Closing them will discard the changes:',\n discardUnsavedChangesPromptBodySingle: '<strong>{{workspaceTitle}}</strong> has unsaved changes. Closing it will discard them.',\n discardUnsavedChangesPromptTitle: 'Discard unsaved changes?',\n keepEditing: 'Keep editing'\n};\nconst coreTranslations = {\n ...addressFields,\n ...workspaceTranslations,\n ...workspace2Translations,\n abnormalValue: 'Abnormal value',\n actions: 'Actions',\n actionableNotification: 'Actionable notification',\n address: 'Address',\n age: 'Age',\n applicationError: 'Application Error',\n batchActionItemSelected: '{{totalSelected}} item selected',\n batchActionsItemsSelected: '{{totalSelected}} items selected',\n cancel: 'Cancel',\n change: 'Change',\n // Default value for the implementationName config property\n Clinic: 'Clinic',\n clearDevOverrides: 'Clear dev overrides',\n close: 'Close',\n closesActionableNotification: 'Close actionable notification',\n closeSnackbar: 'Close snackbar',\n confirm: 'Confirm',\n contactAdministratorIfIssuePersists: 'Contact your system administrator if the problem persists.',\n contactDetails: 'Contact details',\n copied: 'Copied!',\n copyToClipboard: 'Copy to clipboard',\n delete: 'Delete',\n discardChanges: 'Discard changes',\n edit: 'Edit',\n emptyStateText: 'There are no {{displayText}} to display',\n error: 'Error',\n errorCopy: 'Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.',\n errorLoadingLoginLocations: 'Unable to load login locations. Please try again or contact support if the problem persists.',\n female: 'Female',\n leftNavigation: 'Left navigation',\n loading: 'Loading',\n localVersion: 'Local Build',\n male: 'Male',\n navigateNonHttp: 'Could not navigate to the requested page as it is not a safe URL',\n noResultsToDisplay: 'No results to display',\n notAvailable: 'Not available',\n other: 'Other',\n paginationItemsCount: '{{pageItemsCount}} / {{totalItems}} items',\n paginationOfPages: 'of {{count}} pages',\n patientAvatarAlt: 'Avatar for {{patientName}}',\n patientIdentifierSticker: 'Patient identifier sticker',\n patientLists: 'Patient lists',\n patientPhotoAlt: 'Profile photo of {{patientName}}',\n patientPhotoPlaceholder: 'Photo placeholder for {{patientName}}',\n prereleaseVersion: 'Prerelease',\n print: 'Print',\n printError: 'Print error',\n printErrorExplainer: 'An error occurred in {{errorLocation}}',\n printIdentifierSticker: 'Print identifier sticker',\n printing: 'Printing',\n recordNewEntry: 'Record {{displayText}}',\n relationships: 'Relationships',\n reload: 'Reload',\n resetOverrides: 'Reset overrides',\n save: 'Save',\n scriptLoadingFailed: 'Error: Script failed to load',\n scriptLoadingError: 'Failed to load overridden script from {{url}}. Please check that the bundled script is available at the expected URL. Click the button below to reset all import map overrides.',\n searchForLocation: 'Search for a location',\n seeAll: 'See all',\n seeMoreLists: 'See {{count}} more lists',\n selectAll: 'Select all',\n serverStartingUp: 'The server is starting',\n serverStartingUpExplainer: 'This can take a few minutes. OpenMRS will open automatically when the server is ready.',\n serverStartingUpSlowExplainer: 'This is taking longer than usual. First startup after an upgrade can take 10 minutes or more. You can leave this page open.',\n sex: 'Sex',\n showLess: 'Show less',\n showMore: 'Show more',\n snackbarNotification: 'Snackbar notification',\n somethingWentWrongTryReloading: 'Something went wrong. Please try reloading.',\n toggleDevTools: 'Toggle dev tools',\n unknown: 'Unknown',\n viewSetupProgress: 'View setup progress',\n waitingForServer: 'Waiting for the server',\n yearAbbreviation: 'yr',\n yearsAbbreviation: 'yrs'\n};\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC9lc218YnVpbHRpbjpzd2MtbG9hZGVyPz9ydWxlU2V0WzFdLnJ1bGVzWzVdLnVzZVswXSEvaG9tZS9ydW5uZXIvd29yay9vcGVubXJzLWVzbS1jb3JlL29wZW5tcnMtZXNtLWNvcmUvcGFja2FnZXMvZnJhbWV3b3JrL2VzbS10cmFuc2xhdGlvbnMvZGlzdC90cmFuc2xhdGlvbnMuanMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9Ab3Blbm1ycy9lc20tYXBwLXNoZWxsLy4uLy4uL2ZyYW1ld29yay9lc20tdHJhbnNsYXRpb25zL2Rpc3QvdHJhbnNsYXRpb25zLmpzPzkwZGYiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqIFBsZWFzZSBrZWVwIHRoZXNlIGFscGhhYmV0aXplZCAqLyBjb25zdCBhZGRyZXNzRmllbGRzID0ge1xuICAgIGFkZHJlc3MxOiAnQWRkcmVzcyBsaW5lIDEnLFxuICAgIGFkZHJlc3MyOiAnQWRkcmVzcyBsaW5lIDInLFxuICAgIGFkZHJlc3MzOiAnQWRkcmVzcyBsaW5lIDMnLFxuICAgIGFkZHJlc3M0OiAnQWRkcmVzcyBsaW5lIDQnLFxuICAgIGFkZHJlc3M1OiAnQWRkcmVzcyBsaW5lIDUnLFxuICAgIGFkZHJlc3M2OiAnQWRkcmVzcyBsaW5lIDYnLFxuICAgIGNpdHk6ICdDaXR5JyxcbiAgICBjaXR5VmlsbGFnZTogJ0NpdHknLFxuICAgIGNvdW50cnk6ICdDb3VudHJ5JyxcbiAgICBjb3VudHlEaXN0cmljdDogJ0Rpc3RyaWN0JyxcbiAgICBkaXN0cmljdDogJ0Rpc3RyaWN0JyxcbiAgICBwb3N0YWxDb2RlOiAnUG9zdGFsIGNvZGUnLFxuICAgIHN0YXRlOiAnU3RhdGUnLFxuICAgIHN0YXRlUHJvdmluY2U6ICdTdGF0ZSdcbn07XG5jb25zdCB3b3Jrc3BhY2VUcmFuc2xhdGlvbnMgPSB7XG4gICAgY2xvc2VBbGxPcGVuZWRXb3Jrc3BhY2VzOiAnRGlzY2FyZCBjaGFuZ2VzIGluIHt7Y291bnR9fSB3b3Jrc3BhY2VzJyxcbiAgICBjbG9zaW5nQWxsV29ya3NwYWNlc1Byb21wdEJvZHk6ICdUaGVyZSBtYXkgYmUgdW5zYXZlZCBjaGFuZ2VzIGluIHRoZSBmb2xsb3dpbmcgd29ya3NwYWNlcy4gRG8geW91IHdhbnQgdG8gZGlzY2FyZCBjaGFuZ2VzIGluIHRoZSBmb2xsb3dpbmcgd29ya3NwYWNlcz8ge3t3b3Jrc3BhY2VOYW1lc319JyxcbiAgICBjbG9zaW5nQWxsV29ya3NwYWNlc1Byb21wdFRpdGxlOiAnWW91IGhhdmUgdW5zYXZlZCBjaGFuZ2VzJyxcbiAgICBkaXNjYXJkOiAnRGlzY2FyZCcsXG4gICAgaGlkZTogJ0hpZGUnLFxuICAgIG1heGltaXplOiAnTWF4aW1pemUnLFxuICAgIG1pbmltaXplOiAnTWluaW1pemUnLFxuICAgIG9wZW5Bbnl3YXk6ICdPcGVuIGFueXdheScsXG4gICAgdW5zYXZlZENoYW5nZXNJbk9wZW5lZFdvcmtzcGFjZTogJ1lvdSBtYXkgaGF2ZSB1bnNhdmVkIGNoYW5nZXMgaW4gdGhlIG9wZW5lZCB3b3Jrc3BhY2UuIERvIHlvdSB3YW50IHRvIGRpc2NhcmQgdGhlc2UgY2hhbmdlcz8nLFxuICAgIHVuc2F2ZWRDaGFuZ2VzSW5Xb3Jrc3BhY2U6ICdUaGVyZSBtYXkgYmUgdW5zYXZlZCBjaGFuZ2VzIGluIFwie3t3b3Jrc3BhY2VOYW1lfX1cIi4gUGxlYXNlIHNhdmUgdGhlbSBiZWZvcmUgb3BlbmluZyBhbm90aGVyIHdvcmtzcGFjZS4nLFxuICAgIHVuc2F2ZWRDaGFuZ2VzVGl0bGVUZXh0OiAnVW5zYXZlZCBjaGFuZ2VzJyxcbiAgICB3b3Jrc3BhY2VIZWFkZXI6ICdXb3Jrc3BhY2UgaGVhZGVyJ1xufTtcbmNvbnN0IHdvcmtzcGFjZTJUcmFuc2xhdGlvbnMgPSB7XG4gICAgZGlzY2FyZFVuc2F2ZWRDaGFuZ2VzUHJvbXB0Qm9keU11bHRpcGxlOiAne3tjb3VudH19IHdvcmtzcGFjZXMgaGF2ZSB1bnNhdmVkIGNoYW5nZXMuIENsb3NpbmcgdGhlbSB3aWxsIGRpc2NhcmQgdGhlIGNoYW5nZXM6JyxcbiAgICBkaXNjYXJkVW5zYXZlZENoYW5nZXNQcm9tcHRCb2R5U2luZ2xlOiAnPHN0cm9uZz57e3dvcmtzcGFjZVRpdGxlfX08L3N0cm9uZz4gaGFzIHVuc2F2ZWQgY2hhbmdlcy4gQ2xvc2luZyBpdCB3aWxsIGRpc2NhcmQgdGhlbS4nLFxuICAgIGRpc2NhcmRVbnNhdmVkQ2hhbmdlc1Byb21wdFRpdGxlOiAnRGlzY2FyZCB1bnNhdmVkIGNoYW5nZXM/JyxcbiAgICBrZWVwRWRpdGluZzogJ0tlZXAgZWRpdGluZydcbn07XG5leHBvcnQgY29uc3QgY29yZVRyYW5zbGF0aW9ucyA9IHtcbiAgICAuLi5hZGRyZXNzRmllbGRzLFxuICAgIC4uLndvcmtzcGFjZVRyYW5zbGF0aW9ucyxcbiAgICAuLi53b3Jrc3BhY2UyVHJhbnNsYXRpb25zLFxuICAgIGFibm9ybWFsVmFsdWU6ICdBYm5vcm1hbCB2YWx1ZScsXG4gICAgYWN0aW9uczogJ0FjdGlvbnMnLFxuICAgIGFjdGlvbmFibGVOb3RpZmljYXRpb246ICdBY3Rpb25hYmxlIG5vdGlmaWNhdGlvbicsXG4gICAgYWRkcmVzczogJ0FkZHJlc3MnLFxuICAgIGFnZTogJ0FnZScsXG4gICAgYXBwbGljYXRpb25FcnJvcjogJ0FwcGxpY2F0aW9uIEVycm9yJyxcbiAgICBiYXRjaEFjdGlvbkl0ZW1TZWxlY3RlZDogJ3t7dG90YWxTZWxlY3RlZH19IGl0ZW0gc2VsZWN0ZWQnLFxuICAgIGJhdGNoQWN0aW9uc0l0ZW1zU2VsZWN0ZWQ6ICd7e3RvdGFsU2VsZWN0ZWR9fSBpdGVtcyBzZWxlY3RlZCcsXG4gICAgY2FuY2VsOiAnQ2FuY2VsJyxcbiAgICBjaGFuZ2U6ICdDaGFuZ2UnLFxuICAgIC8vIERlZmF1bHQgdmFsdWUgZm9yIHRoZSBpbXBsZW1lbnRhdGlvbk5hbWUgY29uZmlnIHByb3BlcnR5XG4gICAgQ2xpbmljOiAnQ2xpbmljJyxcbiAgICBjbGVhckRldk92ZXJyaWRlczogJ0NsZWFyIGRldiBvdmVycmlkZXMnLFxuICAgIGNsb3NlOiAnQ2xvc2UnLFxuICAgIGNsb3Nlc0FjdGlvbmFibGVOb3RpZmljYXRpb246ICdDbG9zZSBhY3Rpb25hYmxlIG5vdGlmaWNhdGlvbicsXG4gICAgY2xvc2VTbmFja2JhcjogJ0Nsb3NlIHNuYWNrYmFyJyxcbiAgICBjb25maXJtOiAnQ29uZmlybScsXG4gICAgY29udGFjdEFkbWluaXN0cmF0b3JJZklzc3VlUGVyc2lzdHM6ICdDb250YWN0IHlvdXIgc3lzdGVtIGFkbWluaXN0cmF0b3IgaWYgdGhlIHByb2JsZW0gcGVyc2lzdHMuJyxcbiAgICBjb250YWN0RGV0YWlsczogJ0NvbnRhY3QgZGV0YWlscycsXG4gICAgY29waWVkOiAnQ29waWVkIScsXG4gICAgY29weVRvQ2xpcGJvYXJkOiAnQ29weSB0byBjbGlwYm9hcmQnLFxuICAgIGRlbGV0ZTogJ0RlbGV0ZScsXG4gICAgZGlzY2FyZENoYW5nZXM6ICdEaXNjYXJkIGNoYW5nZXMnLFxuICAgIGVkaXQ6ICdFZGl0JyxcbiAgICBlbXB0eVN0YXRlVGV4dDogJ1RoZXJlIGFyZSBubyB7e2Rpc3BsYXlUZXh0fX0gdG8gZGlzcGxheScsXG4gICAgZXJyb3I6ICdFcnJvcicsXG4gICAgZXJyb3JDb3B5OiAnU29ycnksIHRoZXJlIHdhcyBhIHByb2JsZW0gZGlzcGxheWluZyB0aGlzIGluZm9ybWF0aW9uLiBZb3UgY2FuIHRyeSB0byByZWxvYWQgdGhpcyBwYWdlLCBvciBjb250YWN0IHRoZSBzaXRlIGFkbWluaXN0cmF0b3IgYW5kIHF1b3RlIHRoZSBlcnJvciBjb2RlIGFib3ZlLicsXG4gICAgZXJyb3JMb2FkaW5nTG9naW5Mb2NhdGlvbnM6ICdVbmFibGUgdG8gbG9hZCBsb2dpbiBsb2NhdGlvbnMuIFBsZWFzZSB0cnkgYWdhaW4gb3IgY29udGFjdCBzdXBwb3J0IGlmIHRoZSBwcm9ibGVtIHBlcnNpc3RzLicsXG4gICAgZmVtYWxlOiAnRmVtYWxlJyxcbiAgICBsZWZ0TmF2aWdhdGlvbjogJ0xlZnQgbmF2aWdhdGlvbicsXG4gICAgbG9hZGluZzogJ0xvYWRpbmcnLFxuICAgIGxvY2FsVmVyc2lvbjogJ0xvY2FsIEJ1aWxkJyxcbiAgICBtYWxlOiAnTWFsZScsXG4gICAgbmF2aWdhdGVOb25IdHRwOiAnQ291bGQgbm90IG5hdmlnYXRlIHRvIHRoZSByZXF1ZXN0ZWQgcGFnZSBhcyBpdCBpcyBub3QgYSBzYWZlIFVSTCcsXG4gICAgbm9SZXN1bHRzVG9EaXNwbGF5OiAnTm8gcmVzdWx0cyB0byBkaXNwbGF5JyxcbiAgICBub3RBdmFpbGFibGU6ICdOb3QgYXZhaWxhYmxlJyxcbiAgICBvdGhlcjogJ090aGVyJyxcbiAgICBwYWdpbmF0aW9uSXRlbXNDb3VudDogJ3t7cGFnZUl0ZW1zQ291bnR9fSAvIHt7dG90YWxJdGVtc319IGl0ZW1zJyxcbiAgICBwYWdpbmF0aW9uT2ZQYWdlczogJ29mIHt7Y291bnR9fSBwYWdlcycsXG4gICAgcGF0aWVudEF2YXRhckFsdDogJ0F2YXRhciBmb3Ige3twYXRpZW50TmFtZX19JyxcbiAgICBwYXRpZW50SWRlbnRpZmllclN0aWNrZXI6ICdQYXRpZW50IGlkZW50aWZpZXIgc3RpY2tlcicsXG4gICAgcGF0aWVudExpc3RzOiAnUGF0aWVudCBsaXN0cycsXG4gICAgcGF0aWVudFBob3RvQWx0OiAnUHJvZmlsZSBwaG90byBvZiB7e3BhdGllbnROYW1lfX0nLFxuICAgIHBhdGllbnRQaG90b1BsYWNlaG9sZGVyOiAnUGhvdG8gcGxhY2Vob2xkZXIgZm9yIHt7cGF0aWVudE5hbWV9fScsXG4gICAgcHJlcmVsZWFzZVZlcnNpb246ICdQcmVyZWxlYXNlJyxcbiAgICBwcmludDogJ1ByaW50JyxcbiAgICBwcmludEVycm9yOiAnUHJpbnQgZXJyb3InLFxuICAgIHByaW50RXJyb3JFeHBsYWluZXI6ICdBbiBlcnJvciBvY2N1cnJlZCBpbiB7e2Vycm9yTG9jYXRpb259fScsXG4gICAgcHJpbnRJZGVudGlmaWVyU3RpY2tlcjogJ1ByaW50IGlkZW50aWZpZXIgc3RpY2tlcicsXG4gICAgcHJpbnRpbmc6ICdQcmludGluZycsXG4gICAgcmVjb3JkTmV3RW50cnk6ICdSZWNvcmQge3tkaXNwbGF5VGV4dH19JyxcbiAgICByZWxhdGlvbnNoaXBzOiAnUmVsYXRpb25zaGlwcycsXG4gICAgcmVsb2FkOiAnUmVsb2FkJyxcbiAgICByZXNldE92ZXJyaWRlczogJ1Jlc2V0IG92ZXJyaWRlcycsXG4gICAgc2F2ZTogJ1NhdmUnLFxuICAgIHNjcmlwdExvYWRpbmdGYWlsZWQ6ICdFcnJvcjogU2NyaXB0IGZhaWxlZCB0byBsb2FkJyxcbiAgICBzY3JpcHRMb2FkaW5nRXJyb3I6ICdGYWlsZWQgdG8gbG9hZCBvdmVycmlkZGVuIHNjcmlwdCBmcm9tIHt7dXJsfX0uIFBsZWFzZSBjaGVjayB0aGF0IHRoZSBidW5kbGVkIHNjcmlwdCBpcyBhdmFpbGFibGUgYXQgdGhlIGV4cGVjdGVkIFVSTC4gQ2xpY2sgdGhlIGJ1dHRvbiBiZWxvdyB0byByZXNldCBhbGwgaW1wb3J0IG1hcCBvdmVycmlkZXMuJyxcbiAgICBzZWFyY2hGb3JMb2NhdGlvbjogJ1NlYXJjaCBmb3IgYSBsb2NhdGlvbicsXG4gICAgc2VlQWxsOiAnU2VlIGFsbCcsXG4gICAgc2VlTW9yZUxpc3RzOiAnU2VlIHt7Y291bnR9fSBtb3JlIGxpc3RzJyxcbiAgICBzZWxlY3RBbGw6ICdTZWxlY3QgYWxsJyxcbiAgICBzZXJ2ZXJTdGFydGluZ1VwOiAnVGhlIHNlcnZlciBpcyBzdGFydGluZycsXG4gICAgc2VydmVyU3RhcnRpbmdVcEV4cGxhaW5lcjogJ1RoaXMgY2FuIHRha2UgYSBmZXcgbWludXRlcy4gT3Blbk1SUyB3aWxsIG9wZW4gYXV0b21hdGljYWxseSB3aGVuIHRoZSBzZXJ2ZXIgaXMgcmVhZHkuJyxcbiAgICBzZXJ2ZXJTdGFydGluZ1VwU2xvd0V4cGxhaW5lcjogJ1RoaXMgaXMgdGFraW5nIGxvbmdlciB0aGFuIHVzdWFsLiBGaXJzdCBzdGFydHVwIGFmdGVyIGFuIHVwZ3JhZGUgY2FuIHRha2UgMTAgbWludXRlcyBvciBtb3JlLiBZb3UgY2FuIGxlYXZlIHRoaXMgcGFnZSBvcGVuLicsXG4gICAgc2V4OiAnU2V4JyxcbiAgICBzaG93TGVzczogJ1Nob3cgbGVzcycsXG4gICAgc2hvd01vcmU6ICdTaG93IG1vcmUnLFxuICAgIHNuYWNrYmFyTm90aWZpY2F0aW9uOiAnU25hY2tiYXIgbm90aWZpY2F0aW9uJyxcbiAgICBzb21ldGhpbmdXZW50V3JvbmdUcnlSZWxvYWRpbmc6ICdTb21ldGhpbmcgd2VudCB3cm9uZy4gUGxlYXNlIHRyeSByZWxvYWRpbmcuJyxcbiAgICB0b2dnbGVEZXZUb29sczogJ1RvZ2dsZSBkZXYgdG9vbHMnLFxuICAgIHVua25vd246ICdVbmtub3duJyxcbiAgICB2aWV3U2V0dXBQcm9ncmVzczogJ1ZpZXcgc2V0dXAgcHJvZ3Jlc3MnLFxuICAgIHdhaXRpbmdGb3JTZXJ2ZXI6ICdXYWl0aW5nIGZvciB0aGUgc2VydmVyJyxcbiAgICB5ZWFyQWJicmV2aWF0aW9uOiAneXInLFxuICAgIHllYXJzQWJicmV2aWF0aW9uOiAneXJzJ1xufTtcbiJdLCJuYW1lcyI6WyJhZGRyZXNzRmllbGRzIiwid29ya3NwYWNlVHJhbnNsYXRpb25zIiwid29ya3NwYWNlMlRyYW5zbGF0aW9ucyIsImNvcmVUcmFuc2xhdGlvbnMiXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxtQ0FBbUMsR0FBRyxNQUFNQSxnQkFBZ0I7SUFDeEQsVUFBVTtJQUNWLFVBQVU7SUFDVixVQUFVO0lBQ1YsVUFBVTtJQUNWLFVBQVU7SUFDVixVQUFVO0lBQ1YsTUFBTTtJQUNOLGFBQWE7SUFDYixTQUFTO0lBQ1QsZ0JBQWdCO0lBQ2hCLFVBQVU7SUFDVixZQUFZO0lBQ1osT0FBTztJQUNQLGVBQWU7QUFDbkI7QUFDQSxNQUFNQyx3QkFBd0I7SUFDMUIsMEJBQTBCO0lBQzFCLGdDQUFnQztJQUNoQyxpQ0FBaUM7SUFDakMsU0FBUztJQUNULE1BQU07SUFDTixVQUFVO0lBQ1YsVUFBVTtJQUNWLFlBQVk7SUFDWixpQ0FBaUM7SUFDakMsMkJBQTJCO0lBQzNCLHlCQUF5QjtJQUN6QixpQkFBaUI7QUFDckI7QUFDQSxNQUFNQyx5QkFBeUI7SUFDM0IseUNBQXlDO0lBQ3pDLHVDQUF1QztJQUN2QyxrQ0FBa0M7SUFDbEMsYUFBYTtBQUNqQjtBQUNPLE1BQU1DLG1CQUFtQjtJQUM1QixHQUFHSCxhQUFhO0lBQ2hCLEdBQUdDLHFCQUFxQjtJQUN4QixHQUFHQyxzQkFBc0I7SUFDekIsZUFBZTtJQUNmLFNBQVM7SUFDVCx3QkFBd0I7SUFDeEIsU0FBUztJQUNULEtBQUs7SUFDTCxrQkFBa0I7SUFDbEIseUJBQXlCO0lBQ3pCLDJCQUEyQjtJQUMzQixRQUFRO0lBQ1IsUUFBUTtJQUNSLDJEQUEyRDtJQUMzRCxRQUFRO0lBQ1IsbUJBQW1CO0lBQ25CLE9BQU87SUFDUCw4QkFBOEI7SUFDOUIsZUFBZTtJQUNmLFNBQVM7SUFDVCxxQ0FBcUM7SUFDckMsZ0JBQWdCO0lBQ2hCLFFBQVE7SUFDUixpQkFBaUI7SUFDakIsUUFBUTtJQUNSLGdCQUFnQjtJQUNoQixNQUFNO0lBQ04sZ0JBQWdCO0lBQ2hCLE9BQU87SUFDUCxXQUFXO0lBQ1gsNEJBQTRCO0lBQzVCLFFBQVE7SUFDUixnQkFBZ0I7SUFDaEIsU0FBUztJQUNULGNBQWM7SUFDZCxNQUFNO0lBQ04saUJBQWlCO0lBQ2pCLG9CQUFvQjtJQUNwQixjQUFjO0lBQ2QsT0FBTztJQUNQLHNCQUFzQjtJQUN0QixtQkFBbUI7SUFDbkIsa0JBQWtCO0lBQ2xCLDBCQUEwQjtJQUMxQixjQUFjO0lBQ2QsaUJBQWlCO0lBQ2pCLHlCQUF5QjtJQUN6QixtQkFBbUI7SUFDbkIsT0FBTztJQUNQLFlBQVk7SUFDWixxQkFBcUI7SUFDckIsd0JBQXdCO0lBQ3hCLFVBQVU7SUFDVixnQkFBZ0I7SUFDaEIsZUFBZTtJQUNmLFFBQVE7SUFDUixnQkFBZ0I7SUFDaEIsTUFBTTtJQUNOLHFCQUFxQjtJQUNyQixvQkFBb0I7SUFDcEIsbUJBQW1CO0lBQ25CLFFBQVE7SUFDUixjQUFjO0lBQ2QsV0FBVztJQUNYLGtCQUFrQjtJQUNsQiwyQkFBMkI7SUFDM0IsK0JBQStCO0lBQy9CLEtBQUs7SUFDTCxVQUFVO0lBQ1YsVUFBVTtJQUNWLHNCQUFzQjtJQUN0QixnQ0FBZ0M7SUFDaEMsZ0JBQWdCO0lBQ2hCLFNBQVM7SUFDVCxtQkFBbUI7SUFDbkIsa0JBQWtCO0lBQ2xCLGtCQUFrQjtJQUNsQixtQkFBbUI7QUFDdkIsRUFBRSJ9\n//# sourceURL=webpack-internal:///../../framework/esm-translations/dist/translations.js\n\n}");
5130
5130
 
5131
5131
  },
5132
5132
  "../../framework/esm-utils/dist/age-helpers.js"(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {