@angular/cdk 19.0.0-next.0 → 19.0.0-next.10
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.
- package/a11y/_index.scss +12 -54
- package/a11y/index.d.ts +24 -38
- package/accordion/index.d.ts +5 -4
- package/bidi/index.d.ts +2 -2
- package/clipboard/index.d.ts +3 -4
- package/dialog/index.d.ts +12 -12
- package/drag-drop/index.d.ts +17 -37
- package/fesm2022/a11y.mjs +134 -181
- package/fesm2022/a11y.mjs.map +1 -1
- package/fesm2022/accordion.mjs +20 -27
- package/fesm2022/accordion.mjs.map +1 -1
- package/fesm2022/bidi.mjs +14 -19
- package/fesm2022/bidi.mjs.map +1 -1
- package/fesm2022/cdk.mjs +1 -1
- package/fesm2022/cdk.mjs.map +1 -1
- package/fesm2022/clipboard.mjs +19 -27
- package/fesm2022/clipboard.mjs.map +1 -1
- package/fesm2022/coercion/private.mjs.map +1 -1
- package/fesm2022/coercion.mjs.map +1 -1
- package/fesm2022/collections.mjs +3 -3
- package/fesm2022/collections.mjs.map +1 -1
- package/fesm2022/dialog.mjs +36 -56
- package/fesm2022/dialog.mjs.map +1 -1
- package/fesm2022/drag-drop.mjs +107 -181
- package/fesm2022/drag-drop.mjs.map +1 -1
- package/fesm2022/keycodes.mjs.map +1 -1
- package/fesm2022/layout.mjs +21 -26
- package/fesm2022/layout.mjs.map +1 -1
- package/fesm2022/listbox.mjs +17 -13
- package/fesm2022/listbox.mjs.map +1 -1
- package/fesm2022/menu.mjs +49 -61
- package/fesm2022/menu.mjs.map +1 -1
- package/fesm2022/observers/private.mjs +3 -3
- package/fesm2022/observers/private.mjs.map +1 -1
- package/fesm2022/observers.mjs +21 -22
- package/fesm2022/observers.mjs.map +1 -1
- package/fesm2022/overlay.mjs +120 -149
- package/fesm2022/overlay.mjs.map +1 -1
- package/fesm2022/platform.mjs +11 -14
- package/fesm2022/platform.mjs.map +1 -1
- package/fesm2022/portal.mjs +60 -63
- package/fesm2022/portal.mjs.map +1 -1
- package/fesm2022/private.mjs +65 -0
- package/fesm2022/private.mjs.map +1 -0
- package/fesm2022/scrolling.mjs +90 -132
- package/fesm2022/scrolling.mjs.map +1 -1
- package/fesm2022/stepper.mjs +69 -63
- package/fesm2022/stepper.mjs.map +1 -1
- package/fesm2022/table.mjs +171 -250
- package/fesm2022/table.mjs.map +1 -1
- package/fesm2022/testing/selenium-webdriver.mjs.map +1 -1
- package/fesm2022/testing/testbed.mjs +3 -2
- package/fesm2022/testing/testbed.mjs.map +1 -1
- package/fesm2022/testing.mjs.map +1 -1
- package/fesm2022/text-field.mjs +46 -40
- package/fesm2022/text-field.mjs.map +1 -1
- package/fesm2022/tree.mjs +90 -80
- package/fesm2022/tree.mjs.map +1 -1
- package/layout/index.d.ts +5 -7
- package/observers/index.d.ts +2 -2
- package/overlay/_index.scss +56 -21
- package/overlay/index.d.ts +24 -36
- package/overlay-prebuilt.css +1 -1
- package/package.json +5 -55
- package/platform/index.d.ts +2 -1
- package/portal/index.d.ts +22 -19
- package/private/index.d.ts +30 -0
- package/schematics/index.d.ts +1 -1
- package/schematics/index.js +2 -2
- package/schematics/index.mjs +2 -2
- package/schematics/ng-add/index.d.ts +1 -1
- package/schematics/ng-add/index.js +3 -3
- package/schematics/ng-add/index.mjs +3 -3
- package/schematics/ng-add/package-config.d.ts +1 -1
- package/schematics/ng-add/package-config.js +2 -2
- package/schematics/ng-add/package-config.mjs +2 -2
- package/schematics/ng-add/schema.d.ts +1 -1
- package/schematics/ng-add/schema.js +2 -2
- package/schematics/ng-add/schema.mjs +2 -2
- package/schematics/ng-generate/drag-drop/index.d.ts +1 -1
- package/schematics/ng-generate/drag-drop/index.js +2 -2
- package/schematics/ng-generate/drag-drop/index.mjs +2 -2
- package/schematics/ng-generate/drag-drop/schema.d.ts +1 -1
- package/schematics/ng-generate/drag-drop/schema.js +2 -2
- package/schematics/ng-generate/drag-drop/schema.mjs +2 -2
- package/schematics/ng-update/data/attribute-selectors.d.ts +1 -1
- package/schematics/ng-update/data/attribute-selectors.js +2 -2
- package/schematics/ng-update/data/attribute-selectors.mjs +2 -2
- package/schematics/ng-update/data/class-names.d.ts +1 -1
- package/schematics/ng-update/data/class-names.js +2 -2
- package/schematics/ng-update/data/class-names.mjs +2 -2
- package/schematics/ng-update/data/constructor-checks.d.ts +1 -1
- package/schematics/ng-update/data/constructor-checks.js +2 -2
- package/schematics/ng-update/data/constructor-checks.mjs +2 -2
- package/schematics/ng-update/data/css-selectors.d.ts +1 -1
- package/schematics/ng-update/data/css-selectors.js +2 -2
- package/schematics/ng-update/data/css-selectors.mjs +2 -2
- package/schematics/ng-update/data/css-tokens.d.ts +1 -1
- package/schematics/ng-update/data/css-tokens.js +2 -2
- package/schematics/ng-update/data/css-tokens.mjs +2 -2
- package/schematics/ng-update/data/element-selectors.d.ts +1 -1
- package/schematics/ng-update/data/element-selectors.js +2 -2
- package/schematics/ng-update/data/element-selectors.mjs +2 -2
- package/schematics/ng-update/data/index.d.ts +1 -1
- package/schematics/ng-update/data/index.js +2 -2
- package/schematics/ng-update/data/index.mjs +2 -2
- package/schematics/ng-update/data/input-names.d.ts +1 -1
- package/schematics/ng-update/data/input-names.js +2 -2
- package/schematics/ng-update/data/input-names.mjs +2 -2
- package/schematics/ng-update/data/method-call-checks.d.ts +1 -1
- package/schematics/ng-update/data/method-call-checks.js +2 -2
- package/schematics/ng-update/data/method-call-checks.mjs +2 -2
- package/schematics/ng-update/data/output-names.d.ts +1 -1
- package/schematics/ng-update/data/output-names.js +2 -2
- package/schematics/ng-update/data/output-names.mjs +2 -2
- package/schematics/ng-update/data/property-names.d.ts +1 -1
- package/schematics/ng-update/data/property-names.js +2 -2
- package/schematics/ng-update/data/property-names.mjs +2 -2
- package/schematics/ng-update/data/symbol-removal.d.ts +1 -1
- package/schematics/ng-update/data/symbol-removal.js +2 -2
- package/schematics/ng-update/data/symbol-removal.mjs +2 -2
- package/schematics/ng-update/devkit-file-system.d.ts +1 -1
- package/schematics/ng-update/devkit-file-system.js +2 -2
- package/schematics/ng-update/devkit-file-system.mjs +2 -2
- package/schematics/ng-update/devkit-migration-rule.d.ts +1 -1
- package/schematics/ng-update/devkit-migration-rule.js +2 -2
- package/schematics/ng-update/devkit-migration-rule.mjs +2 -2
- package/schematics/ng-update/devkit-migration.d.ts +1 -1
- package/schematics/ng-update/devkit-migration.js +2 -2
- package/schematics/ng-update/devkit-migration.mjs +2 -2
- package/schematics/ng-update/find-stylesheets.d.ts +1 -1
- package/schematics/ng-update/find-stylesheets.js +2 -2
- package/schematics/ng-update/find-stylesheets.mjs +2 -2
- package/schematics/ng-update/html-parsing/angular.d.ts +1 -1
- package/schematics/ng-update/html-parsing/angular.js +2 -2
- package/schematics/ng-update/html-parsing/angular.mjs +2 -2
- package/schematics/ng-update/html-parsing/elements.d.ts +1 -1
- package/schematics/ng-update/html-parsing/elements.js +2 -2
- package/schematics/ng-update/html-parsing/elements.mjs +2 -2
- package/schematics/ng-update/index.d.ts +1 -1
- package/schematics/ng-update/index.js +2 -2
- package/schematics/ng-update/index.mjs +2 -2
- package/schematics/ng-update/migrations/attribute-selectors.d.ts +1 -1
- package/schematics/ng-update/migrations/attribute-selectors.js +2 -2
- package/schematics/ng-update/migrations/attribute-selectors.mjs +2 -2
- package/schematics/ng-update/migrations/class-inheritance.d.ts +1 -1
- package/schematics/ng-update/migrations/class-inheritance.js +2 -2
- package/schematics/ng-update/migrations/class-inheritance.mjs +2 -2
- package/schematics/ng-update/migrations/class-names.d.ts +1 -1
- package/schematics/ng-update/migrations/class-names.js +2 -2
- package/schematics/ng-update/migrations/class-names.mjs +2 -2
- package/schematics/ng-update/migrations/constructor-signature.d.ts +1 -1
- package/schematics/ng-update/migrations/constructor-signature.js +2 -2
- package/schematics/ng-update/migrations/constructor-signature.mjs +2 -2
- package/schematics/ng-update/migrations/css-selectors.d.ts +1 -1
- package/schematics/ng-update/migrations/css-selectors.js +2 -2
- package/schematics/ng-update/migrations/css-selectors.mjs +2 -2
- package/schematics/ng-update/migrations/css-tokens.d.ts +1 -1
- package/schematics/ng-update/migrations/css-tokens.js +2 -2
- package/schematics/ng-update/migrations/css-tokens.mjs +2 -2
- package/schematics/ng-update/migrations/element-selectors.d.ts +1 -1
- package/schematics/ng-update/migrations/element-selectors.js +2 -2
- package/schematics/ng-update/migrations/element-selectors.mjs +2 -2
- package/schematics/ng-update/migrations/input-names.d.ts +1 -1
- package/schematics/ng-update/migrations/input-names.js +2 -2
- package/schematics/ng-update/migrations/input-names.mjs +2 -2
- package/schematics/ng-update/migrations/method-call-arguments.d.ts +1 -1
- package/schematics/ng-update/migrations/method-call-arguments.js +2 -2
- package/schematics/ng-update/migrations/method-call-arguments.mjs +2 -2
- package/schematics/ng-update/migrations/misc-template.d.ts +1 -1
- package/schematics/ng-update/migrations/misc-template.js +2 -2
- package/schematics/ng-update/migrations/misc-template.mjs +2 -2
- package/schematics/ng-update/migrations/output-names.d.ts +1 -1
- package/schematics/ng-update/migrations/output-names.js +2 -2
- package/schematics/ng-update/migrations/output-names.mjs +2 -2
- package/schematics/ng-update/migrations/property-names.d.ts +1 -1
- package/schematics/ng-update/migrations/property-names.js +2 -2
- package/schematics/ng-update/migrations/property-names.mjs +2 -2
- package/schematics/ng-update/migrations/symbol-removal.d.ts +1 -1
- package/schematics/ng-update/migrations/symbol-removal.js +2 -2
- package/schematics/ng-update/migrations/symbol-removal.mjs +2 -2
- package/schematics/ng-update/public-api.d.ts +1 -1
- package/schematics/ng-update/public-api.js +2 -2
- package/schematics/ng-update/public-api.mjs +2 -2
- package/schematics/ng-update/typescript/base-types.d.ts +1 -1
- package/schematics/ng-update/typescript/base-types.js +2 -2
- package/schematics/ng-update/typescript/base-types.mjs +2 -2
- package/schematics/ng-update/typescript/imports.d.ts +1 -1
- package/schematics/ng-update/typescript/imports.js +2 -2
- package/schematics/ng-update/typescript/imports.mjs +2 -2
- package/schematics/ng-update/typescript/literal.d.ts +1 -1
- package/schematics/ng-update/typescript/literal.js +2 -2
- package/schematics/ng-update/typescript/literal.mjs +2 -2
- package/schematics/ng-update/typescript/module-specifiers.d.ts +1 -1
- package/schematics/ng-update/typescript/module-specifiers.js +2 -2
- package/schematics/ng-update/typescript/module-specifiers.mjs +2 -2
- package/schematics/ng-update/upgrade-data.d.ts +1 -1
- package/schematics/ng-update/upgrade-data.js +2 -2
- package/schematics/ng-update/upgrade-data.mjs +2 -2
- package/schematics/paths.d.ts +1 -1
- package/schematics/paths.js +2 -2
- package/schematics/paths.mjs +2 -2
- package/schematics/update-tool/component-resource-collector.d.ts +1 -1
- package/schematics/update-tool/component-resource-collector.js +2 -2
- package/schematics/update-tool/component-resource-collector.mjs +2 -2
- package/schematics/update-tool/file-system.d.ts +1 -1
- package/schematics/update-tool/file-system.js +2 -2
- package/schematics/update-tool/file-system.mjs +2 -2
- package/schematics/update-tool/index.d.ts +1 -1
- package/schematics/update-tool/index.js +2 -2
- package/schematics/update-tool/index.mjs +2 -2
- package/schematics/update-tool/logger.d.ts +1 -1
- package/schematics/update-tool/logger.js +2 -2
- package/schematics/update-tool/logger.mjs +2 -2
- package/schematics/update-tool/migration.d.ts +1 -1
- package/schematics/update-tool/migration.js +2 -2
- package/schematics/update-tool/migration.mjs +2 -2
- package/schematics/update-tool/public-api.d.ts +1 -1
- package/schematics/update-tool/public-api.js +2 -2
- package/schematics/update-tool/public-api.mjs +2 -2
- package/schematics/update-tool/target-version.d.ts +1 -1
- package/schematics/update-tool/target-version.js +2 -2
- package/schematics/update-tool/target-version.mjs +2 -2
- package/schematics/update-tool/update-recorder.d.ts +1 -1
- package/schematics/update-tool/update-recorder.js +2 -2
- package/schematics/update-tool/update-recorder.mjs +2 -2
- package/schematics/update-tool/utils/decorators.d.ts +1 -1
- package/schematics/update-tool/utils/decorators.js +2 -2
- package/schematics/update-tool/utils/decorators.mjs +2 -2
- package/schematics/update-tool/utils/diagnostics.d.ts +1 -1
- package/schematics/update-tool/utils/diagnostics.js +2 -2
- package/schematics/update-tool/utils/diagnostics.mjs +2 -2
- package/schematics/update-tool/utils/functions.d.ts +1 -1
- package/schematics/update-tool/utils/functions.js +2 -2
- package/schematics/update-tool/utils/functions.mjs +2 -2
- package/schematics/update-tool/utils/imports.d.ts +1 -1
- package/schematics/update-tool/utils/imports.js +2 -2
- package/schematics/update-tool/utils/imports.mjs +2 -2
- package/schematics/update-tool/utils/line-mappings.d.ts +1 -1
- package/schematics/update-tool/utils/line-mappings.js +2 -2
- package/schematics/update-tool/utils/line-mappings.mjs +2 -2
- package/schematics/update-tool/utils/parse-tsconfig.d.ts +1 -1
- package/schematics/update-tool/utils/parse-tsconfig.js +2 -2
- package/schematics/update-tool/utils/parse-tsconfig.mjs +2 -2
- package/schematics/update-tool/utils/property-name.d.ts +1 -1
- package/schematics/update-tool/utils/property-name.js +2 -2
- package/schematics/update-tool/utils/property-name.mjs +2 -2
- package/schematics/update-tool/utils/virtual-host.d.ts +1 -1
- package/schematics/update-tool/utils/virtual-host.js +2 -2
- package/schematics/update-tool/utils/virtual-host.mjs +2 -2
- package/schematics/update-tool/version-changes.d.ts +1 -1
- package/schematics/update-tool/version-changes.js +2 -2
- package/schematics/update-tool/version-changes.mjs +2 -2
- package/schematics/utils/ast/ng-module-imports.d.ts +1 -1
- package/schematics/utils/ast/ng-module-imports.js +2 -2
- package/schematics/utils/ast/ng-module-imports.mjs +2 -2
- package/schematics/utils/ast.d.ts +1 -1
- package/schematics/utils/ast.js +2 -2
- package/schematics/utils/ast.mjs +2 -2
- package/schematics/utils/build-component.d.ts +1 -1
- package/schematics/utils/build-component.js +2 -2
- package/schematics/utils/build-component.mjs +2 -2
- package/schematics/utils/get-project.d.ts +1 -1
- package/schematics/utils/get-project.js +2 -2
- package/schematics/utils/get-project.mjs +2 -2
- package/schematics/utils/html-manipulation.d.ts +1 -1
- package/schematics/utils/html-manipulation.js +2 -2
- package/schematics/utils/html-manipulation.mjs +2 -2
- package/schematics/utils/index.d.ts +1 -1
- package/schematics/utils/index.js +2 -2
- package/schematics/utils/index.mjs +2 -2
- package/schematics/utils/parse5-element.d.ts +1 -1
- package/schematics/utils/parse5-element.js +2 -2
- package/schematics/utils/parse5-element.mjs +2 -2
- package/schematics/utils/project-index-file.d.ts +1 -1
- package/schematics/utils/project-index-file.js +2 -2
- package/schematics/utils/project-index-file.mjs +2 -2
- package/schematics/utils/project-main-file.d.ts +1 -1
- package/schematics/utils/project-main-file.js +2 -2
- package/schematics/utils/project-main-file.mjs +2 -2
- package/schematics/utils/project-style-file.d.ts +1 -1
- package/schematics/utils/project-style-file.js +2 -2
- package/schematics/utils/project-style-file.mjs +2 -2
- package/schematics/utils/project-targets.d.ts +1 -1
- package/schematics/utils/project-targets.js +4 -3
- package/schematics/utils/project-targets.mjs +4 -3
- package/schematics/utils/project-tsconfig-paths.d.ts +1 -1
- package/schematics/utils/project-tsconfig-paths.js +2 -2
- package/schematics/utils/project-tsconfig-paths.mjs +2 -2
- package/schematics/utils/schematic-options.d.ts +1 -1
- package/schematics/utils/schematic-options.js +2 -2
- package/schematics/utils/schematic-options.mjs +2 -2
- package/scrolling/index.d.ts +19 -38
- package/stepper/index.d.ts +16 -69
- package/table/index.d.ts +41 -56
- package/text-field/index.d.ts +6 -9
- package/tree/index.d.ts +17 -16
- package/esm2022/a11y/a11y-module.mjs +0 -31
- package/esm2022/a11y/a11y_public_index.mjs +0 -5
- package/esm2022/a11y/aria-describer/aria-describer.mjs +0 -232
- package/esm2022/a11y/aria-describer/aria-reference.mjs +0 -47
- package/esm2022/a11y/fake-event-detection.mjs +0 -29
- package/esm2022/a11y/focus-monitor/focus-monitor.mjs +0 -468
- package/esm2022/a11y/focus-trap/configurable-focus-trap-config.mjs +0 -9
- package/esm2022/a11y/focus-trap/configurable-focus-trap-factory.mjs +0 -54
- package/esm2022/a11y/focus-trap/configurable-focus-trap.mjs +0 -51
- package/esm2022/a11y/focus-trap/event-listener-inert-strategy.mjs +0 -61
- package/esm2022/a11y/focus-trap/focus-trap-inert-strategy.mjs +0 -11
- package/esm2022/a11y/focus-trap/focus-trap-manager.mjs +0 -53
- package/esm2022/a11y/focus-trap/focus-trap.mjs +0 -396
- package/esm2022/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +0 -116
- package/esm2022/a11y/index.mjs +0 -9
- package/esm2022/a11y/input-modality/input-modality-detector.mjs +0 -176
- package/esm2022/a11y/interactivity-checker/interactivity-checker.mjs +0 -238
- package/esm2022/a11y/key-manager/activedescendant-key-manager.mjs +0 -20
- package/esm2022/a11y/key-manager/focus-key-manager.mjs +0 -29
- package/esm2022/a11y/key-manager/list-key-manager.mjs +0 -357
- package/esm2022/a11y/key-manager/noop-tree-key-manager.mjs +0 -94
- package/esm2022/a11y/key-manager/tree-key-manager-strategy.mjs +0 -9
- package/esm2022/a11y/key-manager/tree-key-manager.mjs +0 -345
- package/esm2022/a11y/key-manager/typeahead.mjs +0 -91
- package/esm2022/a11y/live-announcer/live-announcer-tokens.mjs +0 -19
- package/esm2022/a11y/live-announcer/live-announcer.mjs +0 -210
- package/esm2022/a11y/public-api.mjs +0 -30
- package/esm2022/accordion/accordion-item.mjs +0 -162
- package/esm2022/accordion/accordion-module.mjs +0 -24
- package/esm2022/accordion/accordion.mjs +0 -65
- package/esm2022/accordion/accordion_public_index.mjs +0 -5
- package/esm2022/accordion/index.mjs +0 -9
- package/esm2022/accordion/public-api.mjs +0 -11
- package/esm2022/bidi/bidi-module.mjs +0 -23
- package/esm2022/bidi/bidi_public_index.mjs +0 -5
- package/esm2022/bidi/dir-document-token.mjs +0 -33
- package/esm2022/bidi/dir.mjs +0 -70
- package/esm2022/bidi/directionality.mjs +0 -52
- package/esm2022/bidi/index.mjs +0 -9
- package/esm2022/bidi/public-api.mjs +0 -12
- package/esm2022/clipboard/clipboard-module.mjs +0 -23
- package/esm2022/clipboard/clipboard.mjs +0 -53
- package/esm2022/clipboard/clipboard_public_index.mjs +0 -5
- package/esm2022/clipboard/copy-to-clipboard.mjs +0 -100
- package/esm2022/clipboard/index.mjs +0 -9
- package/esm2022/clipboard/pending-copy.mjs +0 -71
- package/esm2022/clipboard/public-api.mjs +0 -12
- package/esm2022/coercion/array.mjs +0 -11
- package/esm2022/coercion/boolean-property.mjs +0 -12
- package/esm2022/coercion/css-pixel-value.mjs +0 -15
- package/esm2022/coercion/element.mjs +0 -16
- package/esm2022/coercion/index.mjs +0 -9
- package/esm2022/coercion/number-property.mjs +0 -24
- package/esm2022/coercion/private/index.mjs +0 -9
- package/esm2022/coercion/private/observable.mjs +0 -19
- package/esm2022/coercion/private/private_public_index.mjs +0 -5
- package/esm2022/coercion/public-api.mjs +0 -14
- package/esm2022/coercion/string-array.mjs +0 -38
- package/esm2022/collections/array-data-source.mjs +0 -21
- package/esm2022/collections/collection-viewer.mjs +0 -9
- package/esm2022/collections/collections_public_index.mjs +0 -5
- package/esm2022/collections/data-source.mjs +0 -19
- package/esm2022/collections/dispose-view-repeater-strategy.mjs +0 -48
- package/esm2022/collections/index.mjs +0 -9
- package/esm2022/collections/public-api.mjs +0 -17
- package/esm2022/collections/recycle-view-repeater-strategy.mjs +0 -129
- package/esm2022/collections/selection-model.mjs +0 -225
- package/esm2022/collections/tree-adapter.mjs +0 -9
- package/esm2022/collections/unique-selection-dispatcher.mjs +0 -55
- package/esm2022/collections/view-repeater.mjs +0 -26
- package/esm2022/dialog/dialog-config.mjs +0 -70
- package/esm2022/dialog/dialog-container.mjs +0 -308
- package/esm2022/dialog/dialog-injectors.mjs +0 -40
- package/esm2022/dialog/dialog-module.mjs +0 -40
- package/esm2022/dialog/dialog-ref.mjs +0 -85
- package/esm2022/dialog/dialog.mjs +0 -303
- package/esm2022/dialog/dialog_public_index.mjs +0 -5
- package/esm2022/dialog/index.mjs +0 -9
- package/esm2022/dialog/public-api.mjs +0 -14
- package/esm2022/drag-drop/directives/assertions.mjs +0 -18
- package/esm2022/drag-drop/directives/config.mjs +0 -14
- package/esm2022/drag-drop/directives/drag-handle.mjs +0 -68
- package/esm2022/drag-drop/directives/drag-placeholder.mjs +0 -43
- package/esm2022/drag-drop/directives/drag-preview.mjs +0 -48
- package/esm2022/drag-drop/directives/drag.mjs +0 -520
- package/esm2022/drag-drop/directives/drop-list-group.mjs +0 -47
- package/esm2022/drag-drop/directives/drop-list.mjs +0 -352
- package/esm2022/drag-drop/dom/clone-node.mjs +0 -65
- package/esm2022/drag-drop/dom/dom-rect.mjs +0 -64
- package/esm2022/drag-drop/dom/parent-position-tracker.mjs +0 -76
- package/esm2022/drag-drop/dom/root-node.mjs +0 -21
- package/esm2022/drag-drop/dom/styling.mjs +0 -89
- package/esm2022/drag-drop/dom/transition-duration.mjs +0 -36
- package/esm2022/drag-drop/drag-drop-module.mjs +0 -49
- package/esm2022/drag-drop/drag-drop-registry.mjs +0 -266
- package/esm2022/drag-drop/drag-drop.mjs +0 -57
- package/esm2022/drag-drop/drag-drop_public_index.mjs +0 -5
- package/esm2022/drag-drop/drag-events.mjs +0 -9
- package/esm2022/drag-drop/drag-parent.mjs +0 -16
- package/esm2022/drag-drop/drag-ref.mjs +0 -1097
- package/esm2022/drag-drop/drag-utils.mjs +0 -60
- package/esm2022/drag-drop/drop-list-ref.mjs +0 -672
- package/esm2022/drag-drop/index.mjs +0 -9
- package/esm2022/drag-drop/preview-ref.mjs +0 -117
- package/esm2022/drag-drop/public-api.mjs +0 -23
- package/esm2022/drag-drop/sorting/drop-list-sort-strategy.mjs +0 -9
- package/esm2022/drag-drop/sorting/mixed-sort-strategy.mjs +0 -246
- package/esm2022/drag-drop/sorting/single-axis-sort-strategy.mjs +0 -343
- package/esm2022/index.mjs +0 -9
- package/esm2022/keycodes/index.mjs +0 -9
- package/esm2022/keycodes/keycodes.mjs +0 -127
- package/esm2022/keycodes/keycodes_public_index.mjs +0 -5
- package/esm2022/keycodes/modifiers.mjs +0 -18
- package/esm2022/keycodes/public-api.mjs +0 -10
- package/esm2022/layout/breakpoints-observer.mjs +0 -105
- package/esm2022/layout/breakpoints.mjs +0 -29
- package/esm2022/layout/index.mjs +0 -9
- package/esm2022/layout/layout-module.mjs +0 -19
- package/esm2022/layout/layout_public_index.mjs +0 -5
- package/esm2022/layout/media-matcher.mjs +0 -94
- package/esm2022/layout/public-api.mjs +0 -12
- package/esm2022/listbox/index.mjs +0 -9
- package/esm2022/listbox/listbox-module.mjs +0 -24
- package/esm2022/listbox/listbox.mjs +0 -888
- package/esm2022/listbox/listbox_public_index.mjs +0 -5
- package/esm2022/listbox/public-api.mjs +0 -10
- package/esm2022/menu/context-menu-trigger.mjs +0 -221
- package/esm2022/menu/event-detection.mjs +0 -28
- package/esm2022/menu/index.mjs +0 -9
- package/esm2022/menu/menu-aim.mjs +0 -204
- package/esm2022/menu/menu-bar.mjs +0 -134
- package/esm2022/menu/menu-base.mjs +0 -192
- package/esm2022/menu/menu-errors.mjs +0 -22
- package/esm2022/menu/menu-group.mjs +0 -31
- package/esm2022/menu/menu-interface.mjs +0 -11
- package/esm2022/menu/menu-item-checkbox.mjs +0 -50
- package/esm2022/menu/menu-item-radio.mjs +0 -72
- package/esm2022/menu/menu-item-selectable.mjs +0 -36
- package/esm2022/menu/menu-item.mjs +0 -270
- package/esm2022/menu/menu-module.mjs +0 -60
- package/esm2022/menu/menu-stack.mjs +0 -163
- package/esm2022/menu/menu-trigger-base.mjs +0 -119
- package/esm2022/menu/menu-trigger.mjs +0 -313
- package/esm2022/menu/menu.mjs +0 -135
- package/esm2022/menu/menu_public_index.mjs +0 -5
- package/esm2022/menu/pointer-focus-tracker.mjs +0 -51
- package/esm2022/menu/public-api.mjs +0 -24
- package/esm2022/observers/index.mjs +0 -9
- package/esm2022/observers/observe-content.mjs +0 -216
- package/esm2022/observers/observers_public_index.mjs +0 -5
- package/esm2022/observers/private/index.mjs +0 -9
- package/esm2022/observers/private/private_public_index.mjs +0 -5
- package/esm2022/observers/private/shared-resize-observer.mjs +0 -125
- package/esm2022/observers/public-api.mjs +0 -9
- package/esm2022/overlay/dispatchers/base-overlay-dispatcher.mjs +0 -52
- package/esm2022/overlay/dispatchers/index.mjs +0 -10
- package/esm2022/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +0 -81
- package/esm2022/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +0 -151
- package/esm2022/overlay/fullscreen-overlay-container.mjs +0 -94
- package/esm2022/overlay/index.mjs +0 -9
- package/esm2022/overlay/overlay-config.mjs +0 -45
- package/esm2022/overlay/overlay-container.mjs +0 -81
- package/esm2022/overlay/overlay-directives.mjs +0 -432
- package/esm2022/overlay/overlay-module.mjs +0 -28
- package/esm2022/overlay/overlay-ref.mjs +0 -437
- package/esm2022/overlay/overlay.mjs +0 -126
- package/esm2022/overlay/overlay_public_index.mjs +0 -5
- package/esm2022/overlay/position/connected-position.mjs +0 -88
- package/esm2022/overlay/position/flexible-connected-position-strategy.mjs +0 -1002
- package/esm2022/overlay/position/global-position-strategy.mjs +0 -237
- package/esm2022/overlay/position/overlay-position-builder.mjs +0 -50
- package/esm2022/overlay/position/position-strategy.mjs +0 -9
- package/esm2022/overlay/position/scroll-clip.mjs +0 -40
- package/esm2022/overlay/public-api.mjs +0 -22
- package/esm2022/overlay/scroll/block-scroll-strategy.mjs +0 -80
- package/esm2022/overlay/scroll/close-scroll-strategy.mjs +0 -65
- package/esm2022/overlay/scroll/index.mjs +0 -14
- package/esm2022/overlay/scroll/noop-scroll-strategy.mjs +0 -17
- package/esm2022/overlay/scroll/reposition-scroll-strategy.mjs +0 -61
- package/esm2022/overlay/scroll/scroll-strategy-options.mjs +0 -55
- package/esm2022/overlay/scroll/scroll-strategy.mjs +0 -14
- package/esm2022/platform/features/input-types.mjs +0 -59
- package/esm2022/platform/features/passive-listeners.mjs +0 -36
- package/esm2022/platform/features/scrolling.mjs +0 -104
- package/esm2022/platform/features/shadow-dom.mjs +0 -54
- package/esm2022/platform/features/test-environment.mjs +0 -24
- package/esm2022/platform/index.mjs +0 -9
- package/esm2022/platform/platform-module.mjs +0 -19
- package/esm2022/platform/platform.mjs +0 -85
- package/esm2022/platform/platform_public_index.mjs +0 -5
- package/esm2022/platform/public-api.mjs +0 -15
- package/esm2022/portal/dom-portal-outlet.mjs +0 -158
- package/esm2022/portal/index.mjs +0 -9
- package/esm2022/portal/portal-directives.mjs +0 -251
- package/esm2022/portal/portal-errors.mjs +0 -51
- package/esm2022/portal/portal-injector.mjs +0 -28
- package/esm2022/portal/portal.mjs +0 -189
- package/esm2022/portal/portal_public_index.mjs +0 -5
- package/esm2022/portal/public-api.mjs +0 -12
- package/esm2022/public-api.mjs +0 -9
- package/esm2022/scrolling/fixed-size-virtual-scroll.mjs +0 -218
- package/esm2022/scrolling/index.mjs +0 -9
- package/esm2022/scrolling/public-api.mjs +0 -20
- package/esm2022/scrolling/scroll-dispatcher.mjs +0 -163
- package/esm2022/scrolling/scrollable.mjs +0 -177
- package/esm2022/scrolling/scrolling-module.mjs +0 -69
- package/esm2022/scrolling/scrolling_public_index.mjs +0 -5
- package/esm2022/scrolling/viewport-ruler.mjs +0 -146
- package/esm2022/scrolling/virtual-for-of.mjs +0 -299
- package/esm2022/scrolling/virtual-scroll-repeater.mjs +0 -9
- package/esm2022/scrolling/virtual-scroll-strategy.mjs +0 -11
- package/esm2022/scrolling/virtual-scroll-viewport.mjs +0 -445
- package/esm2022/scrolling/virtual-scrollable-element.mjs +0 -42
- package/esm2022/scrolling/virtual-scrollable-window.mjs +0 -41
- package/esm2022/scrolling/virtual-scrollable.mjs +0 -40
- package/esm2022/stepper/index.mjs +0 -9
- package/esm2022/stepper/public-api.mjs +0 -13
- package/esm2022/stepper/step-header.mjs +0 -31
- package/esm2022/stepper/step-label.mjs +0 -24
- package/esm2022/stepper/stepper-button.mjs +0 -58
- package/esm2022/stepper/stepper-module.mjs +0 -41
- package/esm2022/stepper/stepper.mjs +0 -452
- package/esm2022/stepper/stepper_public_index.mjs +0 -5
- package/esm2022/table/can-stick.mjs +0 -46
- package/esm2022/table/cell.mjs +0 -245
- package/esm2022/table/coalesced-style-scheduler.mjs +0 -79
- package/esm2022/table/index.mjs +0 -9
- package/esm2022/table/public-api.mjs +0 -20
- package/esm2022/table/row.mjs +0 -317
- package/esm2022/table/sticky-position-listener.mjs +0 -11
- package/esm2022/table/sticky-styler.mjs +0 -347
- package/esm2022/table/table-errors.mjs +0 -67
- package/esm2022/table/table-module.mjs +0 -93
- package/esm2022/table/table.mjs +0 -1148
- package/esm2022/table/table_public_index.mjs +0 -5
- package/esm2022/table/text-column.mjs +0 -154
- package/esm2022/table/tokens.mjs +0 -16
- package/esm2022/testing/change-detection.mjs +0 -102
- package/esm2022/testing/component-harness.mjs +0 -328
- package/esm2022/testing/element-dimensions.mjs +0 -9
- package/esm2022/testing/harness-environment.mjs +0 -220
- package/esm2022/testing/index.mjs +0 -9
- package/esm2022/testing/public-api.mjs +0 -15
- package/esm2022/testing/selenium-webdriver/index.mjs +0 -9
- package/esm2022/testing/selenium-webdriver/public-api.mjs +0 -10
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-element.mjs +0 -216
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +0 -88
- package/esm2022/testing/selenium-webdriver/selenium-webdriver-keys.mjs +0 -64
- package/esm2022/testing/test-element-errors.mjs +0 -15
- package/esm2022/testing/test-element.mjs +0 -49
- package/esm2022/testing/testbed/fake-events/dispatch-events.mjs +0 -53
- package/esm2022/testing/testbed/fake-events/element-focus.mjs +0 -39
- package/esm2022/testing/testbed/fake-events/event-objects.mjs +0 -127
- package/esm2022/testing/testbed/fake-events/index.mjs +0 -14
- package/esm2022/testing/testbed/fake-events/type-in-element.mjs +0 -97
- package/esm2022/testing/testbed/index.mjs +0 -9
- package/esm2022/testing/testbed/public-api.mjs +0 -10
- package/esm2022/testing/testbed/task-state-zone-interceptor.mjs +0 -82
- package/esm2022/testing/testbed/testbed-harness-environment.mjs +0 -165
- package/esm2022/testing/testbed/unit-test-element.mjs +0 -258
- package/esm2022/testing/text-filtering.mjs +0 -21
- package/esm2022/text-field/autofill.mjs +0 -114
- package/esm2022/text-field/autosize.mjs +0 -309
- package/esm2022/text-field/index.mjs +0 -9
- package/esm2022/text-field/public-api.mjs +0 -11
- package/esm2022/text-field/text-field-module.mjs +0 -24
- package/esm2022/text-field/text-field_public_index.mjs +0 -5
- package/esm2022/tree/control/base-tree-control.mjs +0 -62
- package/esm2022/tree/control/flat-tree-control.mjs +0 -57
- package/esm2022/tree/control/nested-tree-control.mjs +0 -67
- package/esm2022/tree/control/tree-control.mjs +0 -2
- package/esm2022/tree/index.mjs +0 -9
- package/esm2022/tree/nested-node.mjs +0 -103
- package/esm2022/tree/node.mjs +0 -36
- package/esm2022/tree/outlet.mjs +0 -40
- package/esm2022/tree/padding.mjs +0 -129
- package/esm2022/tree/public-api.mjs +0 -20
- package/esm2022/tree/toggle.mjs +0 -51
- package/esm2022/tree/tree-errors.mjs +0 -44
- package/esm2022/tree/tree-module.mjs +0 -49
- package/esm2022/tree/tree.mjs +0 -1123
- package/esm2022/tree/tree_public_index.mjs +0 -5
- package/esm2022/version.mjs +0 -11
package/esm2022/table/table.mjs
DELETED
|
@@ -1,1148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { Directionality } from '@angular/cdk/bidi';
|
|
9
|
-
import { _DisposeViewRepeaterStrategy, _RecycleViewRepeaterStrategy, isDataSource, _VIEW_REPEATER_STRATEGY, _ViewRepeaterOperation, } from '@angular/cdk/collections';
|
|
10
|
-
import { Platform } from '@angular/cdk/platform';
|
|
11
|
-
import { ViewportRuler } from '@angular/cdk/scrolling';
|
|
12
|
-
import { DOCUMENT } from '@angular/common';
|
|
13
|
-
import { Attribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, Directive, ElementRef, EmbeddedViewRef, EventEmitter, Inject, Input, IterableDiffers, NgZone, Optional, Output, QueryList, SkipSelf, ViewContainerRef, ViewEncapsulation, booleanAttribute, inject, afterNextRender, Injector, } from '@angular/core';
|
|
14
|
-
import { BehaviorSubject, isObservable, of as observableOf, Subject, } from 'rxjs';
|
|
15
|
-
import { takeUntil } from 'rxjs/operators';
|
|
16
|
-
import { CdkColumnDef } from './cell';
|
|
17
|
-
import { _CoalescedStyleScheduler, _COALESCED_STYLE_SCHEDULER } from './coalesced-style-scheduler';
|
|
18
|
-
import { CdkCellOutlet, CdkFooterRowDef, CdkHeaderRowDef, CdkNoDataRow, CdkRowDef, } from './row';
|
|
19
|
-
import { StickyStyler } from './sticky-styler';
|
|
20
|
-
import { getTableDuplicateColumnNameError, getTableMissingMatchingRowDefError, getTableMissingRowDefsError, getTableMultipleDefaultRowDefsError, getTableUnknownColumnError, getTableUnknownDataSourceError, } from './table-errors';
|
|
21
|
-
import { STICKY_POSITIONING_LISTENER } from './sticky-position-listener';
|
|
22
|
-
import { CDK_TABLE } from './tokens';
|
|
23
|
-
import * as i0 from "@angular/core";
|
|
24
|
-
import * as i1 from "@angular/cdk/bidi";
|
|
25
|
-
import * as i2 from "@angular/cdk/platform";
|
|
26
|
-
import * as i3 from "@angular/cdk/scrolling";
|
|
27
|
-
import * as i4 from "./coalesced-style-scheduler";
|
|
28
|
-
/**
|
|
29
|
-
* Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
|
|
30
|
-
* tables that animate rows.
|
|
31
|
-
*/
|
|
32
|
-
export class CdkRecycleRows {
|
|
33
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkRecycleRows, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
34
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: CdkRecycleRows, isStandalone: true, selector: "cdk-table[recycleRows], table[cdk-table][recycleRows]", providers: [{ provide: _VIEW_REPEATER_STRATEGY, useClass: _RecycleViewRepeaterStrategy }], ngImport: i0 }); }
|
|
35
|
-
}
|
|
36
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkRecycleRows, decorators: [{
|
|
37
|
-
type: Directive,
|
|
38
|
-
args: [{
|
|
39
|
-
selector: 'cdk-table[recycleRows], table[cdk-table][recycleRows]',
|
|
40
|
-
providers: [{ provide: _VIEW_REPEATER_STRATEGY, useClass: _RecycleViewRepeaterStrategy }],
|
|
41
|
-
standalone: true,
|
|
42
|
-
}]
|
|
43
|
-
}] });
|
|
44
|
-
/**
|
|
45
|
-
* Provides a handle for the table to grab the view container's ng-container to insert data rows.
|
|
46
|
-
* @docs-private
|
|
47
|
-
*/
|
|
48
|
-
export class DataRowOutlet {
|
|
49
|
-
constructor(viewContainer, elementRef) {
|
|
50
|
-
this.viewContainer = viewContainer;
|
|
51
|
-
this.elementRef = elementRef;
|
|
52
|
-
const table = inject(CDK_TABLE);
|
|
53
|
-
table._rowOutlet = this;
|
|
54
|
-
table._outletAssigned();
|
|
55
|
-
}
|
|
56
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: DataRowOutlet, deps: [{ token: i0.ViewContainerRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
57
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: DataRowOutlet, isStandalone: true, selector: "[rowOutlet]", ngImport: i0 }); }
|
|
58
|
-
}
|
|
59
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: DataRowOutlet, decorators: [{
|
|
60
|
-
type: Directive,
|
|
61
|
-
args: [{
|
|
62
|
-
selector: '[rowOutlet]',
|
|
63
|
-
standalone: true,
|
|
64
|
-
}]
|
|
65
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ElementRef }] });
|
|
66
|
-
/**
|
|
67
|
-
* Provides a handle for the table to grab the view container's ng-container to insert the header.
|
|
68
|
-
* @docs-private
|
|
69
|
-
*/
|
|
70
|
-
export class HeaderRowOutlet {
|
|
71
|
-
constructor(viewContainer, elementRef) {
|
|
72
|
-
this.viewContainer = viewContainer;
|
|
73
|
-
this.elementRef = elementRef;
|
|
74
|
-
const table = inject(CDK_TABLE);
|
|
75
|
-
table._headerRowOutlet = this;
|
|
76
|
-
table._outletAssigned();
|
|
77
|
-
}
|
|
78
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: HeaderRowOutlet, deps: [{ token: i0.ViewContainerRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
79
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: HeaderRowOutlet, isStandalone: true, selector: "[headerRowOutlet]", ngImport: i0 }); }
|
|
80
|
-
}
|
|
81
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: HeaderRowOutlet, decorators: [{
|
|
82
|
-
type: Directive,
|
|
83
|
-
args: [{
|
|
84
|
-
selector: '[headerRowOutlet]',
|
|
85
|
-
standalone: true,
|
|
86
|
-
}]
|
|
87
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ElementRef }] });
|
|
88
|
-
/**
|
|
89
|
-
* Provides a handle for the table to grab the view container's ng-container to insert the footer.
|
|
90
|
-
* @docs-private
|
|
91
|
-
*/
|
|
92
|
-
export class FooterRowOutlet {
|
|
93
|
-
constructor(viewContainer, elementRef) {
|
|
94
|
-
this.viewContainer = viewContainer;
|
|
95
|
-
this.elementRef = elementRef;
|
|
96
|
-
const table = inject(CDK_TABLE);
|
|
97
|
-
table._footerRowOutlet = this;
|
|
98
|
-
table._outletAssigned();
|
|
99
|
-
}
|
|
100
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: FooterRowOutlet, deps: [{ token: i0.ViewContainerRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
101
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: FooterRowOutlet, isStandalone: true, selector: "[footerRowOutlet]", ngImport: i0 }); }
|
|
102
|
-
}
|
|
103
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: FooterRowOutlet, decorators: [{
|
|
104
|
-
type: Directive,
|
|
105
|
-
args: [{
|
|
106
|
-
selector: '[footerRowOutlet]',
|
|
107
|
-
standalone: true,
|
|
108
|
-
}]
|
|
109
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ElementRef }] });
|
|
110
|
-
/**
|
|
111
|
-
* Provides a handle for the table to grab the view
|
|
112
|
-
* container's ng-container to insert the no data row.
|
|
113
|
-
* @docs-private
|
|
114
|
-
*/
|
|
115
|
-
export class NoDataRowOutlet {
|
|
116
|
-
constructor(viewContainer, elementRef) {
|
|
117
|
-
this.viewContainer = viewContainer;
|
|
118
|
-
this.elementRef = elementRef;
|
|
119
|
-
const table = inject(CDK_TABLE);
|
|
120
|
-
table._noDataRowOutlet = this;
|
|
121
|
-
table._outletAssigned();
|
|
122
|
-
}
|
|
123
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: NoDataRowOutlet, deps: [{ token: i0.ViewContainerRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
124
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.0-next.2", type: NoDataRowOutlet, isStandalone: true, selector: "[noDataRowOutlet]", ngImport: i0 }); }
|
|
125
|
-
}
|
|
126
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: NoDataRowOutlet, decorators: [{
|
|
127
|
-
type: Directive,
|
|
128
|
-
args: [{
|
|
129
|
-
selector: '[noDataRowOutlet]',
|
|
130
|
-
standalone: true,
|
|
131
|
-
}]
|
|
132
|
-
}], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.ElementRef }] });
|
|
133
|
-
/**
|
|
134
|
-
* The table template that can be used by the mat-table. Should not be used outside of the
|
|
135
|
-
* material library.
|
|
136
|
-
* @docs-private
|
|
137
|
-
*/
|
|
138
|
-
export const CDK_TABLE_TEMPLATE =
|
|
139
|
-
// Note that according to MDN, the `caption` element has to be projected as the **first**
|
|
140
|
-
// element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption
|
|
141
|
-
`
|
|
142
|
-
<ng-content select="caption"/>
|
|
143
|
-
<ng-content select="colgroup, col"/>
|
|
144
|
-
|
|
145
|
-
<!--
|
|
146
|
-
Unprojected content throws a hydration error so we need this to capture it.
|
|
147
|
-
It gets removed on the client so it doesn't affect the layout.
|
|
148
|
-
-->
|
|
149
|
-
@if (_isServer) {
|
|
150
|
-
<ng-content/>
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
@if (_isNativeHtmlTable) {
|
|
154
|
-
<thead role="rowgroup">
|
|
155
|
-
<ng-container headerRowOutlet/>
|
|
156
|
-
</thead>
|
|
157
|
-
<tbody role="rowgroup">
|
|
158
|
-
<ng-container rowOutlet/>
|
|
159
|
-
<ng-container noDataRowOutlet/>
|
|
160
|
-
</tbody>
|
|
161
|
-
<tfoot role="rowgroup">
|
|
162
|
-
<ng-container footerRowOutlet/>
|
|
163
|
-
</tfoot>
|
|
164
|
-
} @else {
|
|
165
|
-
<ng-container headerRowOutlet/>
|
|
166
|
-
<ng-container rowOutlet/>
|
|
167
|
-
<ng-container noDataRowOutlet/>
|
|
168
|
-
<ng-container footerRowOutlet/>
|
|
169
|
-
}
|
|
170
|
-
`;
|
|
171
|
-
/**
|
|
172
|
-
* Class used to conveniently type the embedded view ref for rows with a context.
|
|
173
|
-
* @docs-private
|
|
174
|
-
*/
|
|
175
|
-
class RowViewRef extends EmbeddedViewRef {
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* A data table that can render a header row, data rows, and a footer row.
|
|
179
|
-
* Uses the dataSource input to determine the data to be rendered. The data can be provided either
|
|
180
|
-
* as a data array, an Observable stream that emits the data array to render, or a DataSource with a
|
|
181
|
-
* connect function that will return an Observable stream that emits the data array to render.
|
|
182
|
-
*/
|
|
183
|
-
export class CdkTable {
|
|
184
|
-
/** Aria role to apply to the table's cells based on the table's own role. */
|
|
185
|
-
_getCellRole() {
|
|
186
|
-
if (this._cellRoleInternal === undefined) {
|
|
187
|
-
// Perform this lazily in case the table's role was updated by a directive after construction.
|
|
188
|
-
const role = this._elementRef.nativeElement.getAttribute('role');
|
|
189
|
-
const cellRole = role === 'grid' || role === 'treegrid' ? 'gridcell' : 'cell';
|
|
190
|
-
this._cellRoleInternal = this._isNativeHtmlTable && cellRole === 'cell' ? null : cellRole;
|
|
191
|
-
}
|
|
192
|
-
return this._cellRoleInternal;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Tracking function that will be used to check the differences in data changes. Used similarly
|
|
196
|
-
* to `ngFor` `trackBy` function. Optimize row operations by identifying a row based on its data
|
|
197
|
-
* relative to the function to know if a row should be added/removed/moved.
|
|
198
|
-
* Accepts a function that takes two parameters, `index` and `item`.
|
|
199
|
-
*/
|
|
200
|
-
get trackBy() {
|
|
201
|
-
return this._trackByFn;
|
|
202
|
-
}
|
|
203
|
-
set trackBy(fn) {
|
|
204
|
-
if ((typeof ngDevMode === 'undefined' || ngDevMode) && fn != null && typeof fn !== 'function') {
|
|
205
|
-
console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}.`);
|
|
206
|
-
}
|
|
207
|
-
this._trackByFn = fn;
|
|
208
|
-
}
|
|
209
|
-
/**
|
|
210
|
-
* The table's source of data, which can be provided in three ways (in order of complexity):
|
|
211
|
-
* - Simple data array (each object represents one table row)
|
|
212
|
-
* - Stream that emits a data array each time the array changes
|
|
213
|
-
* - `DataSource` object that implements the connect/disconnect interface.
|
|
214
|
-
*
|
|
215
|
-
* If a data array is provided, the table must be notified when the array's objects are
|
|
216
|
-
* added, removed, or moved. This can be done by calling the `renderRows()` function which will
|
|
217
|
-
* render the diff since the last table render. If the data array reference is changed, the table
|
|
218
|
-
* will automatically trigger an update to the rows.
|
|
219
|
-
*
|
|
220
|
-
* When providing an Observable stream, the table will trigger an update automatically when the
|
|
221
|
-
* stream emits a new array of data.
|
|
222
|
-
*
|
|
223
|
-
* Finally, when providing a `DataSource` object, the table will use the Observable stream
|
|
224
|
-
* provided by the connect function and trigger updates when that stream emits new data array
|
|
225
|
-
* values. During the table's ngOnDestroy or when the data source is removed from the table, the
|
|
226
|
-
* table will call the DataSource's `disconnect` function (may be useful for cleaning up any
|
|
227
|
-
* subscriptions registered during the connect process).
|
|
228
|
-
*/
|
|
229
|
-
get dataSource() {
|
|
230
|
-
return this._dataSource;
|
|
231
|
-
}
|
|
232
|
-
set dataSource(dataSource) {
|
|
233
|
-
if (this._dataSource !== dataSource) {
|
|
234
|
-
this._switchDataSource(dataSource);
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Whether to allow multiple rows per data object by evaluating which rows evaluate their 'when'
|
|
239
|
-
* predicate to true. If `multiTemplateDataRows` is false, which is the default value, then each
|
|
240
|
-
* dataobject will render the first row that evaluates its when predicate to true, in the order
|
|
241
|
-
* defined in the table, or otherwise the default row which does not have a when predicate.
|
|
242
|
-
*/
|
|
243
|
-
get multiTemplateDataRows() {
|
|
244
|
-
return this._multiTemplateDataRows;
|
|
245
|
-
}
|
|
246
|
-
set multiTemplateDataRows(value) {
|
|
247
|
-
this._multiTemplateDataRows = value;
|
|
248
|
-
// In Ivy if this value is set via a static attribute (e.g. <table multiTemplateDataRows>),
|
|
249
|
-
// this setter will be invoked before the row outlet has been defined hence the null check.
|
|
250
|
-
if (this._rowOutlet && this._rowOutlet.viewContainer.length) {
|
|
251
|
-
this._forceRenderDataRows();
|
|
252
|
-
this.updateStickyColumnStyles();
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Whether to use a fixed table layout. Enabling this option will enforce consistent column widths
|
|
257
|
-
* and optimize rendering sticky styles for native tables. No-op for flex tables.
|
|
258
|
-
*/
|
|
259
|
-
get fixedLayout() {
|
|
260
|
-
return this._fixedLayout;
|
|
261
|
-
}
|
|
262
|
-
set fixedLayout(value) {
|
|
263
|
-
this._fixedLayout = value;
|
|
264
|
-
// Toggling `fixedLayout` may change column widths. Sticky column styles should be recalculated.
|
|
265
|
-
this._forceRecalculateCellWidths = true;
|
|
266
|
-
this._stickyColumnStylesNeedReset = true;
|
|
267
|
-
}
|
|
268
|
-
constructor(_differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform, _viewRepeater, _coalescedStyleScheduler, _viewportRuler,
|
|
269
|
-
/**
|
|
270
|
-
* @deprecated `_stickyPositioningListener` parameter to become required.
|
|
271
|
-
* @breaking-change 13.0.0
|
|
272
|
-
*/
|
|
273
|
-
_stickyPositioningListener,
|
|
274
|
-
/**
|
|
275
|
-
* @deprecated `_unusedNgZone` parameter to be removed.
|
|
276
|
-
* @breaking-change 19.0.0
|
|
277
|
-
*/
|
|
278
|
-
_unusedNgZone) {
|
|
279
|
-
this._differs = _differs;
|
|
280
|
-
this._changeDetectorRef = _changeDetectorRef;
|
|
281
|
-
this._elementRef = _elementRef;
|
|
282
|
-
this._dir = _dir;
|
|
283
|
-
this._platform = _platform;
|
|
284
|
-
this._viewRepeater = _viewRepeater;
|
|
285
|
-
this._coalescedStyleScheduler = _coalescedStyleScheduler;
|
|
286
|
-
this._viewportRuler = _viewportRuler;
|
|
287
|
-
this._stickyPositioningListener = _stickyPositioningListener;
|
|
288
|
-
/** Subject that emits when the component has been destroyed. */
|
|
289
|
-
this._onDestroy = new Subject();
|
|
290
|
-
/**
|
|
291
|
-
* Map of all the user's defined columns (header, data, and footer cell template) identified by
|
|
292
|
-
* name. Collection populated by the column definitions gathered by `ContentChildren` as well as
|
|
293
|
-
* any custom column definitions added to `_customColumnDefs`.
|
|
294
|
-
*/
|
|
295
|
-
this._columnDefsByName = new Map();
|
|
296
|
-
/**
|
|
297
|
-
* Column definitions that were defined outside of the direct content children of the table.
|
|
298
|
-
* These will be defined when, e.g., creating a wrapper around the cdkTable that has
|
|
299
|
-
* column definitions as *its* content child.
|
|
300
|
-
*/
|
|
301
|
-
this._customColumnDefs = new Set();
|
|
302
|
-
/**
|
|
303
|
-
* Data row definitions that were defined outside of the direct content children of the table.
|
|
304
|
-
* These will be defined when, e.g., creating a wrapper around the cdkTable that has
|
|
305
|
-
* built-in data rows as *its* content child.
|
|
306
|
-
*/
|
|
307
|
-
this._customRowDefs = new Set();
|
|
308
|
-
/**
|
|
309
|
-
* Header row definitions that were defined outside of the direct content children of the table.
|
|
310
|
-
* These will be defined when, e.g., creating a wrapper around the cdkTable that has
|
|
311
|
-
* built-in header rows as *its* content child.
|
|
312
|
-
*/
|
|
313
|
-
this._customHeaderRowDefs = new Set();
|
|
314
|
-
/**
|
|
315
|
-
* Footer row definitions that were defined outside of the direct content children of the table.
|
|
316
|
-
* These will be defined when, e.g., creating a wrapper around the cdkTable that has a
|
|
317
|
-
* built-in footer row as *its* content child.
|
|
318
|
-
*/
|
|
319
|
-
this._customFooterRowDefs = new Set();
|
|
320
|
-
/**
|
|
321
|
-
* Whether the header row definition has been changed. Triggers an update to the header row after
|
|
322
|
-
* content is checked. Initialized as true so that the table renders the initial set of rows.
|
|
323
|
-
*/
|
|
324
|
-
this._headerRowDefChanged = true;
|
|
325
|
-
/**
|
|
326
|
-
* Whether the footer row definition has been changed. Triggers an update to the footer row after
|
|
327
|
-
* content is checked. Initialized as true so that the table renders the initial set of rows.
|
|
328
|
-
*/
|
|
329
|
-
this._footerRowDefChanged = true;
|
|
330
|
-
/**
|
|
331
|
-
* Whether the sticky column styles need to be updated. Set to `true` when the visible columns
|
|
332
|
-
* change.
|
|
333
|
-
*/
|
|
334
|
-
this._stickyColumnStylesNeedReset = true;
|
|
335
|
-
/**
|
|
336
|
-
* Whether the sticky styler should recalculate cell widths when applying sticky styles. If
|
|
337
|
-
* `false`, cached values will be used instead. This is only applicable to tables with
|
|
338
|
-
* {@link fixedLayout} enabled. For other tables, cell widths will always be recalculated.
|
|
339
|
-
*/
|
|
340
|
-
this._forceRecalculateCellWidths = true;
|
|
341
|
-
/**
|
|
342
|
-
* Cache of the latest rendered `RenderRow` objects as a map for easy retrieval when constructing
|
|
343
|
-
* a new list of `RenderRow` objects for rendering rows. Since the new list is constructed with
|
|
344
|
-
* the cached `RenderRow` objects when possible, the row identity is preserved when the data
|
|
345
|
-
* and row template matches, which allows the `IterableDiffer` to check rows by reference
|
|
346
|
-
* and understand which rows are added/moved/removed.
|
|
347
|
-
*
|
|
348
|
-
* Implemented as a map of maps where the first key is the `data: T` object and the second is the
|
|
349
|
-
* `CdkRowDef<T>` object. With the two keys, the cache points to a `RenderRow<T>` object that
|
|
350
|
-
* contains an array of created pairs. The array is necessary to handle cases where the data
|
|
351
|
-
* array contains multiple duplicate data objects and each instantiated `RenderRow` must be
|
|
352
|
-
* stored.
|
|
353
|
-
*/
|
|
354
|
-
this._cachedRenderRowsMap = new Map();
|
|
355
|
-
/**
|
|
356
|
-
* CSS class added to any row or cell that has sticky positioning applied. May be overridden by
|
|
357
|
-
* table subclasses.
|
|
358
|
-
*/
|
|
359
|
-
this.stickyCssClass = 'cdk-table-sticky';
|
|
360
|
-
/**
|
|
361
|
-
* Whether to manually add position: sticky to all sticky cell elements. Not needed if
|
|
362
|
-
* the position is set in a selector associated with the value of stickyCssClass. May be
|
|
363
|
-
* overridden by table subclasses
|
|
364
|
-
*/
|
|
365
|
-
this.needsPositionStickyOnElement = true;
|
|
366
|
-
/** Whether the no data row is currently showing anything. */
|
|
367
|
-
this._isShowingNoDataRow = false;
|
|
368
|
-
/** Whether the table has rendered out all the outlets for the first time. */
|
|
369
|
-
this._hasAllOutlets = false;
|
|
370
|
-
/** Whether the table is done initializing. */
|
|
371
|
-
this._hasInitialized = false;
|
|
372
|
-
this._cellRoleInternal = undefined;
|
|
373
|
-
this._multiTemplateDataRows = false;
|
|
374
|
-
this._fixedLayout = false;
|
|
375
|
-
/**
|
|
376
|
-
* Emits when the table completes rendering a set of data rows based on the latest data from the
|
|
377
|
-
* data source, even if the set of rows is empty.
|
|
378
|
-
*/
|
|
379
|
-
this.contentChanged = new EventEmitter();
|
|
380
|
-
// TODO(andrewseguin): Remove max value as the end index
|
|
381
|
-
// and instead calculate the view on init and scroll.
|
|
382
|
-
/**
|
|
383
|
-
* Stream containing the latest information on what rows are being displayed on screen.
|
|
384
|
-
* Can be used by the data source to as a heuristic of what data should be provided.
|
|
385
|
-
*
|
|
386
|
-
* @docs-private
|
|
387
|
-
*/
|
|
388
|
-
this.viewChange = new BehaviorSubject({
|
|
389
|
-
start: 0,
|
|
390
|
-
end: Number.MAX_VALUE,
|
|
391
|
-
});
|
|
392
|
-
this._injector = inject(Injector);
|
|
393
|
-
if (!role) {
|
|
394
|
-
_elementRef.nativeElement.setAttribute('role', 'table');
|
|
395
|
-
}
|
|
396
|
-
this._document = _document;
|
|
397
|
-
this._isServer = !_platform.isBrowser;
|
|
398
|
-
this._isNativeHtmlTable = _elementRef.nativeElement.nodeName === 'TABLE';
|
|
399
|
-
}
|
|
400
|
-
ngOnInit() {
|
|
401
|
-
this._setupStickyStyler();
|
|
402
|
-
// Set up the trackBy function so that it uses the `RenderRow` as its identity by default. If
|
|
403
|
-
// the user has provided a custom trackBy, return the result of that function as evaluated
|
|
404
|
-
// with the values of the `RenderRow`'s data and index.
|
|
405
|
-
this._dataDiffer = this._differs.find([]).create((_i, dataRow) => {
|
|
406
|
-
return this.trackBy ? this.trackBy(dataRow.dataIndex, dataRow.data) : dataRow;
|
|
407
|
-
});
|
|
408
|
-
this._viewportRuler
|
|
409
|
-
.change()
|
|
410
|
-
.pipe(takeUntil(this._onDestroy))
|
|
411
|
-
.subscribe(() => {
|
|
412
|
-
this._forceRecalculateCellWidths = true;
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
ngAfterContentInit() {
|
|
416
|
-
this._hasInitialized = true;
|
|
417
|
-
}
|
|
418
|
-
ngAfterContentChecked() {
|
|
419
|
-
// Only start re-rendering in `ngAfterContentChecked` after the first render.
|
|
420
|
-
if (this._canRender()) {
|
|
421
|
-
this._render();
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
ngOnDestroy() {
|
|
425
|
-
[
|
|
426
|
-
this._rowOutlet?.viewContainer,
|
|
427
|
-
this._headerRowOutlet?.viewContainer,
|
|
428
|
-
this._footerRowOutlet?.viewContainer,
|
|
429
|
-
this._cachedRenderRowsMap,
|
|
430
|
-
this._customColumnDefs,
|
|
431
|
-
this._customRowDefs,
|
|
432
|
-
this._customHeaderRowDefs,
|
|
433
|
-
this._customFooterRowDefs,
|
|
434
|
-
this._columnDefsByName,
|
|
435
|
-
].forEach((def) => {
|
|
436
|
-
def?.clear();
|
|
437
|
-
});
|
|
438
|
-
this._headerRowDefs = [];
|
|
439
|
-
this._footerRowDefs = [];
|
|
440
|
-
this._defaultRowDef = null;
|
|
441
|
-
this._onDestroy.next();
|
|
442
|
-
this._onDestroy.complete();
|
|
443
|
-
if (isDataSource(this.dataSource)) {
|
|
444
|
-
this.dataSource.disconnect(this);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
/**
|
|
448
|
-
* Renders rows based on the table's latest set of data, which was either provided directly as an
|
|
449
|
-
* input or retrieved through an Observable stream (directly or from a DataSource).
|
|
450
|
-
* Checks for differences in the data since the last diff to perform only the necessary
|
|
451
|
-
* changes (add/remove/move rows).
|
|
452
|
-
*
|
|
453
|
-
* If the table's data source is a DataSource or Observable, this will be invoked automatically
|
|
454
|
-
* each time the provided Observable stream emits a new data array. Otherwise if your data is
|
|
455
|
-
* an array, this function will need to be called to render any changes.
|
|
456
|
-
*/
|
|
457
|
-
renderRows() {
|
|
458
|
-
this._renderRows = this._getAllRenderRows();
|
|
459
|
-
const changes = this._dataDiffer.diff(this._renderRows);
|
|
460
|
-
if (!changes) {
|
|
461
|
-
this._updateNoDataRow();
|
|
462
|
-
this.contentChanged.next();
|
|
463
|
-
return;
|
|
464
|
-
}
|
|
465
|
-
const viewContainer = this._rowOutlet.viewContainer;
|
|
466
|
-
this._viewRepeater.applyChanges(changes, viewContainer, (record, _adjustedPreviousIndex, currentIndex) => this._getEmbeddedViewArgs(record.item, currentIndex), record => record.item.data, (change) => {
|
|
467
|
-
if (change.operation === _ViewRepeaterOperation.INSERTED && change.context) {
|
|
468
|
-
this._renderCellTemplateForItem(change.record.item.rowDef, change.context);
|
|
469
|
-
}
|
|
470
|
-
});
|
|
471
|
-
// Update the meta context of a row's context data (index, count, first, last, ...)
|
|
472
|
-
this._updateRowIndexContext();
|
|
473
|
-
// Update rows that did not get added/removed/moved but may have had their identity changed,
|
|
474
|
-
// e.g. if trackBy matched data on some property but the actual data reference changed.
|
|
475
|
-
changes.forEachIdentityChange((record) => {
|
|
476
|
-
const rowView = viewContainer.get(record.currentIndex);
|
|
477
|
-
rowView.context.$implicit = record.item.data;
|
|
478
|
-
});
|
|
479
|
-
this._updateNoDataRow();
|
|
480
|
-
afterNextRender(() => {
|
|
481
|
-
this.updateStickyColumnStyles();
|
|
482
|
-
}, { injector: this._injector });
|
|
483
|
-
this.contentChanged.next();
|
|
484
|
-
}
|
|
485
|
-
/** Adds a column definition that was not included as part of the content children. */
|
|
486
|
-
addColumnDef(columnDef) {
|
|
487
|
-
this._customColumnDefs.add(columnDef);
|
|
488
|
-
}
|
|
489
|
-
/** Removes a column definition that was not included as part of the content children. */
|
|
490
|
-
removeColumnDef(columnDef) {
|
|
491
|
-
this._customColumnDefs.delete(columnDef);
|
|
492
|
-
}
|
|
493
|
-
/** Adds a row definition that was not included as part of the content children. */
|
|
494
|
-
addRowDef(rowDef) {
|
|
495
|
-
this._customRowDefs.add(rowDef);
|
|
496
|
-
}
|
|
497
|
-
/** Removes a row definition that was not included as part of the content children. */
|
|
498
|
-
removeRowDef(rowDef) {
|
|
499
|
-
this._customRowDefs.delete(rowDef);
|
|
500
|
-
}
|
|
501
|
-
/** Adds a header row definition that was not included as part of the content children. */
|
|
502
|
-
addHeaderRowDef(headerRowDef) {
|
|
503
|
-
this._customHeaderRowDefs.add(headerRowDef);
|
|
504
|
-
this._headerRowDefChanged = true;
|
|
505
|
-
}
|
|
506
|
-
/** Removes a header row definition that was not included as part of the content children. */
|
|
507
|
-
removeHeaderRowDef(headerRowDef) {
|
|
508
|
-
this._customHeaderRowDefs.delete(headerRowDef);
|
|
509
|
-
this._headerRowDefChanged = true;
|
|
510
|
-
}
|
|
511
|
-
/** Adds a footer row definition that was not included as part of the content children. */
|
|
512
|
-
addFooterRowDef(footerRowDef) {
|
|
513
|
-
this._customFooterRowDefs.add(footerRowDef);
|
|
514
|
-
this._footerRowDefChanged = true;
|
|
515
|
-
}
|
|
516
|
-
/** Removes a footer row definition that was not included as part of the content children. */
|
|
517
|
-
removeFooterRowDef(footerRowDef) {
|
|
518
|
-
this._customFooterRowDefs.delete(footerRowDef);
|
|
519
|
-
this._footerRowDefChanged = true;
|
|
520
|
-
}
|
|
521
|
-
/** Sets a no data row definition that was not included as a part of the content children. */
|
|
522
|
-
setNoDataRow(noDataRow) {
|
|
523
|
-
this._customNoDataRow = noDataRow;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* Updates the header sticky styles. First resets all applied styles with respect to the cells
|
|
527
|
-
* sticking to the top. Then, evaluating which cells need to be stuck to the top. This is
|
|
528
|
-
* automatically called when the header row changes its displayed set of columns, or if its
|
|
529
|
-
* sticky input changes. May be called manually for cases where the cell content changes outside
|
|
530
|
-
* of these events.
|
|
531
|
-
*/
|
|
532
|
-
updateStickyHeaderRowStyles() {
|
|
533
|
-
const headerRows = this._getRenderedRows(this._headerRowOutlet);
|
|
534
|
-
// Hide the thead element if there are no header rows. This is necessary to satisfy
|
|
535
|
-
// overzealous a11y checkers that fail because the `rowgroup` element does not contain
|
|
536
|
-
// required child `row`.
|
|
537
|
-
if (this._isNativeHtmlTable) {
|
|
538
|
-
const thead = closestTableSection(this._headerRowOutlet, 'thead');
|
|
539
|
-
if (thead) {
|
|
540
|
-
thead.style.display = headerRows.length ? '' : 'none';
|
|
541
|
-
}
|
|
542
|
-
}
|
|
543
|
-
const stickyStates = this._headerRowDefs.map(def => def.sticky);
|
|
544
|
-
this._stickyStyler.clearStickyPositioning(headerRows, ['top']);
|
|
545
|
-
this._stickyStyler.stickRows(headerRows, stickyStates, 'top');
|
|
546
|
-
// Reset the dirty state of the sticky input change since it has been used.
|
|
547
|
-
this._headerRowDefs.forEach(def => def.resetStickyChanged());
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
* Updates the footer sticky styles. First resets all applied styles with respect to the cells
|
|
551
|
-
* sticking to the bottom. Then, evaluating which cells need to be stuck to the bottom. This is
|
|
552
|
-
* automatically called when the footer row changes its displayed set of columns, or if its
|
|
553
|
-
* sticky input changes. May be called manually for cases where the cell content changes outside
|
|
554
|
-
* of these events.
|
|
555
|
-
*/
|
|
556
|
-
updateStickyFooterRowStyles() {
|
|
557
|
-
const footerRows = this._getRenderedRows(this._footerRowOutlet);
|
|
558
|
-
// Hide the tfoot element if there are no footer rows. This is necessary to satisfy
|
|
559
|
-
// overzealous a11y checkers that fail because the `rowgroup` element does not contain
|
|
560
|
-
// required child `row`.
|
|
561
|
-
if (this._isNativeHtmlTable) {
|
|
562
|
-
const tfoot = closestTableSection(this._footerRowOutlet, 'tfoot');
|
|
563
|
-
if (tfoot) {
|
|
564
|
-
tfoot.style.display = footerRows.length ? '' : 'none';
|
|
565
|
-
}
|
|
566
|
-
}
|
|
567
|
-
const stickyStates = this._footerRowDefs.map(def => def.sticky);
|
|
568
|
-
this._stickyStyler.clearStickyPositioning(footerRows, ['bottom']);
|
|
569
|
-
this._stickyStyler.stickRows(footerRows, stickyStates, 'bottom');
|
|
570
|
-
this._stickyStyler.updateStickyFooterContainer(this._elementRef.nativeElement, stickyStates);
|
|
571
|
-
// Reset the dirty state of the sticky input change since it has been used.
|
|
572
|
-
this._footerRowDefs.forEach(def => def.resetStickyChanged());
|
|
573
|
-
}
|
|
574
|
-
/**
|
|
575
|
-
* Updates the column sticky styles. First resets all applied styles with respect to the cells
|
|
576
|
-
* sticking to the left and right. Then sticky styles are added for the left and right according
|
|
577
|
-
* to the column definitions for each cell in each row. This is automatically called when
|
|
578
|
-
* the data source provides a new set of data or when a column definition changes its sticky
|
|
579
|
-
* input. May be called manually for cases where the cell content changes outside of these events.
|
|
580
|
-
*/
|
|
581
|
-
updateStickyColumnStyles() {
|
|
582
|
-
const headerRows = this._getRenderedRows(this._headerRowOutlet);
|
|
583
|
-
const dataRows = this._getRenderedRows(this._rowOutlet);
|
|
584
|
-
const footerRows = this._getRenderedRows(this._footerRowOutlet);
|
|
585
|
-
// For tables not using a fixed layout, the column widths may change when new rows are rendered.
|
|
586
|
-
// In a table using a fixed layout, row content won't affect column width, so sticky styles
|
|
587
|
-
// don't need to be cleared unless either the sticky column config changes or one of the row
|
|
588
|
-
// defs change.
|
|
589
|
-
if ((this._isNativeHtmlTable && !this._fixedLayout) || this._stickyColumnStylesNeedReset) {
|
|
590
|
-
// Clear the left and right positioning from all columns in the table across all rows since
|
|
591
|
-
// sticky columns span across all table sections (header, data, footer)
|
|
592
|
-
this._stickyStyler.clearStickyPositioning([...headerRows, ...dataRows, ...footerRows], ['left', 'right']);
|
|
593
|
-
this._stickyColumnStylesNeedReset = false;
|
|
594
|
-
}
|
|
595
|
-
// Update the sticky styles for each header row depending on the def's sticky state
|
|
596
|
-
headerRows.forEach((headerRow, i) => {
|
|
597
|
-
this._addStickyColumnStyles([headerRow], this._headerRowDefs[i]);
|
|
598
|
-
});
|
|
599
|
-
// Update the sticky styles for each data row depending on its def's sticky state
|
|
600
|
-
this._rowDefs.forEach(rowDef => {
|
|
601
|
-
// Collect all the rows rendered with this row definition.
|
|
602
|
-
const rows = [];
|
|
603
|
-
for (let i = 0; i < dataRows.length; i++) {
|
|
604
|
-
if (this._renderRows[i].rowDef === rowDef) {
|
|
605
|
-
rows.push(dataRows[i]);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
this._addStickyColumnStyles(rows, rowDef);
|
|
609
|
-
});
|
|
610
|
-
// Update the sticky styles for each footer row depending on the def's sticky state
|
|
611
|
-
footerRows.forEach((footerRow, i) => {
|
|
612
|
-
this._addStickyColumnStyles([footerRow], this._footerRowDefs[i]);
|
|
613
|
-
});
|
|
614
|
-
// Reset the dirty state of the sticky input change since it has been used.
|
|
615
|
-
Array.from(this._columnDefsByName.values()).forEach(def => def.resetStickyChanged());
|
|
616
|
-
}
|
|
617
|
-
/** Invoked whenever an outlet is created and has been assigned to the table. */
|
|
618
|
-
_outletAssigned() {
|
|
619
|
-
// Trigger the first render once all outlets have been assigned. We do it this way, as
|
|
620
|
-
// opposed to waiting for the next `ngAfterContentChecked`, because we don't know when
|
|
621
|
-
// the next change detection will happen.
|
|
622
|
-
// Also we can't use queries to resolve the outlets, because they're wrapped in a
|
|
623
|
-
// conditional, so we have to rely on them being assigned via DI.
|
|
624
|
-
if (!this._hasAllOutlets &&
|
|
625
|
-
this._rowOutlet &&
|
|
626
|
-
this._headerRowOutlet &&
|
|
627
|
-
this._footerRowOutlet &&
|
|
628
|
-
this._noDataRowOutlet) {
|
|
629
|
-
this._hasAllOutlets = true;
|
|
630
|
-
// In some setups this may fire before `ngAfterContentInit`
|
|
631
|
-
// so we need a check here. See #28538.
|
|
632
|
-
if (this._canRender()) {
|
|
633
|
-
this._render();
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
/** Whether the table has all the information to start rendering. */
|
|
638
|
-
_canRender() {
|
|
639
|
-
return this._hasAllOutlets && this._hasInitialized;
|
|
640
|
-
}
|
|
641
|
-
/** Renders the table if its state has changed. */
|
|
642
|
-
_render() {
|
|
643
|
-
// Cache the row and column definitions gathered by ContentChildren and programmatic injection.
|
|
644
|
-
this._cacheRowDefs();
|
|
645
|
-
this._cacheColumnDefs();
|
|
646
|
-
// Make sure that the user has at least added header, footer, or data row def.
|
|
647
|
-
if (!this._headerRowDefs.length &&
|
|
648
|
-
!this._footerRowDefs.length &&
|
|
649
|
-
!this._rowDefs.length &&
|
|
650
|
-
(typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
651
|
-
throw getTableMissingRowDefsError();
|
|
652
|
-
}
|
|
653
|
-
// Render updates if the list of columns have been changed for the header, row, or footer defs.
|
|
654
|
-
const columnsChanged = this._renderUpdatedColumns();
|
|
655
|
-
const rowDefsChanged = columnsChanged || this._headerRowDefChanged || this._footerRowDefChanged;
|
|
656
|
-
// Ensure sticky column styles are reset if set to `true` elsewhere.
|
|
657
|
-
this._stickyColumnStylesNeedReset = this._stickyColumnStylesNeedReset || rowDefsChanged;
|
|
658
|
-
this._forceRecalculateCellWidths = rowDefsChanged;
|
|
659
|
-
// If the header row definition has been changed, trigger a render to the header row.
|
|
660
|
-
if (this._headerRowDefChanged) {
|
|
661
|
-
this._forceRenderHeaderRows();
|
|
662
|
-
this._headerRowDefChanged = false;
|
|
663
|
-
}
|
|
664
|
-
// If the footer row definition has been changed, trigger a render to the footer row.
|
|
665
|
-
if (this._footerRowDefChanged) {
|
|
666
|
-
this._forceRenderFooterRows();
|
|
667
|
-
this._footerRowDefChanged = false;
|
|
668
|
-
}
|
|
669
|
-
// If there is a data source and row definitions, connect to the data source unless a
|
|
670
|
-
// connection has already been made.
|
|
671
|
-
if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) {
|
|
672
|
-
this._observeRenderChanges();
|
|
673
|
-
}
|
|
674
|
-
else if (this._stickyColumnStylesNeedReset) {
|
|
675
|
-
// In the above case, _observeRenderChanges will result in updateStickyColumnStyles being
|
|
676
|
-
// called when it row data arrives. Otherwise, we need to call it proactively.
|
|
677
|
-
this.updateStickyColumnStyles();
|
|
678
|
-
}
|
|
679
|
-
this._checkStickyStates();
|
|
680
|
-
}
|
|
681
|
-
/**
|
|
682
|
-
* Get the list of RenderRow objects to render according to the current list of data and defined
|
|
683
|
-
* row definitions. If the previous list already contained a particular pair, it should be reused
|
|
684
|
-
* so that the differ equates their references.
|
|
685
|
-
*/
|
|
686
|
-
_getAllRenderRows() {
|
|
687
|
-
const renderRows = [];
|
|
688
|
-
// Store the cache and create a new one. Any re-used RenderRow objects will be moved into the
|
|
689
|
-
// new cache while unused ones can be picked up by garbage collection.
|
|
690
|
-
const prevCachedRenderRows = this._cachedRenderRowsMap;
|
|
691
|
-
this._cachedRenderRowsMap = new Map();
|
|
692
|
-
// For each data object, get the list of rows that should be rendered, represented by the
|
|
693
|
-
// respective `RenderRow` object which is the pair of `data` and `CdkRowDef`.
|
|
694
|
-
for (let i = 0; i < this._data.length; i++) {
|
|
695
|
-
let data = this._data[i];
|
|
696
|
-
const renderRowsForData = this._getRenderRowsForData(data, i, prevCachedRenderRows.get(data));
|
|
697
|
-
if (!this._cachedRenderRowsMap.has(data)) {
|
|
698
|
-
this._cachedRenderRowsMap.set(data, new WeakMap());
|
|
699
|
-
}
|
|
700
|
-
for (let j = 0; j < renderRowsForData.length; j++) {
|
|
701
|
-
let renderRow = renderRowsForData[j];
|
|
702
|
-
const cache = this._cachedRenderRowsMap.get(renderRow.data);
|
|
703
|
-
if (cache.has(renderRow.rowDef)) {
|
|
704
|
-
cache.get(renderRow.rowDef).push(renderRow);
|
|
705
|
-
}
|
|
706
|
-
else {
|
|
707
|
-
cache.set(renderRow.rowDef, [renderRow]);
|
|
708
|
-
}
|
|
709
|
-
renderRows.push(renderRow);
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
return renderRows;
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* Gets a list of `RenderRow<T>` for the provided data object and any `CdkRowDef` objects that
|
|
716
|
-
* should be rendered for this data. Reuses the cached RenderRow objects if they match the same
|
|
717
|
-
* `(T, CdkRowDef)` pair.
|
|
718
|
-
*/
|
|
719
|
-
_getRenderRowsForData(data, dataIndex, cache) {
|
|
720
|
-
const rowDefs = this._getRowDefs(data, dataIndex);
|
|
721
|
-
return rowDefs.map(rowDef => {
|
|
722
|
-
const cachedRenderRows = cache && cache.has(rowDef) ? cache.get(rowDef) : [];
|
|
723
|
-
if (cachedRenderRows.length) {
|
|
724
|
-
const dataRow = cachedRenderRows.shift();
|
|
725
|
-
dataRow.dataIndex = dataIndex;
|
|
726
|
-
return dataRow;
|
|
727
|
-
}
|
|
728
|
-
else {
|
|
729
|
-
return { data, rowDef, dataIndex };
|
|
730
|
-
}
|
|
731
|
-
});
|
|
732
|
-
}
|
|
733
|
-
/** Update the map containing the content's column definitions. */
|
|
734
|
-
_cacheColumnDefs() {
|
|
735
|
-
this._columnDefsByName.clear();
|
|
736
|
-
const columnDefs = mergeArrayAndSet(this._getOwnDefs(this._contentColumnDefs), this._customColumnDefs);
|
|
737
|
-
columnDefs.forEach(columnDef => {
|
|
738
|
-
if (this._columnDefsByName.has(columnDef.name) &&
|
|
739
|
-
(typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
740
|
-
throw getTableDuplicateColumnNameError(columnDef.name);
|
|
741
|
-
}
|
|
742
|
-
this._columnDefsByName.set(columnDef.name, columnDef);
|
|
743
|
-
});
|
|
744
|
-
}
|
|
745
|
-
/** Update the list of all available row definitions that can be used. */
|
|
746
|
-
_cacheRowDefs() {
|
|
747
|
-
this._headerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentHeaderRowDefs), this._customHeaderRowDefs);
|
|
748
|
-
this._footerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentFooterRowDefs), this._customFooterRowDefs);
|
|
749
|
-
this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs);
|
|
750
|
-
// After all row definitions are determined, find the row definition to be considered default.
|
|
751
|
-
const defaultRowDefs = this._rowDefs.filter(def => !def.when);
|
|
752
|
-
if (!this.multiTemplateDataRows &&
|
|
753
|
-
defaultRowDefs.length > 1 &&
|
|
754
|
-
(typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
755
|
-
throw getTableMultipleDefaultRowDefsError();
|
|
756
|
-
}
|
|
757
|
-
this._defaultRowDef = defaultRowDefs[0];
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Check if the header, data, or footer rows have changed what columns they want to display or
|
|
761
|
-
* whether the sticky states have changed for the header or footer. If there is a diff, then
|
|
762
|
-
* re-render that section.
|
|
763
|
-
*/
|
|
764
|
-
_renderUpdatedColumns() {
|
|
765
|
-
const columnsDiffReducer = (acc, def) => acc || !!def.getColumnsDiff();
|
|
766
|
-
// Force re-render data rows if the list of column definitions have changed.
|
|
767
|
-
const dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false);
|
|
768
|
-
if (dataColumnsChanged) {
|
|
769
|
-
this._forceRenderDataRows();
|
|
770
|
-
}
|
|
771
|
-
// Force re-render header/footer rows if the list of column definitions have changed.
|
|
772
|
-
const headerColumnsChanged = this._headerRowDefs.reduce(columnsDiffReducer, false);
|
|
773
|
-
if (headerColumnsChanged) {
|
|
774
|
-
this._forceRenderHeaderRows();
|
|
775
|
-
}
|
|
776
|
-
const footerColumnsChanged = this._footerRowDefs.reduce(columnsDiffReducer, false);
|
|
777
|
-
if (footerColumnsChanged) {
|
|
778
|
-
this._forceRenderFooterRows();
|
|
779
|
-
}
|
|
780
|
-
return dataColumnsChanged || headerColumnsChanged || footerColumnsChanged;
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Switch to the provided data source by resetting the data and unsubscribing from the current
|
|
784
|
-
* render change subscription if one exists. If the data source is null, interpret this by
|
|
785
|
-
* clearing the row outlet. Otherwise start listening for new data.
|
|
786
|
-
*/
|
|
787
|
-
_switchDataSource(dataSource) {
|
|
788
|
-
this._data = [];
|
|
789
|
-
if (isDataSource(this.dataSource)) {
|
|
790
|
-
this.dataSource.disconnect(this);
|
|
791
|
-
}
|
|
792
|
-
// Stop listening for data from the previous data source.
|
|
793
|
-
if (this._renderChangeSubscription) {
|
|
794
|
-
this._renderChangeSubscription.unsubscribe();
|
|
795
|
-
this._renderChangeSubscription = null;
|
|
796
|
-
}
|
|
797
|
-
if (!dataSource) {
|
|
798
|
-
if (this._dataDiffer) {
|
|
799
|
-
this._dataDiffer.diff([]);
|
|
800
|
-
}
|
|
801
|
-
if (this._rowOutlet) {
|
|
802
|
-
this._rowOutlet.viewContainer.clear();
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
this._dataSource = dataSource;
|
|
806
|
-
}
|
|
807
|
-
/** Set up a subscription for the data provided by the data source. */
|
|
808
|
-
_observeRenderChanges() {
|
|
809
|
-
// If no data source has been set, there is nothing to observe for changes.
|
|
810
|
-
if (!this.dataSource) {
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
let dataStream;
|
|
814
|
-
if (isDataSource(this.dataSource)) {
|
|
815
|
-
dataStream = this.dataSource.connect(this);
|
|
816
|
-
}
|
|
817
|
-
else if (isObservable(this.dataSource)) {
|
|
818
|
-
dataStream = this.dataSource;
|
|
819
|
-
}
|
|
820
|
-
else if (Array.isArray(this.dataSource)) {
|
|
821
|
-
dataStream = observableOf(this.dataSource);
|
|
822
|
-
}
|
|
823
|
-
if (dataStream === undefined && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
824
|
-
throw getTableUnknownDataSourceError();
|
|
825
|
-
}
|
|
826
|
-
this._renderChangeSubscription = dataStream
|
|
827
|
-
.pipe(takeUntil(this._onDestroy))
|
|
828
|
-
.subscribe(data => {
|
|
829
|
-
this._data = data || [];
|
|
830
|
-
this.renderRows();
|
|
831
|
-
});
|
|
832
|
-
}
|
|
833
|
-
/**
|
|
834
|
-
* Clears any existing content in the header row outlet and creates a new embedded view
|
|
835
|
-
* in the outlet using the header row definition.
|
|
836
|
-
*/
|
|
837
|
-
_forceRenderHeaderRows() {
|
|
838
|
-
// Clear the header row outlet if any content exists.
|
|
839
|
-
if (this._headerRowOutlet.viewContainer.length > 0) {
|
|
840
|
-
this._headerRowOutlet.viewContainer.clear();
|
|
841
|
-
}
|
|
842
|
-
this._headerRowDefs.forEach((def, i) => this._renderRow(this._headerRowOutlet, def, i));
|
|
843
|
-
this.updateStickyHeaderRowStyles();
|
|
844
|
-
}
|
|
845
|
-
/**
|
|
846
|
-
* Clears any existing content in the footer row outlet and creates a new embedded view
|
|
847
|
-
* in the outlet using the footer row definition.
|
|
848
|
-
*/
|
|
849
|
-
_forceRenderFooterRows() {
|
|
850
|
-
// Clear the footer row outlet if any content exists.
|
|
851
|
-
if (this._footerRowOutlet.viewContainer.length > 0) {
|
|
852
|
-
this._footerRowOutlet.viewContainer.clear();
|
|
853
|
-
}
|
|
854
|
-
this._footerRowDefs.forEach((def, i) => this._renderRow(this._footerRowOutlet, def, i));
|
|
855
|
-
this.updateStickyFooterRowStyles();
|
|
856
|
-
}
|
|
857
|
-
/** Adds the sticky column styles for the rows according to the columns' stick states. */
|
|
858
|
-
_addStickyColumnStyles(rows, rowDef) {
|
|
859
|
-
const columnDefs = Array.from(rowDef.columns || []).map(columnName => {
|
|
860
|
-
const columnDef = this._columnDefsByName.get(columnName);
|
|
861
|
-
if (!columnDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
862
|
-
throw getTableUnknownColumnError(columnName);
|
|
863
|
-
}
|
|
864
|
-
return columnDef;
|
|
865
|
-
});
|
|
866
|
-
const stickyStartStates = columnDefs.map(columnDef => columnDef.sticky);
|
|
867
|
-
const stickyEndStates = columnDefs.map(columnDef => columnDef.stickyEnd);
|
|
868
|
-
this._stickyStyler.updateStickyColumns(rows, stickyStartStates, stickyEndStates, !this._fixedLayout || this._forceRecalculateCellWidths);
|
|
869
|
-
}
|
|
870
|
-
/** Gets the list of rows that have been rendered in the row outlet. */
|
|
871
|
-
_getRenderedRows(rowOutlet) {
|
|
872
|
-
const renderedRows = [];
|
|
873
|
-
for (let i = 0; i < rowOutlet.viewContainer.length; i++) {
|
|
874
|
-
const viewRef = rowOutlet.viewContainer.get(i);
|
|
875
|
-
renderedRows.push(viewRef.rootNodes[0]);
|
|
876
|
-
}
|
|
877
|
-
return renderedRows;
|
|
878
|
-
}
|
|
879
|
-
/**
|
|
880
|
-
* Get the matching row definitions that should be used for this row data. If there is only
|
|
881
|
-
* one row definition, it is returned. Otherwise, find the row definitions that has a when
|
|
882
|
-
* predicate that returns true with the data. If none return true, return the default row
|
|
883
|
-
* definition.
|
|
884
|
-
*/
|
|
885
|
-
_getRowDefs(data, dataIndex) {
|
|
886
|
-
if (this._rowDefs.length == 1) {
|
|
887
|
-
return [this._rowDefs[0]];
|
|
888
|
-
}
|
|
889
|
-
let rowDefs = [];
|
|
890
|
-
if (this.multiTemplateDataRows) {
|
|
891
|
-
rowDefs = this._rowDefs.filter(def => !def.when || def.when(dataIndex, data));
|
|
892
|
-
}
|
|
893
|
-
else {
|
|
894
|
-
let rowDef = this._rowDefs.find(def => def.when && def.when(dataIndex, data)) || this._defaultRowDef;
|
|
895
|
-
if (rowDef) {
|
|
896
|
-
rowDefs.push(rowDef);
|
|
897
|
-
}
|
|
898
|
-
}
|
|
899
|
-
if (!rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
900
|
-
throw getTableMissingMatchingRowDefError(data);
|
|
901
|
-
}
|
|
902
|
-
return rowDefs;
|
|
903
|
-
}
|
|
904
|
-
_getEmbeddedViewArgs(renderRow, index) {
|
|
905
|
-
const rowDef = renderRow.rowDef;
|
|
906
|
-
const context = { $implicit: renderRow.data };
|
|
907
|
-
return {
|
|
908
|
-
templateRef: rowDef.template,
|
|
909
|
-
context,
|
|
910
|
-
index,
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
/**
|
|
914
|
-
* Creates a new row template in the outlet and fills it with the set of cell templates.
|
|
915
|
-
* Optionally takes a context to provide to the row and cells, as well as an optional index
|
|
916
|
-
* of where to place the new row template in the outlet.
|
|
917
|
-
*/
|
|
918
|
-
_renderRow(outlet, rowDef, index, context = {}) {
|
|
919
|
-
// TODO(andrewseguin): enforce that one outlet was instantiated from createEmbeddedView
|
|
920
|
-
const view = outlet.viewContainer.createEmbeddedView(rowDef.template, context, index);
|
|
921
|
-
this._renderCellTemplateForItem(rowDef, context);
|
|
922
|
-
return view;
|
|
923
|
-
}
|
|
924
|
-
_renderCellTemplateForItem(rowDef, context) {
|
|
925
|
-
for (let cellTemplate of this._getCellTemplates(rowDef)) {
|
|
926
|
-
if (CdkCellOutlet.mostRecentCellOutlet) {
|
|
927
|
-
CdkCellOutlet.mostRecentCellOutlet._viewContainer.createEmbeddedView(cellTemplate, context);
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
this._changeDetectorRef.markForCheck();
|
|
931
|
-
}
|
|
932
|
-
/**
|
|
933
|
-
* Updates the index-related context for each row to reflect any changes in the index of the rows,
|
|
934
|
-
* e.g. first/last/even/odd.
|
|
935
|
-
*/
|
|
936
|
-
_updateRowIndexContext() {
|
|
937
|
-
const viewContainer = this._rowOutlet.viewContainer;
|
|
938
|
-
for (let renderIndex = 0, count = viewContainer.length; renderIndex < count; renderIndex++) {
|
|
939
|
-
const viewRef = viewContainer.get(renderIndex);
|
|
940
|
-
const context = viewRef.context;
|
|
941
|
-
context.count = count;
|
|
942
|
-
context.first = renderIndex === 0;
|
|
943
|
-
context.last = renderIndex === count - 1;
|
|
944
|
-
context.even = renderIndex % 2 === 0;
|
|
945
|
-
context.odd = !context.even;
|
|
946
|
-
if (this.multiTemplateDataRows) {
|
|
947
|
-
context.dataIndex = this._renderRows[renderIndex].dataIndex;
|
|
948
|
-
context.renderIndex = renderIndex;
|
|
949
|
-
}
|
|
950
|
-
else {
|
|
951
|
-
context.index = this._renderRows[renderIndex].dataIndex;
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
/** Gets the column definitions for the provided row def. */
|
|
956
|
-
_getCellTemplates(rowDef) {
|
|
957
|
-
if (!rowDef || !rowDef.columns) {
|
|
958
|
-
return [];
|
|
959
|
-
}
|
|
960
|
-
return Array.from(rowDef.columns, columnId => {
|
|
961
|
-
const column = this._columnDefsByName.get(columnId);
|
|
962
|
-
if (!column && (typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
963
|
-
throw getTableUnknownColumnError(columnId);
|
|
964
|
-
}
|
|
965
|
-
return rowDef.extractCellTemplate(column);
|
|
966
|
-
});
|
|
967
|
-
}
|
|
968
|
-
/**
|
|
969
|
-
* Forces a re-render of the data rows. Should be called in cases where there has been an input
|
|
970
|
-
* change that affects the evaluation of which rows should be rendered, e.g. toggling
|
|
971
|
-
* `multiTemplateDataRows` or adding/removing row definitions.
|
|
972
|
-
*/
|
|
973
|
-
_forceRenderDataRows() {
|
|
974
|
-
this._dataDiffer.diff([]);
|
|
975
|
-
this._rowOutlet.viewContainer.clear();
|
|
976
|
-
this.renderRows();
|
|
977
|
-
}
|
|
978
|
-
/**
|
|
979
|
-
* Checks if there has been a change in sticky states since last check and applies the correct
|
|
980
|
-
* sticky styles. Since checking resets the "dirty" state, this should only be performed once
|
|
981
|
-
* during a change detection and after the inputs are settled (after content check).
|
|
982
|
-
*/
|
|
983
|
-
_checkStickyStates() {
|
|
984
|
-
const stickyCheckReducer = (acc, d) => {
|
|
985
|
-
return acc || d.hasStickyChanged();
|
|
986
|
-
};
|
|
987
|
-
// Note that the check needs to occur for every definition since it notifies the definition
|
|
988
|
-
// that it can reset its dirty state. Using another operator like `some` may short-circuit
|
|
989
|
-
// remaining definitions and leave them in an unchecked state.
|
|
990
|
-
if (this._headerRowDefs.reduce(stickyCheckReducer, false)) {
|
|
991
|
-
this.updateStickyHeaderRowStyles();
|
|
992
|
-
}
|
|
993
|
-
if (this._footerRowDefs.reduce(stickyCheckReducer, false)) {
|
|
994
|
-
this.updateStickyFooterRowStyles();
|
|
995
|
-
}
|
|
996
|
-
if (Array.from(this._columnDefsByName.values()).reduce(stickyCheckReducer, false)) {
|
|
997
|
-
this._stickyColumnStylesNeedReset = true;
|
|
998
|
-
this.updateStickyColumnStyles();
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
/**
|
|
1002
|
-
* Creates the sticky styler that will be used for sticky rows and columns. Listens
|
|
1003
|
-
* for directionality changes and provides the latest direction to the styler. Re-applies column
|
|
1004
|
-
* stickiness when directionality changes.
|
|
1005
|
-
*/
|
|
1006
|
-
_setupStickyStyler() {
|
|
1007
|
-
const direction = this._dir ? this._dir.value : 'ltr';
|
|
1008
|
-
this._stickyStyler = new StickyStyler(this._isNativeHtmlTable, this.stickyCssClass, direction, this._coalescedStyleScheduler, this._platform.isBrowser, this.needsPositionStickyOnElement, this._stickyPositioningListener);
|
|
1009
|
-
(this._dir ? this._dir.change : observableOf())
|
|
1010
|
-
.pipe(takeUntil(this._onDestroy))
|
|
1011
|
-
.subscribe(value => {
|
|
1012
|
-
this._stickyStyler.direction = value;
|
|
1013
|
-
this.updateStickyColumnStyles();
|
|
1014
|
-
});
|
|
1015
|
-
}
|
|
1016
|
-
/** Filters definitions that belong to this table from a QueryList. */
|
|
1017
|
-
_getOwnDefs(items) {
|
|
1018
|
-
return items.filter(item => !item._table || item._table === this);
|
|
1019
|
-
}
|
|
1020
|
-
/** Creates or removes the no data row, depending on whether any data is being shown. */
|
|
1021
|
-
_updateNoDataRow() {
|
|
1022
|
-
const noDataRow = this._customNoDataRow || this._noDataRow;
|
|
1023
|
-
if (!noDataRow) {
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
const shouldShow = this._rowOutlet.viewContainer.length === 0;
|
|
1027
|
-
if (shouldShow === this._isShowingNoDataRow) {
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
const container = this._noDataRowOutlet.viewContainer;
|
|
1031
|
-
if (shouldShow) {
|
|
1032
|
-
const view = container.createEmbeddedView(noDataRow.templateRef);
|
|
1033
|
-
const rootNode = view.rootNodes[0];
|
|
1034
|
-
// Only add the attributes if we have a single root node since it's hard
|
|
1035
|
-
// to figure out which one to add it to when there are multiple.
|
|
1036
|
-
if (view.rootNodes.length === 1 && rootNode?.nodeType === this._document.ELEMENT_NODE) {
|
|
1037
|
-
rootNode.setAttribute('role', 'row');
|
|
1038
|
-
rootNode.classList.add(noDataRow._contentClassName);
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
else {
|
|
1042
|
-
container.clear();
|
|
1043
|
-
}
|
|
1044
|
-
this._isShowingNoDataRow = shouldShow;
|
|
1045
|
-
this._changeDetectorRef.markForCheck();
|
|
1046
|
-
}
|
|
1047
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkTable, deps: [{ token: i0.IterableDiffers }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: 'role', attribute: true }, { token: i1.Directionality, optional: true }, { token: DOCUMENT }, { token: i2.Platform }, { token: _VIEW_REPEATER_STRATEGY }, { token: _COALESCED_STYLE_SCHEDULER }, { token: i3.ViewportRuler }, { token: STICKY_POSITIONING_LISTENER, optional: true, skipSelf: true }, { token: i0.NgZone, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1048
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0-next.2", type: CdkTable, isStandalone: true, selector: "cdk-table, table[cdk-table]", inputs: { trackBy: "trackBy", dataSource: "dataSource", multiTemplateDataRows: ["multiTemplateDataRows", "multiTemplateDataRows", booleanAttribute], fixedLayout: ["fixedLayout", "fixedLayout", booleanAttribute] }, outputs: { contentChanged: "contentChanged" }, host: { properties: { "class.cdk-table-fixed-layout": "fixedLayout" }, classAttribute: "cdk-table" }, providers: [
|
|
1049
|
-
{ provide: CDK_TABLE, useExisting: CdkTable },
|
|
1050
|
-
{ provide: _VIEW_REPEATER_STRATEGY, useClass: _DisposeViewRepeaterStrategy },
|
|
1051
|
-
{ provide: _COALESCED_STYLE_SCHEDULER, useClass: _CoalescedStyleScheduler },
|
|
1052
|
-
// Prevent nested tables from seeing this table's StickyPositioningListener.
|
|
1053
|
-
{ provide: STICKY_POSITIONING_LISTENER, useValue: null },
|
|
1054
|
-
], queries: [{ propertyName: "_noDataRow", first: true, predicate: CdkNoDataRow, descendants: true }, { propertyName: "_contentColumnDefs", predicate: CdkColumnDef, descendants: true }, { propertyName: "_contentRowDefs", predicate: CdkRowDef, descendants: true }, { propertyName: "_contentHeaderRowDefs", predicate: CdkHeaderRowDef, descendants: true }, { propertyName: "_contentFooterRowDefs", predicate: CdkFooterRowDef, descendants: true }], exportAs: ["cdkTable"], ngImport: i0, template: "\n <ng-content select=\"caption\"/>\n <ng-content select=\"colgroup, col\"/>\n\n <!--\n Unprojected content throws a hydration error so we need this to capture it.\n It gets removed on the client so it doesn't affect the layout.\n -->\n @if (_isServer) {\n <ng-content/>\n }\n\n @if (_isNativeHtmlTable) {\n <thead role=\"rowgroup\">\n <ng-container headerRowOutlet/>\n </thead>\n <tbody role=\"rowgroup\">\n <ng-container rowOutlet/>\n <ng-container noDataRowOutlet/>\n </tbody>\n <tfoot role=\"rowgroup\">\n <ng-container footerRowOutlet/>\n </tfoot>\n } @else {\n <ng-container headerRowOutlet/>\n <ng-container rowOutlet/>\n <ng-container noDataRowOutlet/>\n <ng-container footerRowOutlet/>\n }\n", isInline: true, styles: [".cdk-table-fixed-layout{table-layout:fixed}"], dependencies: [{ kind: "directive", type: HeaderRowOutlet, selector: "[headerRowOutlet]" }, { kind: "directive", type: DataRowOutlet, selector: "[rowOutlet]" }, { kind: "directive", type: NoDataRowOutlet, selector: "[noDataRowOutlet]" }, { kind: "directive", type: FooterRowOutlet, selector: "[footerRowOutlet]" }], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None }); }
|
|
1055
|
-
}
|
|
1056
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0-next.2", ngImport: i0, type: CdkTable, decorators: [{
|
|
1057
|
-
type: Component,
|
|
1058
|
-
args: [{ selector: 'cdk-table, table[cdk-table]', exportAs: 'cdkTable', template: CDK_TABLE_TEMPLATE, host: {
|
|
1059
|
-
'class': 'cdk-table',
|
|
1060
|
-
'[class.cdk-table-fixed-layout]': 'fixedLayout',
|
|
1061
|
-
}, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, providers: [
|
|
1062
|
-
{ provide: CDK_TABLE, useExisting: CdkTable },
|
|
1063
|
-
{ provide: _VIEW_REPEATER_STRATEGY, useClass: _DisposeViewRepeaterStrategy },
|
|
1064
|
-
{ provide: _COALESCED_STYLE_SCHEDULER, useClass: _CoalescedStyleScheduler },
|
|
1065
|
-
// Prevent nested tables from seeing this table's StickyPositioningListener.
|
|
1066
|
-
{ provide: STICKY_POSITIONING_LISTENER, useValue: null },
|
|
1067
|
-
], standalone: true, imports: [HeaderRowOutlet, DataRowOutlet, NoDataRowOutlet, FooterRowOutlet], styles: [".cdk-table-fixed-layout{table-layout:fixed}"] }]
|
|
1068
|
-
}], ctorParameters: () => [{ type: i0.IterableDiffers }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: undefined, decorators: [{
|
|
1069
|
-
type: Attribute,
|
|
1070
|
-
args: ['role']
|
|
1071
|
-
}] }, { type: i1.Directionality, decorators: [{
|
|
1072
|
-
type: Optional
|
|
1073
|
-
}] }, { type: undefined, decorators: [{
|
|
1074
|
-
type: Inject,
|
|
1075
|
-
args: [DOCUMENT]
|
|
1076
|
-
}] }, { type: i2.Platform }, { type: undefined, decorators: [{
|
|
1077
|
-
type: Inject,
|
|
1078
|
-
args: [_VIEW_REPEATER_STRATEGY]
|
|
1079
|
-
}] }, { type: i4._CoalescedStyleScheduler, decorators: [{
|
|
1080
|
-
type: Inject,
|
|
1081
|
-
args: [_COALESCED_STYLE_SCHEDULER]
|
|
1082
|
-
}] }, { type: i3.ViewportRuler }, { type: undefined, decorators: [{
|
|
1083
|
-
type: Optional
|
|
1084
|
-
}, {
|
|
1085
|
-
type: SkipSelf
|
|
1086
|
-
}, {
|
|
1087
|
-
type: Inject,
|
|
1088
|
-
args: [STICKY_POSITIONING_LISTENER]
|
|
1089
|
-
}] }, { type: i0.NgZone, decorators: [{
|
|
1090
|
-
type: Optional
|
|
1091
|
-
}] }], propDecorators: { trackBy: [{
|
|
1092
|
-
type: Input
|
|
1093
|
-
}], dataSource: [{
|
|
1094
|
-
type: Input
|
|
1095
|
-
}], multiTemplateDataRows: [{
|
|
1096
|
-
type: Input,
|
|
1097
|
-
args: [{ transform: booleanAttribute }]
|
|
1098
|
-
}], fixedLayout: [{
|
|
1099
|
-
type: Input,
|
|
1100
|
-
args: [{ transform: booleanAttribute }]
|
|
1101
|
-
}], contentChanged: [{
|
|
1102
|
-
type: Output
|
|
1103
|
-
}], _contentColumnDefs: [{
|
|
1104
|
-
type: ContentChildren,
|
|
1105
|
-
args: [CdkColumnDef, { descendants: true }]
|
|
1106
|
-
}], _contentRowDefs: [{
|
|
1107
|
-
type: ContentChildren,
|
|
1108
|
-
args: [CdkRowDef, { descendants: true }]
|
|
1109
|
-
}], _contentHeaderRowDefs: [{
|
|
1110
|
-
type: ContentChildren,
|
|
1111
|
-
args: [CdkHeaderRowDef, {
|
|
1112
|
-
descendants: true,
|
|
1113
|
-
}]
|
|
1114
|
-
}], _contentFooterRowDefs: [{
|
|
1115
|
-
type: ContentChildren,
|
|
1116
|
-
args: [CdkFooterRowDef, {
|
|
1117
|
-
descendants: true,
|
|
1118
|
-
}]
|
|
1119
|
-
}], _noDataRow: [{
|
|
1120
|
-
type: ContentChild,
|
|
1121
|
-
args: [CdkNoDataRow]
|
|
1122
|
-
}] } });
|
|
1123
|
-
/** Utility function that gets a merged list of the entries in an array and values of a Set. */
|
|
1124
|
-
function mergeArrayAndSet(array, set) {
|
|
1125
|
-
return array.concat(Array.from(set));
|
|
1126
|
-
}
|
|
1127
|
-
/**
|
|
1128
|
-
* Finds the closest table section to an outlet. We can't use `HTMLElement.closest` for this,
|
|
1129
|
-
* because the node representing the outlet is a comment.
|
|
1130
|
-
*/
|
|
1131
|
-
function closestTableSection(outlet, section) {
|
|
1132
|
-
const uppercaseSection = section.toUpperCase();
|
|
1133
|
-
let current = outlet.viewContainer.element.nativeElement;
|
|
1134
|
-
while (current) {
|
|
1135
|
-
// 1 is an element node.
|
|
1136
|
-
const nodeName = current.nodeType === 1 ? current.nodeName : null;
|
|
1137
|
-
if (nodeName === uppercaseSection) {
|
|
1138
|
-
return current;
|
|
1139
|
-
}
|
|
1140
|
-
else if (nodeName === 'TABLE') {
|
|
1141
|
-
// Stop traversing past the `table` node.
|
|
1142
|
-
break;
|
|
1143
|
-
}
|
|
1144
|
-
current = current.parentNode;
|
|
1145
|
-
}
|
|
1146
|
-
return null;
|
|
1147
|
-
}
|
|
1148
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL3RhYmxlL3RhYmxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBWSxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RCxPQUFPLEVBR0wsNEJBQTRCLEVBQzVCLDRCQUE0QixFQUM1QixZQUFZLEVBQ1osdUJBQXVCLEVBSXZCLHNCQUFzQixHQUN2QixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDckQsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFHTCxTQUFTLEVBQ1QsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLGVBQWUsRUFDZixTQUFTLEVBQ1QsVUFBVSxFQUNWLGVBQWUsRUFDZixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxlQUFlLEVBQ2YsTUFBTSxFQUdOLFFBQVEsRUFDUixNQUFNLEVBQ04sU0FBUyxFQUNULFFBQVEsRUFHUixnQkFBZ0IsRUFDaEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixNQUFNLEVBQ04sZUFBZSxFQUNmLFFBQVEsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsZUFBZSxFQUNmLFlBQVksRUFFWixFQUFFLElBQUksWUFBWSxFQUNsQixPQUFPLEdBRVIsTUFBTSxNQUFNLENBQUM7QUFDZCxPQUFPLEVBQUMsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDekMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUNwQyxPQUFPLEVBQUMsd0JBQXdCLEVBQUUsMEJBQTBCLEVBQUMsTUFB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QUFFLENBQUM7WUFDbEMsT0FBTyxPQUFzQixDQUFDO1FBQ2hDLENBQUM7YUFBTSxJQUFJLFFBQVEsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUNoQyx5Q0FBeUM7WUFDekMsTUFBTTtRQUNSLENBQUM7UUFDRCxPQUFPLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQztJQUMvQixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7RGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHtcbiAgQ29sbGVjdGlvblZpZXdlcixcbiAgRGF0YVNvdXJjZSxcbiAgX0Rpc3Bvc2VWaWV3UmVwZWF0ZXJTdHJhdGVneSxcbiAgX1JlY3ljbGVWaWV3UmVwZWF0ZXJTdHJhdGVneSxcbiAgaXNEYXRhU291cmNlLFxuICBfVklFV19SRVBFQVRFUl9TVFJBVEVHWSxcbiAgX1ZpZXdSZXBlYXRlcixcbiAgX1ZpZXdSZXBlYXRlckl0ZW1DaGFuZ2UsXG4gIF9WaWV3UmVwZWF0ZXJJdGVtSW5zZXJ0QXJncyxcbiAgX1ZpZXdSZXBlYXRlck9wZXJhdGlvbixcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2NvbGxlY3Rpb25zJztcbmltcG9ydCB7UGxhdGZvcm19IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5pbXBvcnQge1ZpZXdwb3J0UnVsZXJ9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudENoZWNrZWQsXG4gIEFmdGVyQ29udGVudEluaXQsXG4gIEF0dHJpYnV0ZSxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIENvbnRlbnRDaGlsZCxcbiAgQ29udGVudENoaWxkcmVuLFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEVtYmVkZGVkVmlld1JlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIElucHV0LFxuICBJdGVyYWJsZUNoYW5nZVJlY29yZCxcbiAgSXRlcmFibGVEaWZmZXIsXG4gIEl0ZXJhYmxlRGlmZmVycyxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBTa2lwU2VsZixcbiAgVGVtcGxhdGVSZWYsXG4gIFRyYWNrQnlGdW5jdGlvbixcbiAgVmlld0NvbnRhaW5lclJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIGJvb2xlYW5BdHRyaWJ1dGUsXG4gIGluamVjdCxcbiAgYWZ0ZXJOZXh0UmVuZGVyLFxuICBJbmplY3Rvcixcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGlzT2JzZXJ2YWJsZSxcbiAgT2JzZXJ2YWJsZSxcbiAgb2YgYXMgb2JzZXJ2YWJsZU9mLFxuICBTdWJqZWN0LFxuICBTdWJzY3JpcHRpb24sXG59IGZyb20gJ3J4anMnO1xuaW1wb3J0IHt0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7Q2RrQ29sdW1uRGVmfSBmcm9tICcuL2NlbGwnO1xuaW1wb3J0IHtfQ29hbGVzY2VkU3R5bGVTY2hlZHVsZXIsIF9DT0FMRVNDRURfU1RZTEVfU0NIRURVTEVSfSBmcm9tICcuL2NvYWxlc2NlZC1zdHlsZS1zY2hlZHVsZXInO1xuaW1wb3J0IHtcbiAgQmFzZVJvd0RlZixcbiAgQ2RrQ2VsbE91dGxldCxcbiAgQ2RrQ2VsbE91dGxldE11bHRpUm93Q29udGV4dCxcbiAgQ2RrQ2VsbE91dGxldFJvd0NvbnRleHQsXG4gIENka0Zvb3RlclJvd0RlZixcbiAgQ2RrSGVhZGVyUm93RGVmLFxuICBDZGtOb0RhdGFSb3csXG4gIENka1Jvd0RlZixcbn0gZnJvbSAnLi9yb3cnO1xuaW1wb3J0IHtTdGlja3lTdHlsZXJ9IGZyb20gJy4vc3RpY2t5LXN0eWxlcic7XG5pbXBvcnQge1xuICBnZXRUYWJsZUR1cGxpY2F0ZUNvbHVtbk5hbWVFcnJvcixcbiAgZ2V0VGFibGVNaXNzaW5nTWF0Y2hpbmdSb3dEZWZFcnJvcixcbiAgZ2V0VGFibGVNaXNzaW5nUm93RGVmc0Vycm9yLFxuICBnZXRUYWJsZU11bHRpcGxlRGVmYXVsdFJvd0RlZnNFcnJvcixcbiAgZ2V0VGFibGVVbmtub3duQ29sdW1uRXJyb3IsXG4gIGdldFRhYmxlVW5rbm93bkRhdGFTb3VyY2VFcnJvcixcbn0gZnJvbSAnLi90YWJsZS1lcnJvcnMnO1xuaW1wb3J0IHtTVElDS1lfUE9TSVRJT05JTkdfTElTVEVORVIsIFN0aWNreVBvc2l0aW9uaW5nTGlzdGVuZXJ9IGZyb20gJy4vc3RpY2t5LXBvc2l0aW9uLWxpc3RlbmVyJztcbmltcG9ydCB7Q0RLX1RBQkxFfSBmcm9tICcuL3Rva2Vucyc7XG5cbi8qKlxuICogRW5hYmxlcyB0aGUgcmVjeWNsZSB2aWV3IHJlcGVhdGVyIHN0cmF0ZWd5LCB3aGljaCByZWR1Y2VzIHJlbmRlcmluZyBsYXRlbmN5LiBOb3QgY29tcGF0aWJsZSB3aXRoXG4gKiB0YWJsZXMgdGhhdCBhbmltYXRlIHJvd3MuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ2Nkay10YWJsZVtyZWN5Y2xlUm93c10sIHRhYmxlW2Nkay10YWJsZV1bcmVjeWNsZVJvd3NdJyxcbiAgcHJvdmlkZXJzOiBbe3Byb3ZpZGU6IF9WSUVXX1JFUEVBVEVSX1NUUkFURUdZLCB1c2VDbGFzczogX1JlY3ljbGVWaWV3UmVwZWF0ZXJTdHJhdGVneX1dLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBDZGtSZWN5Y2xlUm93cyB7fVxuXG4vKiogSW50ZXJmYWNlIHVzZWQgdG8gcHJvdmlkZSBhbiBvdXRsZXQgZm9yIHJvd3MgdG8gYmUgaW5zZXJ0ZWQgaW50by4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm93T3V0bGV0IHtcbiAgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZjtcbn1cblxuLyoqIFBvc3NpYmxlIHR5cGVzIHRoYXQgY2FuIGJlIHNldCBhcyB0aGUgZGF0YSBzb3VyY2UgZm9yIGEgYENka1RhYmxlYC4gKi9cbmV4cG9ydCB0eXBlIENka1RhYmxlRGF0YVNvdXJjZUlucHV0PFQ+ID0gcmVhZG9ubHkgVFtdIHwgRGF0YVNvdXJjZTxUPiB8IE9ic2VydmFibGU8cmVhZG9ubHkgVFtdPjtcblxuLyoqXG4gKiBQcm92aWRlcyBhIGhhbmRsZSBmb3IgdGhlIHRhYmxlIHRvIGdyYWIgdGhlIHZpZXcgY29udGFpbmVyJ3MgbmctY29udGFpbmVyIHRvIGluc2VydCBkYXRhIHJvd3MuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tyb3dPdXRsZXRdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgRGF0YVJvd091dGxldCBpbXBsZW1lbnRzIFJvd091dGxldCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICApIHtcbiAgICBjb25zdCB0YWJsZSA9IGluamVjdDxDZGtUYWJsZTx1bmtub3duPj4oQ0RLX1RBQkxFKTtcbiAgICB0YWJsZS5fcm93T3V0bGV0ID0gdGhpcztcbiAgICB0YWJsZS5fb3V0bGV0QXNzaWduZWQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3ZpZGVzIGEgaGFuZGxlIGZvciB0aGUgdGFibGUgdG8gZ3JhYiB0aGUgdmlldyBjb250YWluZXIncyBuZy1jb250YWluZXIgdG8gaW5zZXJ0IHRoZSBoZWFkZXIuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1toZWFkZXJSb3dPdXRsZXRdJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbn0pXG5leHBvcnQgY2xhc3MgSGVhZGVyUm93T3V0bGV0IGltcGxlbWVudHMgUm93T3V0bGV0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWYsXG4gICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICkge1xuICAgIGNvbnN0IHRhYmxlID0gaW5qZWN0PENka1RhYmxlPHVua25vd24+PihDREtfVEFCTEUpO1xuICAgIHRhYmxlLl9oZWFkZXJSb3dPdXRsZXQgPSB0aGlzO1xuICAgIHRhYmxlLl9vdXRsZXRBc3NpZ25lZCgpO1xuICB9XG59XG5cbi8qKlxuICogUHJvdmlkZXMgYSBoYW5kbGUgZm9yIHRoZSB0YWJsZSB0byBncmFiIHRoZSB2aWV3IGNvbnRhaW5lcidzIG5nLWNvbnRhaW5lciB0byBpbnNlcnQgdGhlIGZvb3Rlci5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnW2Zvb3RlclJvd091dGxldF0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBGb290ZXJSb3dPdXRsZXQgaW1wbGVtZW50cyBSb3dPdXRsZXQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgdmlld0NvbnRhaW5lcjogVmlld0NvbnRhaW5lclJlZixcbiAgICBwdWJsaWMgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgKSB7XG4gICAgY29uc3QgdGFibGUgPSBpbmplY3Q8Q2RrVGFibGU8dW5rbm93bj4+KENES19UQUJMRSk7XG4gICAgdGFibGUuX2Zvb3RlclJvd091dGxldCA9IHRoaXM7XG4gICAgdGFibGUuX291dGxldEFzc2lnbmVkKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBQcm92aWRlcyBhIGhhbmRsZSBmb3IgdGhlIHRhYmxlIHRvIGdyYWIgdGhlIHZpZXdcbiAqIGNvbnRhaW5lcidzIG5nLWNvbnRhaW5lciB0byBpbnNlcnQgdGhlIG5vIGRhdGEgcm93LlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbm9EYXRhUm93T3V0bGV0XScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIE5vRGF0YVJvd091dGxldCBpbXBsZW1lbnRzIFJvd091dGxldCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyB2aWV3Q29udGFpbmVyOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICApIHtcbiAgICBjb25zdCB0YWJsZSA9IGluamVjdDxDZGtUYWJsZTx1bmtub3duPj4oQ0RLX1RBQkxFKTtcbiAgICB0YWJsZS5fbm9EYXRhUm93T3V0bGV0ID0gdGhpcztcbiAgICB0YWJsZS5fb3V0bGV0QXNzaWduZWQoKTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSB0YWJsZSB0ZW1wbGF0ZSB0aGF0IGNhbiBiZSB1c2VkIGJ5IHRoZSBtYXQtdGFibGUuIFNob3VsZCBub3QgYmUgdXNlZCBvdXRzaWRlIG9mIHRoZVxuICogbWF0ZXJpYWwgbGlicmFyeS5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZXhwb3J0IGNvbnN0IENES19UQUJMRV9URU1QTEFURSA9XG4gIC8vIE5vdGUgdGhhdCBhY2NvcmRpbmcgdG8gTUROLCB0aGUgYGNhcHRpb25gIGVsZW1lbnQgaGFzIHRvIGJlIHByb2plY3RlZCBhcyB0aGUgKipmaXJzdCoqXG4gIC8vIGVsZW1lbnQgaW4gdGhlIHRhYmxlLiBTZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRNTC9FbGVtZW50L2NhcHRpb25cbiAgYFxuICA8bmctY29udGVudCBzZWxlY3Q9XCJjYXB0aW9uXCIvPlxuICA8bmctY29udGVudCBzZWxlY3Q9XCJjb2xncm91cCwgY29sXCIvPlxuXG4gIDwhLS1cbiAgICBVbnByb2plY3RlZCBjb250ZW50IHRocm93cyBhIGh5ZHJhdGlvbiBlcnJvciBzbyB3ZSBuZWVkIHRoaXMgdG8gY2FwdHVyZSBpdC5cbiAgICBJdCBnZXRzIHJlbW92ZWQgb24gdGhlIGNsaWVudCBzbyBpdCBkb2Vzbid0IGFmZmVjdCB0aGUgbGF5b3V0LlxuICAtLT5cbiAgQGlmIChfaXNTZXJ2ZXIpIHtcbiAgICA8bmctY29udGVudC8+XG4gIH1cblxuICBAaWYgKF9pc05hdGl2ZUh0bWxUYWJsZSkge1xuICAgIDx0aGVhZCByb2xlPVwicm93Z3JvdXBcIj5cbiAgICAgIDxuZy1jb250YWluZXIgaGVhZGVyUm93T3V0bGV0Lz5cbiAgICA8L3RoZWFkPlxuICAgIDx0Ym9keSByb2xlPVwicm93Z3JvdXBcIj5cbiAgICAgIDxuZy1jb250YWluZXIgcm93T3V0bGV0Lz5cbiAgICAgIDxuZy1jb250YWluZXIgbm9EYXRhUm93T3V0bGV0Lz5cbiAgICA8L3Rib2R5PlxuICAgIDx0Zm9vdCByb2xlPVwicm93Z3JvdXBcIj5cbiAgICAgIDxuZy1jb250YWluZXIgZm9vdGVyUm93T3V0bGV0Lz5cbiAgICA8L3Rmb290PlxuICB9IEBlbHNlIHtcbiAgICA8bmctY29udGFpbmVyIGhlYWRlclJvd091dGxldC8+XG4gICAgPG5nLWNvbnRhaW5lciByb3dPdXRsZXQvPlxuICAgIDxuZy1jb250YWluZXIgbm9EYXRhUm93T3V0bGV0Lz5cbiAgICA8bmctY29udGFpbmVyIGZvb3RlclJvd091dGxldC8+XG4gIH1cbmA7XG5cbi8qKlxuICogSW50ZXJmYWNlIHVzZWQgdG8gY29udmVuaWVudGx5IHR5cGUgdGhlIHBvc3NpYmxlIGNvbnRleHQgaW50ZXJmYWNlcyBmb3IgdGhlIHJlbmRlciByb3cuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUm93Q29udGV4dDxUPlxuICBleHRlbmRzIENka0NlbGxPdXRsZXRNdWx0aVJvd0NvbnRleHQ8VD4sXG4gICAgQ2RrQ2VsbE91dGxldFJvd0NvbnRleHQ8VD4ge31cblxuLyoqXG4gKiBDbGFzcyB1c2VkIHRvIGNvbnZlbmllbnRseSB0eXBlIHRoZSBlbWJlZGRlZCB2aWV3IHJlZiBmb3Igcm93cyB3aXRoIGEgY29udGV4dC5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuYWJzdHJhY3QgY2xhc3MgUm93Vmlld1JlZjxUPiBleHRlbmRzIEVtYmVkZGVkVmlld1JlZjxSb3dDb250ZXh0PFQ+PiB7fVxuXG4vKipcbiAqIFNldCBvZiBwcm9wZXJ0aWVzIHRoYXQgcmVwcmVzZW50cyB0aGUgaWRlbnRpdHkgb2YgYSBzaW5nbGUgcmVuZGVyZWQgcm93LlxuICpcbiAqIFdoZW4gdGhlIHRhYmxlIG5lZWRzIHRvIGRldGVybWluZSB0aGUgbGlzdCBvZiByb3dzIHRvIHJlbmRlciwgaXQgd2lsbCBkbyBzbyBieSBpdGVyYXRpbmcgdGhyb3VnaFxuICogZWFjaCBkYXRhIG9iamVjdCBhbmQgZXZhbHVhdGluZyBpdHMgbGlzdCBvZiByb3cgdGVtcGxhdGVzIHRvIGRpc3BsYXkgKHdoZW4gbXVsdGlUZW1wbGF0ZURhdGFSb3dzXG4gKiBpcyBmYWxzZSwgdGhlcmUgaXMgb25seSBvbmUgdGVtcGxhdGUgcGVyIGRhdGEgb2JqZWN0KS4gRm9yIGVhY2ggcGFpciBvZiBkYXRhIG9iamVjdCBhbmQgcm93XG4gKiB0ZW1wbGF0ZSwgYSBgUmVuZGVyUm93YCBpcyBhZGRlZCB0byB0aGUgbGlzdCBvZiByb3dzIHRvIHJlbmRlci4gSWYgdGhlIGRhdGEgb2JqZWN0IGFuZCByb3dcbiAqIHRlbXBsYXRlIHBhaXIgaGFzIGFscmVhZHkgYmVlbiByZW5kZXJlZCwgdGhlIHByZXZpb3VzbHkgdXNlZCBgUmVuZGVyUm93YCBpcyBhZGRlZDsgZWxzZSBhIG5ld1xuICogYFJlbmRlclJvd2AgaXMgKiBjcmVhdGVkLiBPbmNlIHRoZSBsaXN0IGlzIGNvbXBsZXRlIGFuZCBhbGwgZGF0YSBvYmplY3RzIGhhdmUgYmVlbiBpdGVyYXRlZFxuICogdGhyb3VnaCwgYSBkaWZmIGlzIHBlcmZvcm1lZCB0byBkZXRlcm1pbmUgdGhlIGNoYW5nZXMgdGhhdCBuZWVkIHRvIGJlIG1hZGUgdG8gdGhlIHJlbmRlcmVkIHJvd3MuXG4gKlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbmRlclJvdzxUPiB7XG4gIGRhdGE6IFQ7XG4gIGRhdGFJbmRleDogbnVtYmVyO1xuICByb3dEZWY6IENka1Jvd0RlZjxUPjtcbn1cblxuLyoqXG4gKiBBIGRhdGEgdGFibGUgdGhhdCBjYW4gcmVuZGVyIGEgaGVhZGVyIHJvdywgZGF0YSByb3dzLCBhbmQgYSBmb290ZXIgcm93LlxuICogVXNlcyB0aGUgZGF0YVNvdXJjZSBpbnB1dCB0byBkZXRlcm1pbmUgdGhlIGRhdGEgdG8gYmUgcmVuZGVyZWQuIFRoZSBkYXRhIGNhbiBiZSBwcm92aWRlZCBlaXRoZXJcbiAqIGFzIGEgZGF0YSBhcnJheSwgYW4gT2JzZXJ2YWJsZSBzdHJlYW0gdGhhdCBlbWl0cyB0aGUgZGF0YSBhcnJheSB0byByZW5kZXIsIG9yIGEgRGF0YVNvdXJjZSB3aXRoIGFcbiAqIGNvbm5lY3QgZnVuY3Rpb24gdGhhdCB3aWxsIHJldHVybiBhbiBPYnNlcnZhYmxlIHN0cmVhbSB0aGF0IGVtaXRzIHRoZSBkYXRhIGFycmF5IHRvIHJlbmRlci5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnY2RrLXRhYmxlLCB0YWJsZVtjZGstdGFibGVdJyxcbiAgZXhwb3J0QXM6ICdjZGtUYWJsZScsXG4gIHRlbXBsYXRlOiBDREtfVEFCTEVfVEVNUExBVEUsXG4gIHN0eWxlVXJsOiAndGFibGUuY3NzJyxcbiAgaG9zdDoge1xuICAgICdjbGFzcyc6ICdjZGstdGFibGUnLFxuICAgICdbY2xhc3MuY2RrLXRhYmxlLWZpeGVkLWxheW91dF0nOiAnZml4ZWRMYXlvdXQnLFxuICB9LFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICAvLyBUaGUgXCJPblB1c2hcIiBzdGF0dXMgZm9yIHRoZSBgTWF0VGFibGVgIGNvbXBvbmVudCBpcyBlZmZlY3RpdmVseSBhIG5vb3AsIHNvIHdlIGFyZSByZW1vdmluZyBpdC5cbiAgLy8gVGhlIHZpZXcgZm9yIGBNYXRUYWJsZWAgY29uc2lzdHMgZW50aXJlbHkgb2YgdGVtcGxhdGVzIGRlY2xhcmVkIGluIG90aGVyIHZpZXdzLiBBcyB0aGV5IGFyZVxuICAvLyBkZWNsYXJlZCBlbHNld2hlcmUsIHRoZXkgYXJlIGNoZWNrZWQgd2hlbiB0aGVpciBkZWNsYXJhdGlvbiBwb2ludHMgYXJlIGNoZWNrZWQuXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTp2YWxpZGF0ZS1kZWNvcmF0b3JzXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuRGVmYXVsdCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge3Byb3ZpZGU6IENES19UQUJMRSwgdXNlRXhpc3Rpbmc6IENka1RhYmxlfSxcbiAgICB7cHJvdmlkZTogX1ZJRVdfUkVQRUFURVJfU1RSQVRFR1ksIHVzZUNsYXNzOiBfRGlzcG9zZVZpZXdSZXBlYXRlclN0cmF0ZWd5fSxcbiAgICB7cHJvdmlkZTogX0NPQUxFU0NFRF9TVFlMRV9TQ0hFRFVMRVIsIHVzZUNsYXNzOiBfQ29hbGVzY2VkU3R5bGVTY2hlZHVsZXJ9LFxuICAgIC8vIFByZXZlbnQgbmVzdGVkIHRhYmxlcyBmcm9tIHNlZWluZyB0aGlzIHRhYmxlJ3MgU3RpY2t5UG9zaXRpb25pbmdMaXN0ZW5lci5cbiAgICB7cHJvdmlkZTogU1RJQ0tZX1BPU0lUSU9OSU5HX0xJU1RFTkVSLCB1c2VWYWx1ZTogbnVsbH0sXG4gIF0sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtIZWFkZXJSb3dPdXRsZXQsIERhdGFSb3dPdXRsZXQsIE5vRGF0YVJvd091dGxldCwgRm9vdGVyUm93T3V0bGV0XSxcbn0pXG5leHBvcnQgY2xhc3MgQ2RrVGFibGU8VD5cbiAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBBZnRlckNvbnRlbnRDaGVja2VkLCBDb2xsZWN0aW9uVmlld2VyLCBPbkRlc3Ryb3ksIE9uSW5pdFxue1xuICBwcml2YXRlIF9kb2N1bWVudDogRG9jdW1lbnQ7XG5cbiAgLyoqIExhdGVzdCBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBkYXRhIHNvdXJjZS4gKi9cbiAgcHJvdGVjdGVkIF9kYXRhOiByZWFkb25seSBUW107XG5cbiAgLyoqIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gZGVzdHJveWVkLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9vbkRlc3Ryb3kgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8qKiBMaXN0IG9mIHRoZSByZW5kZXJlZCByb3dzIGFzIGlkZW50aWZpZWQgYnkgdGhlaXIgYFJlbmRlclJvd2Agb2JqZWN0LiAqL1xuICBwcml2YXRlIF9yZW5kZXJSb3dzOiBSZW5kZXJSb3c8VD5bXTtcblxuICAvKiogU3Vic2NyaXB0aW9uIHRoYXQgbGlzdGVucyBmb3IgdGhlIGRhdGEgcHJvdmlkZWQgYnkgdGhlIGRhdGEgc291cmNlLiAqL1xuICBwcml2YXRlIF9yZW5kZXJDaGFuZ2VTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIE1hcCBvZiBhbGwgdGhlIHVzZXIncyBkZWZpbmVkIGNvbHVtbnMgKGhlYWRlciwgZGF0YSwgYW5kIGZvb3RlciBjZWxsIHRlbXBsYXRlKSBpZGVudGlmaWVkIGJ5XG4gICAqIG5hbWUuIENvbGxlY3Rpb24gcG9wdWxhdGVkIGJ5IHRoZSBjb2x1bW4gZGVmaW5pdGlvbnMgZ2F0aGVyZWQgYnkgYENvbnRlbnRDaGlsZHJlbmAgYXMgd2VsbCBhc1xuICAgKiBhbnkgY3VzdG9tIGNvbHVtbiBkZWZpbml0aW9ucyBhZGRlZCB0byBgX2N1c3RvbUNvbHVtbkRlZnNgLlxuICAgKi9cbiAgcHJpdmF0ZSBfY29sdW1uRGVmc0J5TmFtZSA9IG5ldyBNYXA8c3RyaW5nLCBDZGtDb2x1bW5EZWY+KCk7XG5cbiAgLyoqXG4gICAqIFNldCBvZiBhbGwgcm93IGRlZmluaXRpb25zIHRoYXQgY2FuIGJlIHVzZWQgYnkgdGhpcyB0YWJsZS4gUG9wdWxhdGVkIGJ5IHRoZSByb3dzIGdhdGhlcmVkIGJ5XG4gICAqIHVzaW5nIGBDb250ZW50Q2hpbGRyZW5gIGFzIHdlbGwgYXMgYW55IGN1c3RvbSByb3cgZGVmaW5pdGlvbnMgYWRkZWQgdG8gYF9jdXN0b21Sb3dEZWZzYC5cbiAgICovXG4gIHByaXZhdGUgX3Jvd0RlZnM6IENka1Jvd0RlZjxUPltdO1xuXG4gIC8qKlxuICAgKiBTZXQgb2YgYWxsIGhlYWRlciByb3cgZGVmaW5pdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCBieSB0aGlzIHRhYmxlLiBQb3B1bGF0ZWQgYnkgdGhlIHJvd3NcbiAgICogZ2F0aGVyZWQgYnkgdXNpbmcgYENvbnRlbnRDaGlsZHJlbmAgYXMgd2VsbCBhcyBhbnkgY3VzdG9tIHJvdyBkZWZpbml0aW9ucyBhZGRlZCB0b1xuICAgKiBgX2N1c3RvbUhlYWRlclJvd0RlZnNgLlxuICAgKi9cbiAgcHJpdmF0ZSBfaGVhZGVyUm93RGVmczogQ2RrSGVhZGVyUm93RGVmW107XG5cbiAgLyoqXG4gICAqIFNldCBvZiBhbGwgcm93IGRlZmluaXRpb25zIHRoYXQgY2FuIGJlIHVzZWQgYnkgdGhpcyB0YWJsZS4gUG9wdWxhdGVkIGJ5IHRoZSByb3dzIGdhdGhlcmVkIGJ5XG4gICAqIHVzaW5nIGBDb250ZW50Q2hpbGRyZW5gIGFzIHdlbGwgYXMgYW55IGN1c3RvbSByb3cgZGVmaW5pdGlvbnMgYWRkZWQgdG9cbiAgICogYF9jdXN0b21Gb290ZXJSb3dEZWZzYC5cbiAgICovXG4gIHByaXZhdGUgX2Zvb3RlclJvd0RlZnM6IENka0Zvb3RlclJvd0RlZltdO1xuXG4gIC8qKiBEaWZmZXIgdXNlZCB0byBmaW5kIHRoZSBjaGFuZ2VzIGluIHRoZSBkYXRhIHByb3ZpZGVkIGJ5IHRoZSBkYXRhIHNvdXJjZS4gKi9cbiAgcHJpdmF0ZSBfZGF0YURpZmZlcjogSXRlcmFibGVEaWZmZXI8UmVuZGVyUm93PFQ+PjtcblxuICAvKiogU3RvcmVzIHRoZSByb3cgZGVmaW5pdGlvbiB0aGF0IGRvZXMgbm90IGhhdmUgYSB3aGVuIHByZWRpY2F0ZS4gKi9cbiAgcHJpdmF0ZSBfZGVmYXVsdFJvd0RlZjogQ2RrUm93RGVmPFQ+IHwgbnVsbDtcblxuICAvKipcbiAgICogQ29sdW1uIGRlZmluaXRpb25zIHRoYXQgd2VyZSBkZWZpbmVkIG91dHNpZGUgb2YgdGhlIGRpcmVjdCBjb250ZW50IGNoaWxkcmVuIG9mIHRoZSB0YWJsZS5cbiAgICogVGhlc2Ugd2lsbCBiZSBkZWZpbmVkIHdoZW4sIGUuZy4sIGNyZWF0aW5nIGEgd3JhcHBlciBhcm91bmQgdGhlIGNka1RhYmxlIHRoYXQgaGFzXG4gICAqIGNvbHVtbiBkZWZpbml0aW9ucyBhcyAqaXRzKiBjb250ZW50IGNoaWxkLlxuICAgKi9cbiAgcHJpdmF0ZSBfY3VzdG9tQ29sdW1uRGVmcyA9IG5ldyBTZXQ8Q2RrQ29sdW1uRGVmPigpO1xuXG4gIC8qKlxuICAgKiBEYXRhIHJvdyBkZWZpbml0aW9ucyB0aGF0IHdlcmUgZGVmaW5lZCBvdXRzaWRlIG9mIHRoZSBkaXJlY3QgY29udGVudCBjaGlsZHJlbiBvZiB0aGUgdGFibGUuXG4gICAqIFRoZXNlIHdpbGwgYmUgZGVmaW5lZCB3aGVuLCBlLmcuLCBjcmVhdGluZyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBjZGtUYWJsZSB0aGF0IGhhc1xuICAgKiBidWlsdC1pbiBkYXRhIHJvd3MgYXMgKml0cyogY29udGVudCBjaGlsZC5cbiAgICovXG4gIHByaXZhdGUgX2N1c3RvbVJvd0RlZnMgPSBuZXcgU2V0PENka1Jvd0RlZjxUPj4oKTtcblxuICAvKipcbiAgICogSGVhZGVyIHJvdyBkZWZpbml0aW9ucyB0aGF0IHdlcmUgZGVmaW5lZCBvdXRzaWRlIG9mIHRoZSBkaXJlY3QgY29udGVudCBjaGlsZHJlbiBvZiB0aGUgdGFibGUuXG4gICAqIFRoZXNlIHdpbGwgYmUgZGVmaW5lZCB3aGVuLCBlLmcuLCBjcmVhdGluZyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBjZGtUYWJsZSB0aGF0IGhhc1xuICAgKiBidWlsdC1pbiBoZWFkZXIgcm93cyBhcyAqaXRzKiBjb250ZW50IGNoaWxkLlxuICAgKi9cbiAgcHJpdmF0ZSBfY3VzdG9tSGVhZGVyUm93RGVmcyA9IG5ldyBTZXQ8Q2RrSGVhZGVyUm93RGVmPigpO1xuXG4gIC8qKlxuICAgKiBGb290ZXIgcm93IGRlZmluaXRpb25zIHRoYXQgd2VyZSBkZWZpbmVkIG91dHNpZGUgb2YgdGhlIGRpcmVjdCBjb250ZW50IGNoaWxkcmVuIG9mIHRoZSB0YWJsZS5cbiAgICogVGhlc2Ugd2lsbCBiZSBkZWZpbmVkIHdoZW4sIGUuZy4sIGNyZWF0aW5nIGEgd3JhcHBlciBhcm91bmQgdGhlIGNka1RhYmxlIHRoYXQgaGFzIGFcbiAgICogYnVpbHQtaW4gZm9vdGVyIHJvdyBhcyAqaXRzKiBjb250ZW50IGNoaWxkLlxuICAgKi9cbiAgcHJpdmF0ZSBfY3VzdG9tRm9vdGVyUm93RGVmcyA9IG5ldyBTZXQ8Q2RrRm9vdGVyUm93RGVmPigpO1xuXG4gIC8qKiBObyBkYXRhIHJvdyB0aGF0IHdhcyBkZWZpbmVkIG91dHNpZGUgb2YgdGhlIGRpcmVjdCBjb250ZW50IGNoaWxkcmVuIG9mIHRoZSB0YWJsZS4gKi9cbiAgcHJpdmF0ZSBfY3VzdG9tTm9EYXRhUm93OiBDZGtOb0RhdGFSb3cgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBoZWFkZXIgcm93IGRlZmluaXRpb24gaGFzIGJlZW4gY2hhbmdlZC4gVHJpZ2dlcnMgYW4gdXBkYXRlIHRvIHRoZSBoZWFkZXIgcm93IGFmdGVyXG4gICAqIGNvbnRlbnQgaXMgY2hlY2tlZC4gSW5pdGlhbGl6ZWQgYXMgdHJ1ZSBzbyB0aGF0IHRoZSB0YWJsZSByZW5kZXJzIHRoZSBpbml0aWFsIHNldCBvZiByb3dzLlxuICAgKi9cbiAgcHJpdmF0ZSBfaGVhZGVyUm93RGVmQ2hhbmdlZCA9IHRydWU7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGZvb3RlciByb3cgZGVmaW5pdGlvbiBoYXMgYmVlbiBjaGFuZ2VkLiBUcmlnZ2VycyBhbiB1cGRhdGUgdG8gdGhlIGZvb3RlciByb3cgYWZ0ZXJcbiAgICogY29udGVudCBpcyBjaGVja2VkLiBJbml0aWFsaXplZCBhcyB0cnVlIHNvIHRoYXQgdGhlIHRhYmxlIHJlbmRlcnMgdGhlIGluaXRpYWwgc2V0IG9mIHJvd3MuXG4gICAqL1xuICBwcml2YXRlIF9mb290ZXJSb3dEZWZDaGFuZ2VkID0gdHJ1ZTtcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgc3RpY2t5IGNvbHVtbiBzdHlsZXMgbmVlZCB0byBiZSB1cGRhdGVkLiBTZXQgdG8gYHRydWVgIHdoZW4gdGhlIHZpc2libGUgY29sdW1uc1xuICAgKiBjaGFuZ2UuXG4gICAqL1xuICBwcml2YXRlIF9zdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdGlja3kgc3R5bGVyIHNob3VsZCByZWNhbGN1bGF0ZSBjZWxsIHdpZHRocyB3aGVuIGFwcGx5aW5nIHN0aWNreSBzdHlsZXMuIElmXG4gICAqIGBmYWxzZWAsIGNhY2hlZCB2YWx1ZXMgd2lsbCBiZSB1c2VkIGluc3RlYWQuIFRoaXMgaXMgb25seSBhcHBsaWNhYmxlIHRvIHRhYmxlcyB3aXRoXG4gICAqIHtAbGluayBmaXhlZExheW91dH0gZW5hYmxlZC4gRm9yIG90aGVyIHRhYmxlcywgY2VsbCB3aWR0aHMgd2lsbCBhbHdheXMgYmUgcmVjYWxjdWxhdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfZm9yY2VSZWNhbGN1bGF0ZUNlbGxXaWR0aHMgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBDYWNoZSBvZiB0aGUgbGF0ZXN0IHJlbmRlcmVkIGBSZW5kZXJSb3dgIG9iamVjdHMgYXMgYSBtYXAgZm9yIGVhc3kgcmV0cmlldmFsIHdoZW4gY29uc3RydWN0aW5nXG4gICAqIGEgbmV3IGxpc3Qgb2YgYFJlbmRlclJvd2Agb2JqZWN0cyBmb3IgcmVuZGVyaW5nIHJvd3MuIFNpbmNlIHRoZSBuZXcgbGlzdCBpcyBjb25zdHJ1Y3RlZCB3aXRoXG4gICAqIHRoZSBjYWNoZWQgYFJlbmRlclJvd2Agb2JqZWN0cyB3aGVuIHBvc3NpYmxlLCB0aGUgcm93IGlkZW50aXR5IGlzIHByZXNlcnZlZCB3aGVuIHRoZSBkYXRhXG4gICAqIGFuZCByb3cgdGVtcGxhdGUgbWF0Y2hlcywgd2hpY2ggYWxsb3dzIHRoZSBgSXRlcmFibGVEaWZmZXJgIHRvIGNoZWNrIHJvd3MgYnkgcmVmZXJlbmNlXG4gICAqIGFuZCB1bmRlcnN0YW5kIHdoaWNoIHJvd3MgYXJlIGFkZGVkL21vdmVkL3JlbW92ZWQuXG4gICAqXG4gICAqIEltcGxlbWVudGVkIGFzIGEgbWFwIG9mIG1hcHMgd2hlcmUgdGhlIGZpcnN0IGtleSBpcyB0aGUgYGRhdGE6IFRgIG9iamVjdCBhbmQgdGhlIHNlY29uZCBpcyB0aGVcbiAgICogYENka1Jvd0RlZjxUPmAgb2JqZWN0LiBXaXRoIHRoZSB0d28ga2V5cywgdGhlIGNhY2hlIHBvaW50cyB0byBhIGBSZW5kZXJSb3c8VD5gIG9iamVjdCB0aGF0XG4gICAqIGNvbnRhaW5zIGFuIGFycmF5IG9mIGNyZWF0ZWQgcGFpcnMuIFRoZSBhcnJheSBpcyBuZWNlc3NhcnkgdG8gaGFuZGxlIGNhc2VzIHdoZXJlIHRoZSBkYXRhXG4gICAqIGFycmF5IGNvbnRhaW5zIG11bHRpcGxlIGR1cGxpY2F0ZSBkYXRhIG9iamVjdHMgYW5kIGVhY2ggaW5zdGFudGlhdGVkIGBSZW5kZXJSb3dgIG11c3QgYmVcbiAgICogc3RvcmVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfY2FjaGVkUmVuZGVyUm93c01hcCA9IG5ldyBNYXA8VCwgV2Vha01hcDxDZGtSb3dEZWY8VD4sIFJlbmRlclJvdzxUPltdPj4oKTtcblxuICAvKiogV2hldGhlciB0aGUgdGFibGUgaXMgYXBwbGllZCB0byBhIG5hdGl2ZSBgPHRhYmxlPmAuICovXG4gIHByb3RlY3RlZCBfaXNOYXRpdmVIdG1sVGFibGU6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFV0aWxpdHkgY2xhc3MgdGhhdCBpcyByZXNwb25zaWJsZSBmb3IgYXBwbHlpbmcgdGhlIGFwcHJvcHJpYXRlIHN0aWNreSBwb3NpdGlvbmluZyBzdHlsZXMgdG9cbiAgICogdGhlIHRhYmxlJ3Mgcm93cyBhbmQgY2VsbHMuXG4gICAqL1xuICBwcml2YXRlIF9zdGlja3lTdHlsZXI6IFN0aWNreVN0eWxlcjtcblxuICAvKipcbiAgICogQ1NTIGNsYXNzIGFkZGVkIHRvIGFueSByb3cgb3IgY2VsbCB0aGF0IGhhcyBzdGlja3kgcG9zaXRpb25pbmcgYXBwbGllZC4gTWF5IGJlIG92ZXJyaWRkZW4gYnlcbiAgICogdGFibGUgc3ViY2xhc3Nlcy5cbiAgICovXG4gIHByb3RlY3RlZCBzdGlja3lDc3NDbGFzczogc3RyaW5nID0gJ2Nkay10YWJsZS1zdGlja3knO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIG1hbnVhbGx5IGFkZCBwb3NpdGlvbjogc3RpY2t5IHRvIGFsbCBzdGlja3kgY2VsbCBlbGVtZW50cy4gTm90IG5lZWRlZCBpZlxuICAgKiB0aGUgcG9zaXRpb24gaXMgc2V0IGluIGEgc2VsZWN0b3IgYXNzb2NpYXRlZCB3aXRoIHRoZSB2YWx1ZSBvZiBzdGlja3lDc3NDbGFzcy4gTWF5IGJlXG4gICAqIG92ZXJyaWRkZW4gYnkgdGFibGUgc3ViY2xhc3Nlc1xuICAgKi9cbiAgcHJvdGVjdGVkIG5lZWRzUG9zaXRpb25TdGlja3lPbkVsZW1lbnQgPSB0cnVlO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBjb21wb25lbnQgaXMgYmVpbmcgcmVuZGVyZWQgb24gdGhlIHNlcnZlci4gKi9cbiAgcHJvdGVjdGVkIF9pc1NlcnZlcjogYm9vbGVhbjtcblxuICAvKiogV2hldGhlciB0aGUgbm8gZGF0YSByb3cgaXMgY3VycmVudGx5IHNob3dpbmcgYW55dGhpbmcuICovXG4gIHByaXZhdGUgX2lzU2hvd2luZ05vRGF0YVJvdyA9IGZhbHNlO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSB0YWJsZSBoYXMgcmVuZGVyZWQgb3V0IGFsbCB0aGUgb3V0bGV0cyBmb3IgdGhlIGZpcnN0IHRpbWUuICovXG4gIHByaXZhdGUgX2hhc0FsbE91dGxldHMgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgdGFibGUgaXMgZG9uZSBpbml0aWFsaXppbmcuICovXG4gIHByaXZhdGUgX2hhc0luaXRpYWxpemVkID0gZmFsc2U7XG5cbiAgLyoqIEFyaWEgcm9sZSB0byBhcHBseSB0byB0aGUgdGFibGUncyBjZWxscyBiYXNlZCBvbiB0aGUgdGFibGUncyBvd24gcm9sZS4gKi9cbiAgX2dldENlbGxSb2xlKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGlmICh0aGlzLl9jZWxsUm9sZUludGVybmFsID09PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIFBlcmZvcm0gdGhpcyBsYXppbHkgaW4gY2FzZSB0aGUgdGFibGUncyByb2xlIHdhcyB1cGRhdGVkIGJ5IGEgZGlyZWN0aXZlIGFmdGVyIGNvbnN0cnVjdGlvbi5cbiAgICAgIGNvbnN0IHJvbGUgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZ2V0QXR0cmlidXRlKCdyb2xlJyk7XG4gICAgICBjb25zdCBjZWxsUm9sZSA9IHJvbGUgPT09ICdncmlkJyB8fCByb2xlID09PSAndHJlZWdyaWQnID8gJ2dyaWRjZWxsJyA6ICdjZWxsJztcbiAgICAgIHRoaXMuX2NlbGxSb2xlSW50ZXJuYWwgPSB0aGlzLl9pc05hdGl2ZUh0bWxUYWJsZSAmJiBjZWxsUm9sZSA9PT0gJ2NlbGwnID8gbnVsbCA6IGNlbGxSb2xlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9jZWxsUm9sZUludGVybmFsO1xuICB9XG4gIHByaXZhdGUgX2NlbGxSb2xlSW50ZXJuYWw6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgLyoqXG4gICAqIFRyYWNraW5nIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB1c2VkIHRvIGNoZWNrIHRoZSBkaWZmZXJlbmNlcyBpbiBkYXRhIGNoYW5nZXMuIFVzZWQgc2ltaWxhcmx5XG4gICAqIHRvIGBuZ0ZvcmAgYHRyYWNrQnlgIGZ1bmN0aW9uLiBPcHRpbWl6ZSByb3cgb3BlcmF0aW9ucyBieSBpZGVudGlmeWluZyBhIHJvdyBiYXNlZCBvbiBpdHMgZGF0YVxuICAgKiByZWxhdGl2ZSB0byB0aGUgZnVuY3Rpb24gdG8ga25vdyBpZiBhIHJvdyBzaG91bGQgYmUgYWRkZWQvcmVtb3ZlZC9tb3ZlZC5cbiAgICogQWNjZXB0cyBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgdHdvIHBhcmFtZXRlcnMsIGBpbmRleGAgYW5kIGBpdGVtYC5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCB0cmFja0J5KCk6IFRyYWNrQnlGdW5jdGlvbjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuX3RyYWNrQnlGbjtcbiAgfVxuICBzZXQgdHJhY2tCeShmbjogVHJhY2tCeUZ1bmN0aW9uPFQ+KSB7XG4gICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmIGZuICE9IG51bGwgJiYgdHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBjb25zb2xlLndhcm4oYHRyYWNrQnkgbXVzdCBiZSBhIGZ1bmN0aW9uLCBidXQgcmVjZWl2ZWQgJHtKU09OLnN0cmluZ2lmeShmbil9LmApO1xuICAgIH1cbiAgICB0aGlzLl90cmFja0J5Rm4gPSBmbjtcbiAgfVxuICBwcml2YXRlIF90cmFja0J5Rm46IFRyYWNrQnlGdW5jdGlvbjxUPjtcblxuICAvKipcbiAgICogVGhlIHRhYmxlJ3Mgc291cmNlIG9mIGRhdGEsIHdoaWNoIGNhbiBiZSBwcm92aWRlZCBpbiB0aHJlZSB3YXlzIChpbiBvcmRlciBvZiBjb21wbGV4aXR5KTpcbiAgICogICAtIFNpbXBsZSBkYXRhIGFycmF5IChlYWNoIG9iamVjdCByZXByZXNlbnRzIG9uZSB0YWJsZSByb3cpXG4gICAqICAgLSBTdHJlYW0gdGhhdCBlbWl0cyBhIGRhdGEgYXJyYXkgZWFjaCB0aW1lIHRoZSBhcnJheSBjaGFuZ2VzXG4gICAqICAgLSBgRGF0YVNvdXJjZWAgb2JqZWN0IHRoYXQgaW1wbGVtZW50cyB0aGUgY29ubmVjdC9kaXNjb25uZWN0IGludGVyZmFjZS5cbiAgICpcbiAgICogSWYgYSBkYXRhIGFycmF5IGlzIHByb3ZpZGVkLCB0aGUgdGFibGUgbXVzdCBiZSBub3RpZmllZCB3aGVuIHRoZSBhcnJheSdzIG9iamVjdHMgYXJlXG4gICAqIGFkZGVkLCByZW1vdmVkLCBvciBtb3ZlZC4gVGhpcyBjYW4gYmUgZG9uZSBieSBjYWxsaW5nIHRoZSBgcmVuZGVyUm93cygpYCBmdW5jdGlvbiB3aGljaCB3aWxsXG4gICAqIHJlbmRlciB0aGUgZGlmZiBzaW5jZSB0aGUgbGFzdCB0YWJsZSByZW5kZXIuIElmIHRoZSBkYXRhIGFycmF5IHJlZmVyZW5jZSBpcyBjaGFuZ2VkLCB0aGUgdGFibGVcbiAgICogd2lsbCBhdXRvbWF0aWNhbGx5IHRyaWdnZXIgYW4gdXBkYXRlIHRvIHRoZSByb3dzLlxuICAgKlxuICAgKiBXaGVuIHByb3ZpZGluZyBhbiBPYnNlcnZhYmxlIHN0cmVhbSwgdGhlIHRhYmxlIHdpbGwgdHJpZ2dlciBhbiB1cGRhdGUgYXV0b21hdGljYWxseSB3aGVuIHRoZVxuICAgKiBzdHJlYW0gZW1pdHMgYSBuZXcgYXJyYXkgb2YgZGF0YS5cbiAgICpcbiAgICogRmluYWxseSwgd2hlbiBwcm92aWRpbmcgYSBgRGF0YVNvdXJjZWAgb2JqZWN0LCB0aGUgdGFibGUgd2lsbCB1c2UgdGhlIE9ic2VydmFibGUgc3RyZWFtXG4gICAqIHByb3ZpZGVkIGJ5IHRoZSBjb25uZWN0IGZ1bmN0aW9uIGFuZCB0cmlnZ2VyIHVwZGF0ZXMgd2hlbiB0aGF0IHN0cmVhbSBlbWl0cyBuZXcgZGF0YSBhcnJheVxuICAgKiB2YWx1ZXMuIER1cmluZyB0aGUgdGFibGUncyBuZ09uRGVzdHJveSBvciB3aGVuIHRoZSBkYXRhIHNvdXJjZSBpcyByZW1vdmVkIGZyb20gdGhlIHRhYmxlLCB0aGVcbiAgICogdGFibGUgd2lsbCBjYWxsIHRoZSBEYXRhU291cmNlJ3MgYGRpc2Nvbm5lY3RgIGZ1bmN0aW9uIChtYXkgYmUgdXNlZnVsIGZvciBjbGVhbmluZyB1cCBhbnlcbiAgICogc3Vic2NyaXB0aW9ucyByZWdpc3RlcmVkIGR1cmluZyB0aGUgY29ubmVjdCBwcm9jZXNzKS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBkYXRhU291cmNlKCk6IENka1RhYmxlRGF0YVNvdXJjZUlucHV0PFQ+IHtcbiAgICByZXR1cm4gdGhpcy5fZGF0YVNvdXJjZTtcbiAgfVxuICBzZXQgZGF0YVNvdXJjZShkYXRhU291cmNlOiBDZGtUYWJsZURhdGFTb3VyY2VJbnB1dDxUPikge1xuICAgIGlmICh0aGlzLl9kYXRhU291cmNlICE9PSBkYXRhU291cmNlKSB7XG4gICAgICB0aGlzLl9zd2l0Y2hEYXRhU291cmNlKGRhdGFTb3VyY2UpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9kYXRhU291cmNlOiBDZGtUYWJsZURhdGFTb3VyY2VJbnB1dDxUPjtcblxuICAvKipcbiAgICogV2hldGhlciB0byBhbGxvdyBtdWx0aXBsZSByb3dzIHBlciBkYXRhIG9iamVjdCBieSBldmFsdWF0aW5nIHdoaWNoIHJvd3MgZXZhbHVhdGUgdGhlaXIgJ3doZW4nXG4gICAqIHByZWRpY2F0ZSB0byB0cnVlLiBJZiBgbXVsdGlUZW1wbGF0ZURhdGFSb3dzYCBpcyBmYWxzZSwgd2hpY2ggaXMgdGhlIGRlZmF1bHQgdmFsdWUsIHRoZW4gZWFjaFxuICAgKiBkYXRhb2JqZWN0IHdpbGwgcmVuZGVyIHRoZSBmaXJzdCByb3cgdGhhdCBldmFsdWF0ZXMgaXRzIHdoZW4gcHJlZGljYXRlIHRvIHRydWUsIGluIHRoZSBvcmRlclxuICAgKiBkZWZpbmVkIGluIHRoZSB0YWJsZSwgb3Igb3RoZXJ3aXNlIHRoZSBkZWZhdWx0IHJvdyB3aGljaCBkb2VzIG5vdCBoYXZlIGEgd2hlbiBwcmVkaWNhdGUuXG4gICAqL1xuICBASW5wdXQoe3RyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZX0pXG4gIGdldCBtdWx0aVRlbXBsYXRlRGF0YVJvd3MoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX211bHRpVGVtcGxhdGVEYXRhUm93cztcbiAgfVxuICBzZXQgbXVsdGlUZW1wbGF0ZURhdGFSb3dzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fbXVsdGlUZW1wbGF0ZURhdGFSb3dzID0gdmFsdWU7XG5cbiAgICAvLyBJbiBJdnkgaWYgdGhpcyB2YWx1ZSBpcyBzZXQgdmlhIGEgc3RhdGljIGF0dHJpYnV0ZSAoZS5nLiA8dGFibGUgbXVsdGlUZW1wbGF0ZURhdGFSb3dzPiksXG4gICAgLy8gdGhpcyBzZXR0ZXIgd2lsbCBiZSBpbnZva2VkIGJlZm9yZSB0aGUgcm93IG91dGxldCBoYXMgYmVlbiBkZWZpbmVkIGhlbmNlIHRoZSBudWxsIGNoZWNrLlxuICAgIGlmICh0aGlzLl9yb3dPdXRsZXQgJiYgdGhpcy5fcm93T3V0bGV0LnZpZXdDb250YWluZXIubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9mb3JjZVJlbmRlckRhdGFSb3dzKCk7XG4gICAgICB0aGlzLnVwZGF0ZVN0aWNreUNvbHVtblN0eWxlcygpO1xuICAgIH1cbiAgfVxuICBfbXVsdGlUZW1wbGF0ZURhdGFSb3dzOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gdXNlIGEgZml4ZWQgdGFibGUgbGF5b3V0LiBFbmFibGluZyB0aGlzIG9wdGlvbiB3aWxsIGVuZm9yY2UgY29uc2lzdGVudCBjb2x1bW4gd2lkdGhzXG4gICAqIGFuZCBvcHRpbWl6ZSByZW5kZXJpbmcgc3RpY2t5IHN0eWxlcyBmb3IgbmF0aXZlIHRhYmxlcy4gTm8tb3AgZm9yIGZsZXggdGFibGVzLlxuICAgKi9cbiAgQElucHV0KHt0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGV9KVxuICBnZXQgZml4ZWRMYXlvdXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2ZpeGVkTGF5b3V0O1xuICB9XG4gIHNldCBmaXhlZExheW91dCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2ZpeGVkTGF5b3V0ID0gdmFsdWU7XG5cbiAgICAvLyBUb2dnbGluZyBgZml4ZWRMYXlvdXRgIG1heSBjaGFuZ2UgY29sdW1uIHdpZHRocy4gU3RpY2t5IGNvbHVtbiBzdHlsZXMgc2hvdWxkIGJlIHJlY2FsY3VsYXRlZC5cbiAgICB0aGlzLl9mb3JjZVJlY2FsY3VsYXRlQ2VsbFdpZHRocyA9IHRydWU7XG4gICAgdGhpcy5fc3RpY2t5Q29sdW1uU3R5bGVzTmVlZFJlc2V0ID0gdHJ1ZTtcbiAgfVxuICBwcml2YXRlIF9maXhlZExheW91dDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGVuIHRoZSB0YWJsZSBjb21wbGV0ZXMgcmVuZGVyaW5nIGEgc2V0IG9mIGRhdGEgcm93cyBiYXNlZCBvbiB0aGUgbGF0ZXN0IGRhdGEgZnJvbSB0aGVcbiAgICogZGF0YSBzb3VyY2UsIGV2ZW4gaWYgdGhlIHNldCBvZiByb3dzIGlzIGVtcHR5LlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIHJlYWRvbmx5IGNvbnRlbnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8vIFRPRE8oYW5kcmV3c2VndWluKTogUmVtb3ZlIG1heCB2YWx1ZSBhcyB0aGUgZW5kIGluZGV4XG4gIC8vICAgYW5kIGluc3RlYWQgY2FsY3VsYXRlIHRoZSB2aWV3IG9uIGluaXQgYW5kIHNjcm9sbC5cbiAgLyoqXG4gICAqIFN0cmVhbSBjb250YWluaW5nIHRoZSBsYXRlc3QgaW5mb3JtYXRpb24gb24gd2hhdCByb3dzIGFyZSBiZWluZyBkaXNwbGF5ZWQgb24gc2NyZWVuLlxuICAgKiBDYW4gYmUgdXNlZCBieSB0aGUgZGF0YSBzb3VyY2UgdG8gYXMgYSBoZXVyaXN0aWMgb2Ygd2hhdCBkYXRhIHNob3VsZCBiZSBwcm92aWRlZC5cbiAgICpcbiAgICogQGRvY3MtcHJpdmF0ZVxuICAgKi9cbiAgcmVhZG9ubHkgdmlld0NoYW5nZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8e3N0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyfT4oe1xuICAgIHN0YXJ0OiAwLFxuICAgIGVuZDogTnVtYmVyLk1BWF9WQUxVRSxcbiAgfSk7XG5cbiAgLy8gT3V0bGV0cyBpbiB0aGUgdGFibGUncyB0ZW1wbGF0ZSB3aGVyZSB0aGUgaGVhZGVyLCBkYXRhIHJvd3MsIGFuZCBmb290ZXIgd2lsbCBiZSBpbnNlcnRlZC5cbiAgX3Jvd091dGxldDogRGF0YVJvd091dGxldDtcbiAgX2hlYWRlclJvd091dGxldDogSGVhZGVyUm93T3V0bGV0O1xuICBfZm9vdGVyUm93T3V0bGV0OiBGb290ZXJSb3dPdXRsZXQ7XG4gIF9ub0RhdGFSb3dPdXRsZXQ6IE5vRGF0YVJvd091dGxldDtcblxuICAvKipcbiAgICogVGhlIGNvbHVtbiBkZWZpbml0aW9ucyBwcm92aWRlZCBieSB0aGUgdXNlciB0aGF0IGNvbnRhaW4gd2hhdCB0aGUgaGVhZGVyLCBkYXRhLCBhbmQgZm9vdGVyXG4gICAqIGNlbGxzIHNob3VsZCByZW5kZXIgZm9yIGVhY2ggY29sdW1uLlxuICAgKi9cbiAgQENvbnRlbnRDaGlsZHJlbihDZGtDb2x1bW5EZWYsIHtkZXNjZW5kYW50czogdHJ1ZX0pIF9jb250ZW50Q29sdW1uRGVmczogUXVlcnlMaXN0PENka0NvbHVtbkRlZj47XG5cbiAgLyoqIFNldCBvZiBkYXRhIHJvdyBkZWZpbml0aW9ucyB0aGF0IHdlcmUgcHJvdmlkZWQgdG8gdGhlIHRhYmxlIGFzIGNvbnRlbnQgY2hpbGRyZW4uICovXG4gIEBDb250ZW50Q2hpbGRyZW4oQ2RrUm93RGVmLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfY29udGVudFJvd0RlZnM6IFF1ZXJ5TGlzdDxDZGtSb3dEZWY8VD4+O1xuXG4gIC8qKiBTZXQgb2YgaGVhZGVyIHJvdyBkZWZpbml0aW9ucyB0aGF0IHdlcmUgcHJvdmlkZWQgdG8gdGhlIHRhYmxlIGFzIGNvbnRlbnQgY2hpbGRyZW4uICovXG4gIEBDb250ZW50Q2hpbGRyZW4oQ2RrSGVhZGVyUm93RGVmLCB7XG4gICAgZGVzY2VuZGFudHM6IHRydWUsXG4gIH0pXG4gIF9jb250ZW50SGVhZGVyUm93RGVmczogUXVlcnlMaXN0PENka0hlYWRlclJvd0RlZj47XG5cbiAgLyoqIFNldCBvZiBmb290ZXIgcm93IGRlZmluaXRpb25zIHRoYXQgd2VyZSBwcm92aWRlZCB0byB0aGUgdGFibGUgYXMgY29udGVudCBjaGlsZHJlbi4gKi9cbiAgQENvbnRlbnRDaGlsZHJlbihDZGtGb290ZXJSb3dEZWYsIHtcbiAgICBkZXNjZW5kYW50czogdHJ1ZSxcbiAgfSlcbiAgX2NvbnRlbnRGb290ZXJSb3dEZWZzOiBRdWVyeUxpc3Q8Q2RrRm9vdGVyUm93RGVmPjtcblxuICAvKiogUm93IGRlZmluaXRpb24gdGhhdCB3aWxsIG9ubHkgYmUgcmVuZGVyZWQgaWYgdGhlcmUncyBubyBkYXRhIGluIHRoZSB0YWJsZS4gKi9cbiAgQENvbnRlbnRDaGlsZChDZGtOb0RhdGFSb3cpIF9ub0RhdGFSb3c6IENka05vRGF0YVJvdztcblxuICBwcml2YXRlIF9pbmplY3RvciA9IGluamVjdChJbmplY3Rvcik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9kaWZmZXJzOiBJdGVyYWJsZURpZmZlcnMsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIEBBdHRyaWJ1dGUoJ3JvbGUnKSByb2xlOiBzdHJpbmcsXG4gICAgQE9wdGlvbmFsKCkgcHJvdGVjdGVkIHJlYWRvbmx5IF9kaXI6IERpcmVjdGlvbmFsaXR5LFxuICAgIEBJbmplY3QoRE9DVU1FTlQpIF9kb2N1bWVudDogYW55LFxuICAgIHByaXZhdGUgX3BsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICBASW5qZWN0KF9WSUVXX1JFUEVBVEVSX1NUUkFURUdZKVxuICAgIHByb3RlY3RlZCByZWFkb25seSBfdmlld1JlcGVhdGVyOiBfVmlld1JlcGVhdGVyPFQsIFJlbmRlclJvdzxUPiwgUm93Q29udGV4dDxUPj4sXG4gICAgQEluamVjdChfQ09BTEVTQ0VEX1NUWUxFX1NDSEVEVUxFUilcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgX2NvYWxlc2NlZFN0eWxlU2NoZWR1bGVyOiBfQ29hbGVzY2VkU3R5bGVTY2hlZHVsZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRSdWxlcjogVmlld3BvcnRSdWxlcixcbiAgICAvKipcbiAgICAgKiBAZGVwcmVjYXRlZCBgX3N0aWNreVBvc2l0aW9uaW5nTGlzdGVuZXJgIHBhcmFtZXRlciB0byBiZWNvbWUgcmVxdWlyZWQuXG4gICAgICogQGJyZWFraW5nLWNoYW5nZSAxMy4wLjBcbiAgICAgKi9cbiAgICBAT3B0aW9uYWwoKVxuICAgIEBTa2lwU2VsZigpXG4gICAgQEluamVjdChTVElDS1lfUE9TSVRJT05JTkdfTElTVEVORVIpXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IF9zdGlja3lQb3NpdGlvbmluZ0xpc3RlbmVyOiBTdGlja3lQb3NpdGlvbmluZ0xpc3RlbmVyLFxuICAgIC8qKlxuICAgICAqIEBkZXByZWNhdGVkIGBfdW51c2VkTmdab25lYCBwYXJhbWV0ZXIgdG8gYmUgcmVtb3ZlZC5cbiAgICAgKiBAYnJlYWtpbmctY2hhbmdlIDE5LjAuMFxuICAgICAqL1xuICAgIEBPcHRpb25hbCgpIF91bnVzZWROZ1pvbmU/OiBOZ1pvbmUsXG4gICkge1xuICAgIGlmICghcm9sZSkge1xuICAgICAgX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3JvbGUnLCAndGFibGUnKTtcbiAgICB9XG5cbiAgICB0aGlzLl9kb2N1bWVudCA9IF9kb2N1bWVudDtcbiAgICB0aGlzLl9pc1NlcnZlciA9ICFfcGxhdGZvcm0uaXNCcm93c2VyO1xuICAgIHRoaXMuX2lzTmF0aXZlSHRtbFRhYmxlID0gX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5ub2RlTmFtZSA9PT0gJ1RBQkxFJztcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuX3NldHVwU3RpY2t5U3R5bGVyKCk7XG5cbiAgICAvLyBTZXQgdXAgdGhlIHRyYWNrQnkgZnVuY3Rpb24gc28gdGhhdCBpdCB1c2VzIHRoZSBgUmVuZGVyUm93YCBhcyBpdHMgaWRlbnRpdHkgYnkgZGVmYXVsdC4gSWZcbiAgICAvLyB0aGUgdXNlciBoYXMgcHJvdmlkZWQgYSBjdXN0b20gdHJhY2tCeSwgcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhhdCBmdW5jdGlvbiBhcyBldmFsdWF0ZWRcbiAgICAvLyB3aXRoIHRoZSB2YWx1ZXMgb2YgdGhlIGBSZW5kZXJSb3dgJ3MgZGF0YSBhbmQgaW5kZXguXG4gICAgdGhpcy5fZGF0YURpZmZlciA9IHRoaXMuX2RpZmZlcnMuZmluZChbXSkuY3JlYXRlKChfaTogbnVtYmVyLCBkYXRhUm93OiBSZW5kZXJSb3c8VD4pID0+IHtcbiAgICAgIHJldHVybiB0aGlzLnRyYWNrQnkgPyB0aGlzLnRyYWNrQnkoZGF0YVJvdy5kYXRhSW5kZXgsIGRhdGFSb3cuZGF0YSkgOiBkYXRhUm93O1xuICAgIH0pO1xuXG4gICAgdGhpcy5fdmlld3BvcnRSdWxlclxuICAgICAgLmNoYW5nZSgpXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5fb25EZXN0cm95KSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLl9mb3JjZVJlY2FsY3VsYXRlQ2VsbFdpZHRocyA9IHRydWU7XG4gICAgICB9KTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLl9oYXNJbml0aWFsaXplZCA9IHRydWU7XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudENoZWNrZWQoKSB7XG4gICAgLy8gT25seSBzdGFydCByZS1yZW5kZXJpbmcgaW4gYG5nQWZ0ZXJDb250ZW50Q2hlY2tlZGAgYWZ0ZXIgdGhlIGZpcnN0IHJlbmRlci5cbiAgICBpZiAodGhpcy5fY2FuUmVuZGVyKCkpIHtcbiAgICAgIHRoaXMuX3JlbmRlcigpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIFtcbiAgICAgIHRoaXMuX3Jvd091dGxldD8udmlld0NvbnRhaW5lcixcbiAgICAgIHRoaXMuX2hlYWRlclJvd091dGxldD8udmlld0NvbnRhaW5lcixcbiAgICAgIHRoaXMuX2Zvb3RlclJvd091dGxldD8udmlld0NvbnRhaW5lcixcbiAgICAgIHRoaXMuX2NhY2hlZFJlbmRlclJvd3NNYXAsXG4gICAgICB0aGlzLl9jdXN0b21Db2x1bW5EZWZzLFxuICAgICAgdGhpcy5fY3VzdG9tUm93RGVmcyxcbiAgICAgIHRoaXMuX2N1c3RvbUhlYWRlclJvd0RlZnMsXG4gICAgICB0aGlzLl9jdXN0b21Gb290ZXJSb3dEZWZzLFxuICAgICAgdGhpcy5fY29sdW1uRGVmc0J5TmFtZSxcbiAgICBdLmZvckVhY2goKGRlZjogVmlld0NvbnRhaW5lclJlZiB8IFNldDx1bmtub3duPiB8IE1hcDx1bmtub3duLCB1bmtub3duPiB8IHVuZGVmaW5lZCkgPT4ge1xuICAgICAgZGVmPy5jbGVhcigpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5faGVhZGVyUm93RGVmcyA9IFtdO1xuICAgIHRoaXMuX2Zvb3RlclJvd0RlZnMgPSBbXTtcbiAgICB0aGlzLl9kZWZhdWx0Um93RGVmID0gbnVsbDtcbiAgICB0aGlzLl9vbkRlc3Ryb3kubmV4dCgpO1xuICAgIHRoaXMuX29uRGVzdHJveS5jb21wbGV0ZSgpO1xuXG4gICAgaWYgKGlzRGF0YVNvdXJjZSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICB0aGlzLmRhdGFTb3VyY2UuZGlzY29ubmVjdCh0aGlzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVuZGVycyByb3dzIGJhc2VkIG9uIHRoZSB0YWJsZSdzIGxhdGVzdCBzZXQgb2YgZGF0YSwgd2hpY2ggd2FzIGVpdGhlciBwcm92aWRlZCBkaXJlY3RseSBhcyBhblxuICAgKiBpbnB1dCBvciByZXRyaWV2ZWQgdGhyb3VnaCBhbiBPYnNlcnZhYmxlIHN0cmVhbSAoZGlyZWN0bHkgb3IgZnJvbSBhIERhdGFTb3VyY2UpLlxuICAgKiBDaGVja3MgZm9yIGRpZmZlcmVuY2VzIGluIHRoZSBkYXRhIHNpbmNlIHRoZSBsYXN0IGRpZmYgdG8gcGVyZm9ybSBvbmx5IHRoZSBuZWNlc3NhcnlcbiAgICogY2hhbmdlcyAoYWRkL3JlbW92ZS9tb3ZlIHJvd3MpLlxuICAgKlxuICAgKiBJZiB0aGUgdGFibGUncyBkYXRhIHNvdXJjZSBpcyBhIERhdGFTb3VyY2Ugb3IgT2JzZXJ2YWJsZSwgdGhpcyB3aWxsIGJlIGludm9rZWQgYXV0b21hdGljYWxseVxuICAgKiBlYWNoIHRpbWUgdGhlIHByb3ZpZGVkIE9ic2VydmFibGUgc3RyZWFtIGVtaXRzIGEgbmV3IGRhdGEgYXJyYXkuIE90aGVyd2lzZSBpZiB5b3VyIGRhdGEgaXNcbiAgICogYW4gYXJyYXksIHRoaXMgZnVuY3Rpb24gd2lsbCBuZWVkIHRvIGJlIGNhbGxlZCB0byByZW5kZXIgYW55IGNoYW5nZXMuXG4gICAqL1xuICByZW5kZXJSb3dzKCkge1xuICAgIHRoaXMuX3JlbmRlclJvd3MgPSB0aGlzLl9nZXRBbGxSZW5kZXJSb3dzKCk7XG4gICAgY29uc3QgY2hhbmdlcyA9IHRoaXMuX2RhdGFEaWZmZXIuZGlmZih0aGlzLl9yZW5kZXJSb3dzKTtcbiAgICBpZiAoIWNoYW5nZXMpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZU5vRGF0YVJvdygpO1xuICAgICAgdGhpcy5jb250ZW50Q2hhbmdlZC5uZXh0KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHZpZXdDb250YWluZXIgPSB0aGlzLl9yb3dPdXRsZXQudmlld0NvbnRhaW5lcjtcblxuICAgIHRoaXMuX3ZpZXdSZXBlYXRlci5hcHBseUNoYW5nZXMoXG4gICAgICBjaGFuZ2VzLFxuICAgICAgdmlld0NvbnRhaW5lcixcbiAgICAgIChcbiAgICAgICAgcmVjb3JkOiBJdGVyYWJsZUNoYW5nZVJlY29yZDxSZW5kZXJSb3c8VD4+LFxuICAgICAgICBfYWRqdXN0ZWRQcmV2aW91c0luZGV4OiBudW1iZXIgfCBudWxsLFxuICAgICAgICBjdXJyZW50SW5kZXg6IG51bWJlciB8IG51bGwsXG4gICAgICApID0+IHRoaXMuX2dldEVtYmVkZGVkVmlld0FyZ3MocmVjb3JkLml0ZW0sIGN1cnJlbnRJbmRleCEpLFxuICAgICAgcmVjb3JkID0+IHJlY29yZC5pdGVtLmRhdGEsXG4gICAgICAoY2hhbmdlOiBfVmlld1JlcGVhdGVySXRlbUNoYW5nZTxSZW5kZXJSb3c8VD4sIFJvd0NvbnRleHQ8VD4+KSA9PiB7XG4gICAgICAgIGlmIChjaGFuZ2Uub3BlcmF0aW9uID09PSBfVmlld1JlcGVhdGVyT3BlcmF0aW9uLklOU0VSVEVEICYmIGNoYW5nZS5jb250ZXh0KSB7XG4gICAgICAgICAgdGhpcy5fcmVuZGVyQ2VsbFRlbXBsYXRlRm9ySXRlbShjaGFuZ2UucmVjb3JkLml0ZW0ucm93RGVmLCBjaGFuZ2UuY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgKTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgbWV0YSBjb250ZXh0IG9mIGEgcm93J3MgY29udGV4dCBkYXRhIChpbmRleCwgY291bnQsIGZpcnN0LCBsYXN0LCAuLi4pXG4gICAgdGhpcy5fdXBkYXRlUm93SW5kZXhDb250ZXh0KCk7XG5cbiAgICAvLyBVcGRhdGUgcm93cyB0aGF0IGRpZCBub3QgZ2V0IGFkZGVkL3JlbW92ZWQvbW92ZWQgYnV0IG1heSBoYXZlIGhhZCB0aGVpciBpZGVudGl0eSBjaGFuZ2VkLFxuICAgIC8vIGUuZy4gaWYgdHJhY2tCeSBtYXRjaGVkIGRhdGEgb24gc29tZSBwcm9wZXJ0eSBidXQgdGhlIGFjdHVhbCBkYXRhIHJlZmVyZW5jZSBjaGFuZ2VkLlxuICAgIGNoYW5nZXMuZm9yRWFjaElkZW50aXR5Q2hhbmdlKChyZWNvcmQ6IEl0ZXJhYmxlQ2hhbmdlUmVjb3JkPFJlbmRlclJvdzxUPj4pID0+IHtcbiAgICAgIGNvbnN0IHJvd1ZpZXcgPSA8Um93Vmlld1JlZjxUPj52aWV3Q29udGFpbmVyLmdldChyZWNvcmQuY3VycmVudEluZGV4ISk7XG4gICAgICByb3dWaWV3LmNvbnRleHQuJGltcGxpY2l0ID0gcmVjb3JkLml0ZW0uZGF0YTtcbiAgICB9KTtcblxuICAgIHRoaXMuX3VwZGF0ZU5vRGF0YVJvdygpO1xuXG4gICAgYWZ0ZXJOZXh0UmVuZGVyKFxuICAgICAgKCkgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZVN0aWNreUNvbHVtblN0eWxlcygpO1xuICAgICAgfSxcbiAgICAgIHtpbmplY3RvcjogdGhpcy5faW5qZWN0b3J9LFxuICAgICk7XG5cbiAgICB0aGlzLmNvbnRlbnRDaGFuZ2VkLm5leHQoKTtcbiAgfVxuXG4gIC8qKiBBZGRzIGEgY29sdW1uIGRlZmluaXRpb24gdGhhdCB3YXMgbm90IGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlIGNvbnRlbnQgY2hpbGRyZW4uICovXG4gIGFkZENvbHVtbkRlZihjb2x1bW5EZWY6IENka0NvbHVtbkRlZikge1xuICAgIHRoaXMuX2N1c3RvbUNvbHVtbkRlZnMuYWRkKGNvbHVtbkRlZik7XG4gIH1cblxuICAvKiogUmVtb3ZlcyBhIGNvbHVtbiBkZWZpbml0aW9uIHRoYXQgd2FzIG5vdCBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBjb250ZW50IGNoaWxkcmVuLiAqL1xuICByZW1vdmVDb2x1bW5EZWYoY29sdW1uRGVmOiBDZGtDb2x1bW5EZWYpIHtcbiAgICB0aGlzLl9jdXN0b21Db2x1bW5EZWZzLmRlbGV0ZShjb2x1bW5EZWYpO1xuICB9XG5cbiAgLyoqIEFkZHMgYSByb3cgZGVmaW5pdGlvbiB0aGF0IHdhcyBub3QgaW5jbHVkZWQgYXMgcGFydCBvZiB0aGUgY29udGVudCBjaGlsZHJlbi4gKi9cbiAgYWRkUm93RGVmKHJvd0RlZjogQ2RrUm93RGVmPFQ+KSB7XG4gICAgdGhpcy5fY3VzdG9tUm93RGVmcy5hZGQocm93RGVmKTtcbiAgfVxuXG4gIC8qKiBSZW1vdmVzIGEgcm93IGRlZmluaXRpb24gdGhhdCB3YXMgbm90IGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlIGNvbnRlbnQgY2hpbGRyZW4uICovXG4gIHJlbW92ZVJvd0RlZihyb3dEZWY6IENka1Jvd0RlZjxUPikge1xuICAgIHRoaXMuX2N1c3RvbVJvd0RlZnMuZGVsZXRlKHJvd0RlZik7XG4gIH1cblxuICAvKiogQWRkcyBhIGhlYWRlciByb3cgZGVmaW5pdGlvbiB0aGF0IHdhcyBub3QgaW5jbHVkZWQgYXMgcGFydCBvZiB0aGUgY29udGVudCBjaGlsZHJlbi4gKi9cbiAgYWRkSGVhZGVyUm93RGVmKGhlYWRlclJvd0RlZjogQ2RrSGVhZGVyUm93RGVmKSB7XG4gICAgdGhpcy5fY3VzdG9tSGVhZGVyUm93RGVmcy5hZGQoaGVhZGVyUm93RGVmKTtcbiAgICB0aGlzLl9oZWFkZXJSb3dEZWZDaGFuZ2VkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBSZW1vdmVzIGEgaGVhZGVyIHJvdyBkZWZpbml0aW9uIHRoYXQgd2FzIG5vdCBpbmNsdWRlZCBhcyBwYXJ0IG9mIHRoZSBjb250ZW50IGNoaWxkcmVuLiAqL1xuICByZW1vdmVIZWFkZXJSb3dEZWYoaGVhZGVyUm93RGVmOiBDZGtIZWFkZXJSb3dEZWYpIHtcbiAgICB0aGlzLl9jdXN0b21IZWFkZXJSb3dEZWZzLmRlbGV0ZShoZWFkZXJSb3dEZWYpO1xuICAgIHRoaXMuX2hlYWRlclJvd0RlZkNoYW5nZWQgPSB0cnVlO1xuICB9XG5cbiAgLyoqIEFkZHMgYSBmb290ZXIgcm93IGRlZmluaXRpb24gdGhhdCB3YXMgbm90IGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlIGNvbnRlbnQgY2hpbGRyZW4uICovXG4gIGFkZEZvb3RlclJvd0RlZihmb290ZXJSb3dEZWY6IENka0Zvb3RlclJvd0RlZikge1xuICAgIHRoaXMuX2N1c3RvbUZvb3RlclJvd0RlZnMuYWRkKGZvb3RlclJvd0RlZik7XG4gICAgdGhpcy5fZm9vdGVyUm93RGVmQ2hhbmdlZCA9IHRydWU7XG4gIH1cblxuICAvKiogUmVtb3ZlcyBhIGZvb3RlciByb3cgZGVmaW5pdGlvbiB0aGF0IHdhcyBub3QgaW5jbHVkZWQgYXMgcGFydCBvZiB0aGUgY29udGVudCBjaGlsZHJlbi4gKi9cbiAgcmVtb3ZlRm9vdGVyUm93RGVmKGZvb3RlclJvd0RlZjogQ2RrRm9vdGVyUm93RGVmKSB7XG4gICAgdGhpcy5fY3VzdG9tRm9vdGVyUm93RGVmcy5kZWxldGUoZm9vdGVyUm93RGVmKTtcbiAgICB0aGlzLl9mb290ZXJSb3dEZWZDaGFuZ2VkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBTZXRzIGEgbm8gZGF0YSByb3cgZGVmaW5pdGlvbiB0aGF0IHdhcyBub3QgaW5jbHVkZWQgYXMgYSBwYXJ0IG9mIHRoZSBjb250ZW50IGNoaWxkcmVuLiAqL1xuICBzZXROb0RhdGFSb3cobm9EYXRhUm93OiBDZGtOb0RhdGFSb3cgfCBudWxsKSB7XG4gICAgdGhpcy5fY3VzdG9tTm9EYXRhUm93ID0gbm9EYXRhUm93O1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGhlYWRlciBzdGlja3kgc3R5bGVzLiBGaXJzdCByZXNldHMgYWxsIGFwcGxpZWQgc3R5bGVzIHdpdGggcmVzcGVjdCB0byB0aGUgY2VsbHNcbiAgICogc3RpY2tpbmcgdG8gdGhlIHRvcC4gVGhlbiwgZXZhbHVhdGluZyB3aGljaCBjZWxscyBuZWVkIHRvIGJlIHN0dWNrIHRvIHRoZSB0b3AuIFRoaXMgaXNcbiAgICogYXV0b21hdGljYWxseSBjYWxsZWQgd2hlbiB0aGUgaGVhZGVyIHJvdyBjaGFuZ2VzIGl0cyBkaXNwbGF5ZWQgc2V0IG9mIGNvbHVtbnMsIG9yIGlmIGl0c1xuICAgKiBzdGlja3kgaW5wdXQgY2hhbmdlcy4gTWF5IGJlIGNhbGxlZCBtYW51YWxseSBmb3IgY2FzZXMgd2hlcmUgdGhlIGNlbGwgY29udGVudCBjaGFuZ2VzIG91dHNpZGVcbiAgICogb2YgdGhlc2UgZXZlbnRzLlxuICAgKi9cbiAgdXBkYXRlU3RpY2t5SGVhZGVyUm93U3R5bGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IGhlYWRlclJvd3MgPSB0aGlzLl9nZXRSZW5kZXJlZFJvd3ModGhpcy5faGVhZGVyUm93T3V0bGV0KTtcblxuICAgIC8vIEhpZGUgdGhlIHRoZWFkIGVsZW1lbnQgaWYgdGhlcmUgYXJlIG5vIGhlYWRlciByb3dzLiBUaGlzIGlzIG5lY2Vzc2FyeSB0byBzYXRpc2Z5XG4gICAgLy8gb3ZlcnplYWxvdXMgYTExeSBjaGVja2VycyB0aGF0IGZhaWwgYmVjYXVzZSB0aGUgYHJvd2dyb3VwYCBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW5cbiAgICAvLyByZXF1aXJlZCBjaGlsZCBgcm93YC5cbiAgICBpZiAodGhpcy5faXNOYXRpdmVIdG1sVGFibGUpIHtcbiAgICAgIGNvbnN0IHRoZWFkID0gY2xvc2VzdFRhYmxlU2VjdGlvbih0aGlzLl9oZWFkZXJSb3dPdXRsZXQsICd0aGVhZCcpO1xuICAgICAgaWYgKHRoZWFkKSB7XG4gICAgICAgIHRoZWFkLnN0eWxlLmRpc3BsYXkgPSBoZWFkZXJSb3dzLmxlbmd0aCA/ICcnIDogJ25vbmUnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0aWNreVN0YXRlcyA9IHRoaXMuX2hlYWRlclJvd0RlZnMubWFwKGRlZiA9PiBkZWYuc3RpY2t5KTtcbiAgICB0aGlzLl9zdGlja3lTdHlsZXIuY2xlYXJTdGlja3lQb3NpdGlvbmluZyhoZWFkZXJSb3dzLCBbJ3RvcCddKTtcbiAgICB0aGlzLl9zdGlja3lTdHlsZXIuc3RpY2tSb3dzKGhlYWRlclJvd3MsIHN0aWNreVN0YXRlcywgJ3RvcCcpO1xuXG4gICAgLy8gUmVzZXQgdGhlIGRpcnR5IHN0YXRlIG9mIHRoZSBzdGlja3kgaW5wdXQgY2hhbmdlIHNpbmNlIGl0IGhhcyBiZWVuIHVzZWQuXG4gICAgdGhpcy5faGVhZGVyUm93RGVmcy5mb3JFYWNoKGRlZiA9PiBkZWYucmVzZXRTdGlja3lDaGFuZ2VkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGZvb3RlciBzdGlja3kgc3R5bGVzLiBGaXJzdCByZXNldHMgYWxsIGFwcGxpZWQgc3R5bGVzIHdpdGggcmVzcGVjdCB0byB0aGUgY2VsbHNcbiAgICogc3RpY2tpbmcgdG8gdGhlIGJvdHRvbS4gVGhlbiwgZXZhbHVhdGluZyB3aGljaCBjZWxscyBuZWVkIHRvIGJlIHN0dWNrIHRvIHRoZSBib3R0b20uIFRoaXMgaXNcbiAgICogYXV0b21hdGljYWxseSBjYWxsZWQgd2hlbiB0aGUgZm9vdGVyIHJvdyBjaGFuZ2VzIGl0cyBkaXNwbGF5ZWQgc2V0IG9mIGNvbHVtbnMsIG9yIGlmIGl0c1xuICAgKiBzdGlja3kgaW5wdXQgY2hhbmdlcy4gTWF5IGJlIGNhbGxlZCBtYW51YWxseSBmb3IgY2FzZXMgd2hlcmUgdGhlIGNlbGwgY29udGVudCBjaGFuZ2VzIG91dHNpZGVcbiAgICogb2YgdGhlc2UgZXZlbnRzLlxuICAgKi9cbiAgdXBkYXRlU3RpY2t5Rm9vdGVyUm93U3R5bGVzKCk6IHZvaWQge1xuICAgIGNvbnN0IGZvb3RlclJvd3MgPSB0aGlzLl9nZXRSZW5kZXJlZFJvd3ModGhpcy5fZm9vdGVyUm93T3V0bGV0KTtcblxuICAgIC8vIEhpZGUgdGhlIHRmb290IGVsZW1lbnQgaWYgdGhlcmUgYXJlIG5vIGZvb3RlciByb3dzLiBUaGlzIGlzIG5lY2Vzc2FyeSB0byBzYXRpc2Z5XG4gICAgLy8gb3ZlcnplYWxvdXMgYTExeSBjaGVja2VycyB0aGF0IGZhaWwgYmVjYXVzZSB0aGUgYHJvd2dyb3VwYCBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW5cbiAgICAvLyByZXF1aXJlZCBjaGlsZCBgcm93YC5cbiAgICBpZiAodGhpcy5faXNOYXRpdmVIdG1sVGFibGUpIHtcbiAgICAgIGNvbnN0IHRmb290ID0gY2xvc2VzdFRhYmxlU2VjdGlvbih0aGlzLl9mb290ZXJSb3dPdXRsZXQsICd0Zm9vdCcpO1xuICAgICAgaWYgKHRmb290KSB7XG4gICAgICAgIHRmb290LnN0eWxlLmRpc3BsYXkgPSBmb290ZXJSb3dzLmxlbmd0aCA/ICcnIDogJ25vbmUnO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN0aWNreVN0YXRlcyA9IHRoaXMuX2Zvb3RlclJvd0RlZnMubWFwKGRlZiA9PiBkZWYuc3RpY2t5KTtcbiAgICB0aGlzLl9zdGlja3lTdHlsZXIuY2xlYXJTdGlja3lQb3NpdGlvbmluZyhmb290ZXJSb3dzLCBbJ2JvdHRvbSddKTtcbiAgICB0aGlzLl9zdGlja3lTdHlsZXIuc3RpY2tSb3dzKGZvb3RlclJvd3MsIHN0aWNreVN0YXRlcywgJ2JvdHRvbScpO1xuICAgIHRoaXMuX3N0aWNreVN0eWxlci51cGRhdGVTdGlja3lGb290ZXJDb250YWluZXIodGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LCBzdGlja3lTdGF0ZXMpO1xuXG4gICAgLy8gUmVzZXQgdGhlIGRpcnR5IHN0YXRlIG9mIHRoZSBzdGlja3kgaW5wdXQgY2hhbmdlIHNpbmNlIGl0IGhhcyBiZWVuIHVzZWQuXG4gICAgdGhpcy5fZm9vdGVyUm93RGVmcy5mb3JFYWNoKGRlZiA9PiBkZWYucmVzZXRTdGlja3lDaGFuZ2VkKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVwZGF0ZXMgdGhlIGNvbHVtbiBzdGlja3kgc3R5bGVzLiBGaXJzdCByZXNldHMgYWxsIGFwcGxpZWQgc3R5bGVzIHdpdGggcmVzcGVjdCB0byB0aGUgY2VsbHNcbiAgICogc3RpY2tpbmcgdG8gdGhlIGxlZnQgYW5kIHJpZ2h0LiBUaGVuIHN0aWNreSBzdHlsZXMgYXJlIGFkZGVkIGZvciB0aGUgbGVmdCBhbmQgcmlnaHQgYWNjb3JkaW5nXG4gICAqIHRvIHRoZSBjb2x1bW4gZGVmaW5pdGlvbnMgZm9yIGVhY2ggY2VsbCBpbiBlYWNoIHJvdy4gVGhpcyBpcyBhdXRvbWF0aWNhbGx5IGNhbGxlZCB3aGVuXG4gICAqIHRoZSBkYXRhIHNvdXJjZSBwcm92aWRlcyBhIG5ldyBzZXQgb2YgZGF0YSBvciB3aGVuIGEgY29sdW1uIGRlZmluaXRpb24gY2hhbmdlcyBpdHMgc3RpY2t5XG4gICAqIGlucHV0LiBNYXkgYmUgY2FsbGVkIG1hbnVhbGx5IGZvciBjYXNlcyB3aGVyZSB0aGUgY2VsbCBjb250ZW50IGNoYW5nZXMgb3V0c2lkZSBvZiB0aGVzZSBldmVudHMuXG4gICAqL1xuICB1cGRhdGVTdGlja3lDb2x1bW5TdHlsZXMoKSB7XG4gICAgY29uc3QgaGVhZGVyUm93cyA9IHRoaXMuX2dldFJlbmRlcmVkUm93cyh0aGlzLl9oZWFkZXJSb3dPdXRsZXQpO1xuICAgIGNvbnN0IGRhdGFSb3dzID0gdGhpcy5fZ2V0UmVuZGVyZWRSb3dzKHRoaXMuX3Jvd091dGxldCk7XG4gICAgY29uc3QgZm9vdGVyUm93cyA9IHRoaXMuX2dldFJlbmRlcmVkUm93cyh0aGlzLl9mb290ZXJSb3dPdXRsZXQpO1xuXG4gICAgLy8gRm9yIHRhYmxlcyBub3QgdXNpbmcgYSBmaXhlZCBsYXlvdXQsIHRoZSBjb2x1bW4gd2lkdGhzIG1heSBjaGFuZ2Ugd2hlbiBuZXcgcm93cyBhcmUgcmVuZGVyZWQuXG4gICAgLy8gSW4gYSB0YWJsZSB1c2luZyBhIGZpeGVkIGxheW91dCwgcm93IGNvbnRlbnQgd29uJ3QgYWZmZWN0IGNvbHVtbiB3aWR0aCwgc28gc3RpY2t5IHN0eWxlc1xuICAgIC8vIGRvbid0IG5lZWQgdG8gYmUgY2xlYXJlZCB1bmxlc3MgZWl0aGVyIHRoZSBzdGlja3kgY29sdW1uIGNvbmZpZyBjaGFuZ2VzIG9yIG9uZSBvZiB0aGUgcm93XG4gICAgLy8gZGVmcyBjaGFuZ2UuXG4gICAgaWYgKCh0aGlzLl9pc05hdGl2ZUh0bWxUYWJsZSAmJiAhdGhpcy5fZml4ZWRMYXlvdXQpIHx8IHRoaXMuX3N0aWNreUNvbHVtblN0eWxlc05lZWRSZXNldCkge1xuICAgICAgLy8gQ2xlYXIgdGhlIGxlZnQgYW5kIHJpZ2h0IHBvc2l0aW9uaW5nIGZyb20gYWxsIGNvbHVtbnMgaW4gdGhlIHRhYmxlIGFjcm9zcyBhbGwgcm93cyBzaW5jZVxuICAgICAgLy8gc3RpY2t5IGNvbHVtbnMgc3BhbiBhY3Jvc3MgYWxsIHRhYmxlIHNlY3Rpb25zIChoZWFkZXIsIGRhdGEsIGZvb3RlcilcbiAgICAgIHRoaXMuX3N0aWNreVN0eWxlci5jbGVhclN0aWNreVBvc2l0aW9uaW5nKFxuICAgICAgICBbLi4uaGVhZGVyUm93cywgLi4uZGF0YVJvd3MsIC4uLmZvb3RlclJvd3NdLFxuICAgICAgICBbJ2xlZnQnLCAncmlnaHQnXSxcbiAgICAgICk7XG4gICAgICB0aGlzLl9zdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBVcGRhdGUgdGhlIHN0aWNreSBzdHlsZXMgZm9yIGVhY2ggaGVhZGVyIHJvdyBkZXBlbmRpbmcgb24gdGhlIGRlZidzIHN0aWNreSBzdGF0ZVxuICAgIGhlYWRlclJvd3MuZm9yRWFjaCgoaGVhZGVyUm93LCBpKSA9PiB7XG4gICAgICB0aGlzLl9hZGRTdGlja3lDb2x1bW5TdHlsZXMoW2hlYWRlclJvd10sIHRoaXMuX2hlYWRlclJvd0RlZnNbaV0pO1xuICAgIH0pO1xuXG4gICAgLy8gVXBkYXRlIHRoZSBzdGlja3kgc3R5bGVzIGZvciBlYWNoIGRhdGEgcm93IGRlcGVuZGluZyBvbiBpdHMgZGVmJ3Mgc3RpY2t5IHN0YXRlXG4gICAgdGhpcy5fcm93RGVmcy5mb3JFYWNoKHJvd0RlZiA9PiB7XG4gICAgICAvLyBDb2xsZWN0IGFsbCB0aGUgcm93cyByZW5kZXJlZCB3aXRoIHRoaXMgcm93IGRlZmluaXRpb24uXG4gICAgICBjb25zdCByb3dzOiBIVE1MRWxlbWVudFtdID0gW107XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRhdGFSb3dzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLl9yZW5kZXJSb3dzW2ldLnJvd0RlZiA9PT0gcm93RGVmKSB7XG4gICAgICAgICAgcm93cy5wdXNoKGRhdGFSb3dzW2ldKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9hZGRTdGlja3lDb2x1bW5TdHlsZXMocm93cywgcm93RGVmKTtcbiAgICB9KTtcblxuICAgIC8vIFVwZGF0ZSB0aGUgc3RpY2t5IHN0eWxlcyBmb3IgZWFjaCBmb290ZXIgcm93IGRlcGVuZGluZyBvbiB0aGUgZGVmJ3Mgc3RpY2t5IHN0YXRlXG4gICAgZm9vdGVyUm93cy5mb3JFYWNoKChmb290ZXJSb3csIGkpID0+IHtcbiAgICAgIHRoaXMuX2FkZFN0aWNreUNvbHVtblN0eWxlcyhbZm9vdGVyUm93XSwgdGhpcy5fZm9vdGVyUm93RGVmc1tpXSk7XG4gICAgfSk7XG5cbiAgICAvLyBSZXNldCB0aGUgZGlydHkgc3RhdGUgb2YgdGhlIHN0aWNreSBpbnB1dCBjaGFuZ2Ugc2luY2UgaXQgaGFzIGJlZW4gdXNlZC5cbiAgICBBcnJheS5mcm9tKHRoaXMuX2NvbHVtbkRlZnNCeU5hbWUudmFsdWVzKCkpLmZvckVhY2goZGVmID0+IGRlZi5yZXNldFN0aWNreUNoYW5nZWQoKSk7XG4gIH1cblxuICAvKiogSW52b2tlZCB3aGVuZXZlciBhbiBvdXRsZXQgaXMgY3JlYXRlZCBhbmQgaGFzIGJlZW4gYXNzaWduZWQgdG8gdGhlIHRhYmxlLiAqL1xuICBfb3V0bGV0QXNzaWduZWQoKTogdm9pZCB7XG4gICAgLy8gVHJpZ2dlciB0aGUgZmlyc3QgcmVuZGVyIG9uY2UgYWxsIG91dGxldHMgaGF2ZSBiZWVuIGFzc2lnbmVkLiBXZSBkbyBpdCB0aGlzIHdheSwgYXNcbiAgICAvLyBvcHBvc2VkIHRvIHdhaXRpbmcgZm9yIHRoZSBuZXh0IGBuZ0FmdGVyQ29udGVudENoZWNrZWRgLCBiZWNhdXNlIHdlIGRvbid0IGtub3cgd2hlblxuICAgIC8vIHRoZSBuZXh0IGNoYW5nZSBkZXRlY3Rpb24gd2lsbCBoYXBwZW4uXG4gICAgLy8gQWxzbyB3ZSBjYW4ndCB1c2UgcXVlcmllcyB0byByZXNvbHZlIHRoZSBvdXRsZXRzLCBiZWNhdXNlIHRoZXkncmUgd3JhcHBlZCBpbiBhXG4gICAgLy8gY29uZGl0aW9uYWwsIHNvIHdlIGhhdmUgdG8gcmVseSBvbiB0aGVtIGJlaW5nIGFzc2lnbmVkIHZpYSBESS5cbiAgICBpZiAoXG4gICAgICAhdGhpcy5faGFzQWxsT3V0bGV0cyAmJlxuICAgICAgdGhpcy5fcm93T3V0bGV0ICYmXG4gICAgICB0aGlzLl9oZWFkZXJSb3dPdXRsZXQgJiZcbiAgICAgIHRoaXMuX2Zvb3RlclJvd091dGxldCAmJlxuICAgICAgdGhpcy5fbm9EYXRhUm93T3V0bGV0XG4gICAgKSB7XG4gICAgICB0aGlzLl9oYXNBbGxPdXRsZXRzID0gdHJ1ZTtcblxuICAgICAgLy8gSW4gc29tZSBzZXR1cHMgdGhpcyBtYXkgZmlyZSBiZWZvcmUgYG5nQWZ0ZXJDb250ZW50SW5pdGBcbiAgICAgIC8vIHNvIHdlIG5lZWQgYSBjaGVjayBoZXJlLiBTZWUgIzI4NTM4LlxuICAgICAgaWYgKHRoaXMuX2NhblJlbmRlcigpKSB7XG4gICAgICAgIHRoaXMuX3JlbmRlcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSB0YWJsZSBoYXMgYWxsIHRoZSBpbmZvcm1hdGlvbiB0byBzdGFydCByZW5kZXJpbmcuICovXG4gIHByaXZhdGUgX2NhblJlbmRlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5faGFzQWxsT3V0bGV0cyAmJiB0aGlzLl9oYXNJbml0aWFsaXplZDtcbiAgfVxuXG4gIC8qKiBSZW5kZXJzIHRoZSB0YWJsZSBpZiBpdHMgc3RhdGUgaGFzIGNoYW5nZWQuICovXG4gIHByaXZhdGUgX3JlbmRlcigpOiB2b2lkIHtcbiAgICAvLyBDYWNoZSB0aGUgcm93IGFuZCBjb2x1bW4gZGVmaW5pdGlvbnMgZ2F0aGVyZWQgYnkgQ29udGVudENoaWxkcmVuIGFuZCBwcm9ncmFtbWF0aWMgaW5qZWN0aW9uLlxuICAgIHRoaXMuX2NhY2hlUm93RGVmcygpO1xuICAgIHRoaXMuX2NhY2hlQ29sdW1uRGVmcygpO1xuXG4gICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlIHVzZXIgaGFzIGF0IGxlYXN0IGFkZGVkIGhlYWRlciwgZm9vdGVyLCBvciBkYXRhIHJvdyBkZWYuXG4gICAgaWYgKFxuICAgICAgIXRoaXMuX2hlYWRlclJvd0RlZnMubGVuZ3RoICYmXG4gICAgICAhdGhpcy5fZm9vdGVyUm93RGVmcy5sZW5ndGggJiZcbiAgICAgICF0aGlzLl9yb3dEZWZzLmxlbmd0aCAmJlxuICAgICAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSlcbiAgICApIHtcbiAgICAgIHRocm93IGdldFRhYmxlTWlzc2luZ1Jvd0RlZnNFcnJvcigpO1xuICAgIH1cblxuICAgIC8vIFJlbmRlciB1cGRhdGVzIGlmIHRoZSBsaXN0IG9mIGNvbHVtbnMgaGF2ZSBiZWVuIGNoYW5nZWQgZm9yIHRoZSBoZWFkZXIsIHJvdywgb3IgZm9vdGVyIGRlZnMuXG4gICAgY29uc3QgY29sdW1uc0NoYW5nZWQgPSB0aGlzLl9yZW5kZXJVcGRhdGVkQ29sdW1ucygpO1xuICAgIGNvbnN0IHJvd0RlZnNDaGFuZ2VkID0gY29sdW1uc0NoYW5nZWQgfHwgdGhpcy5faGVhZGVyUm93RGVmQ2hhbmdlZCB8fCB0aGlzLl9mb290ZXJSb3dEZWZDaGFuZ2VkO1xuICAgIC8vIEVuc3VyZSBzdGlja3kgY29sdW1uIHN0eWxlcyBhcmUgcmVzZXQgaWYgc2V0IHRvIGB0cnVlYCBlbHNld2hlcmUuXG4gICAgdGhpcy5fc3RpY2t5Q29sdW1uU3R5bGVzTmVlZFJlc2V0ID0gdGhpcy5fc3RpY2t5Q29sdW1uU3R5bGVzTmVlZFJlc2V0IHx8IHJvd0RlZnNDaGFuZ2VkO1xuICAgIHRoaXMuX2ZvcmNlUmVjYWxjdWxhdGVDZWxsV2lkdGhzID0gcm93RGVmc0NoYW5nZWQ7XG5cbiAgICAvLyBJZiB0aGUgaGVhZGVyIHJvdyBkZWZpbml0aW9uIGhhcyBiZWVuIGNoYW5nZWQsIHRyaWdnZXIgYSByZW5kZXIgdG8gdGhlIGhlYWRlciByb3cuXG4gICAgaWYgKHRoaXMuX2hlYWRlclJvd0RlZkNoYW5nZWQpIHtcbiAgICAgIHRoaXMuX2ZvcmNlUmVuZGVySGVhZGVyUm93cygpO1xuICAgICAgdGhpcy5faGVhZGVyUm93RGVmQ2hhbmdlZCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSBmb290ZXIgcm93IGRlZmluaXRpb24gaGFzIGJlZW4gY2hhbmdlZCwgdHJpZ2dlciBhIHJlbmRlciB0byB0aGUgZm9vdGVyIHJvdy5cbiAgICBpZiAodGhpcy5fZm9vdGVyUm93RGVmQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fZm9yY2VSZW5kZXJGb290ZXJSb3dzKCk7XG4gICAgICB0aGlzLl9mb290ZXJSb3dEZWZDaGFuZ2VkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlcmUgaXMgYSBkYXRhIHNvdXJjZSBhbmQgcm93IGRlZmluaXRpb25zLCBjb25uZWN0IHRvIHRoZSBkYXRhIHNvdXJjZSB1bmxlc3MgYVxuICAgIC8vIGNvbm5lY3Rpb24gaGFzIGFscmVhZHkgYmVlbiBtYWRlLlxuICAgIGlmICh0aGlzLmRhdGFTb3VyY2UgJiYgdGhpcy5fcm93RGVmcy5sZW5ndGggPiAwICYmICF0aGlzLl9yZW5kZXJDaGFuZ2VTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX29ic2VydmVSZW5kZXJDaGFuZ2VzKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9zdGlja3lDb2x1bW5TdHlsZXNOZWVkUmVzZXQpIHtcbiAgICAgIC8vIEluIHRoZSBhYm92ZSBjYXNlLCBfb2JzZXJ2ZVJlbmRlckNoYW5nZXMgd2lsbCByZXN1bHQgaW4gdXBkYXRlU3RpY2t5Q29sdW1uU3R5bGVzIGJlaW5nXG4gICAgICAvLyBjYWxsZWQgd2hlbiBpdCByb3cgZGF0YSBhcnJpdmVzLiBPdGhlcndpc2UsIHdlIG5lZWQgdG8gY2FsbCBpdCBwcm9hY3RpdmVseS5cbiAgICAgIHRoaXMudXBkYXRlU3RpY2t5Q29sdW1uU3R5bGVzKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hlY2tTdGlja3lTdGF0ZXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGxpc3Qgb2YgUmVuZGVyUm93IG9iamVjdHMgdG8gcmVuZGVyIGFjY29yZGluZyB0byB0aGUgY3VycmVudCBsaXN0IG9mIGRhdGEgYW5kIGRlZmluZWRcbiAgICogcm93IGRlZmluaXRpb25zLiBJZiB0aGUgcHJldmlvdXMgbGlzdCBhbHJlYWR5IGNvbnRhaW5lZCBhIHBhcnRpY3VsYXIgcGFpciwgaXQgc2hvdWxkIGJlIHJldXNlZFxuICAgKiBzbyB0aGF0IHRoZSBkaWZmZXIgZXF1YXRlcyB0aGVpciByZWZlcmVuY2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0QWxsUmVuZGVyUm93cygpOiBSZW5kZXJSb3c8VD5bXSB7XG4gICAgY29uc3QgcmVuZGVyUm93czogUmVuZGVyUm93PFQ+W10gPSBbXTtcblxuICAgIC8vIFN0b3JlIHRoZSBjYWNoZSBhbmQgY3JlYXRlIGEgbmV3IG9uZS4gQW55IHJlLXVzZWQgUmVuZGVyUm93IG9iamVjdHMgd2lsbCBiZSBtb3ZlZCBpbnRvIHRoZVxuICAgIC8vIG5ldyBjYWNoZSB3aGlsZSB1bnVzZWQgb25lcyBjYW4gYmUgcGlja2VkIHVwIGJ5IGdhcmJhZ2UgY29sbGVjdGlvbi5cbiAgICBjb25zdCBwcmV2Q2FjaGVkUmVuZGVyUm93cyA9IHRoaXMuX2NhY2hlZFJlbmRlclJvd3NNYXA7XG4gICAgdGhpcy5fY2FjaGVkUmVuZGVyUm93c01hcCA9IG5ldyBNYXAoKTtcblxuICAgIC8vIEZvciBlYWNoIGRhdGEgb2JqZWN0LCBnZXQgdGhlIGxpc3Qgb2Ygcm93cyB0aGF0IHNob3VsZCBiZSByZW5kZXJlZCwgcmVwcmVzZW50ZWQgYnkgdGhlXG4gICAgLy8gcmVzcGVjdGl2ZSBgUmVuZGVyUm93YCBvYmplY3Qgd2hpY2ggaXMgdGhlIHBhaXIgb2YgYGRhdGFgIGFuZCBgQ2RrUm93RGVmYC5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2RhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGxldCBkYXRhID0gdGhpcy5fZGF0YVtpXTtcbiAgICAgIGNvbnN0IHJlbmRlclJvd3NGb3JEYXRhID0gdGhpcy5fZ2V0UmVuZGVyUm93c0ZvckRhdGEoZGF0YSwgaSwgcHJldkNhY2hlZFJlbmRlclJvd3MuZ2V0KGRhdGEpKTtcblxuICAgICAgaWYgKCF0aGlzLl9jYWNoZWRSZW5kZXJSb3dzTWFwLmhhcyhkYXRhKSkge1xuICAgICAgICB0aGlzLl9jYWNoZWRSZW5kZXJSb3dzTWFwLnNldChkYXRhLCBuZXcgV2Vha01hcCgpKTtcbiAgICAgIH1cblxuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCByZW5kZXJSb3dzRm9yRGF0YS5sZW5ndGg7IGorKykge1xuICAgICAgICBsZXQgcmVuZGVyUm93ID0gcmVuZGVyUm93c0ZvckRhdGFbal07XG5cbiAgICAgICAgY29uc3QgY2FjaGUgPSB0aGlzLl9jYWNoZWRSZW5kZXJSb3dzTWFwLmdldChyZW5kZXJSb3cuZGF0YSkhO1xuICAgICAgICBpZiAoY2FjaGUuaGFzKHJlbmRlclJvdy5yb3dEZWYpKSB7XG4gICAgICAgICAgY2FjaGUuZ2V0KHJlbmRlclJvdy5yb3dEZWYpIS5wdXNoKHJlbmRlclJvdyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY2FjaGUuc2V0KHJlbmRlclJvdy5yb3dEZWYsIFtyZW5kZXJSb3ddKTtcbiAgICAgICAgfVxuICAgICAgICByZW5kZXJSb3dzLnB1c2gocmVuZGVyUm93KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVuZGVyUm93cztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgbGlzdCBvZiBgUmVuZGVyUm93PFQ+YCBmb3IgdGhlIHByb3ZpZGVkIGRhdGEgb2JqZWN0IGFuZCBhbnkgYENka1Jvd0RlZmAgb2JqZWN0cyB0aGF0XG4gICAqIHNob3VsZCBiZSByZW5kZXJlZCBmb3IgdGhpcyBkYXRhLiBSZXVzZXMgdGhlIGNhY2hlZCBSZW5kZXJSb3cgb2JqZWN0cyBpZiB0aGV5IG1hdGNoIHRoZSBzYW1lXG4gICAqIGAoVCwgQ2RrUm93RGVmKWAgcGFpci5cbiAgICovXG4gIHByaXZhdGUgX2dldFJlbmRlclJvd3NGb3JEYXRhKFxuICAgIGRhdGE6IFQsXG4gICAgZGF0YUluZGV4OiBudW1iZXIsXG4gICAgY2FjaGU/OiBXZWFrTWFwPENka1Jvd0RlZjxUPiwgUmVuZGVyUm93PFQ+W10+LFxuICApOiBSZW5kZXJSb3c8VD5bXSB7XG4gICAgY29uc3Qgcm93RGVmcyA9IHRoaXMuX2dldFJvd0RlZnMoZGF0YSwgZGF0YUluZGV4KTtcblxuICAgIHJldHVybiByb3dEZWZzLm1hcChyb3dEZWYgPT4ge1xuICAgICAgY29uc3QgY2FjaGVkUmVuZGVyUm93cyA9IGNhY2hlICYmIGNhY2hlLmhhcyhyb3dEZWYpID8gY2FjaGUuZ2V0KHJvd0RlZikhIDogW107XG4gICAgICBpZiAoY2FjaGVkUmVuZGVyUm93cy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgZGF0YVJvdyA9IGNhY2hlZFJlbmRlclJvd3Muc2hpZnQoKSE7XG4gICAgICAgIGRhdGFSb3cuZGF0YUluZGV4ID0gZGF0YUluZGV4O1xuICAgICAgICByZXR1cm4gZGF0YVJvdztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiB7ZGF0YSwgcm93RGVmLCBkYXRhSW5kZXh9O1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFVwZGF0ZSB0aGUgbWFwIGNvbnRhaW5pbmcgdGhlIGNvbnRlbnQncyBjb2x1bW4gZGVmaW5pdGlvbnMuICovXG4gIHByaXZhdGUgX2NhY2hlQ29sdW1uRGVmcygpIHtcbiAgICB0aGlzLl9jb2x1bW5EZWZzQnlOYW1lLmNsZWFyKCk7XG5cbiAgICBjb25zdCBjb2x1bW5EZWZzID0gbWVyZ2VBcnJheUFuZFNldChcbiAgICAgIHRoaXMuX2dldE93bkRlZnModGhpcy5fY29udGVudENvbHVtbkRlZnMpLFxuICAgICAgdGhpcy5fY3VzdG9tQ29sdW1uRGVmcyxcbiAgICApO1xuICAgIGNvbHVtbkRlZnMuZm9yRWFjaChjb2x1bW5EZWYgPT4ge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLl9jb2x1bW5EZWZzQnlOYW1lLmhhcyhjb2x1bW5EZWYubmFtZSkgJiZcbiAgICAgICAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSlcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBnZXRUYWJsZUR1cGxpY2F0ZUNvbHVtbk5hbWVFcnJvcihjb2x1bW5EZWYubmFtZSk7XG4gICAgICB9XG4gICAgICB0aGlzLl9jb2x1bW5EZWZzQnlOYW1lLnNldChjb2x1bW5EZWYubmFtZSwgY29sdW1uRGVmKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKiBVcGRhdGUgdGhlIGxpc3Qgb2YgYWxsIGF2YWlsYWJsZSByb3cgZGVmaW5pdGlvbnMgdGhhdCBjYW4gYmUgdXNlZC4gKi9cbiAgcHJpdmF0ZSBfY2FjaGVSb3dEZWZzKCkge1xuICAgIHRoaXMuX2hlYWRlclJvd0RlZnMgPSBtZXJnZUFycmF5QW5kU2V0KFxuICAgICAgdGhpcy5fZ2V0T3duRGVmcyh0aGlzLl9jb250ZW50SGVhZGVyUm93RGVmcyksXG4gICAgICB0aGlzLl9jdXN0b21IZWFkZXJSb3dEZWZzLFxuICAgICk7XG4gICAgdGhpcy5fZm9vdGVyUm93RGVmcyA9IG1lcmdlQXJyYXlBbmRTZXQoXG4gICAgICB0aGlzLl9nZXRPd25EZWZzKHRoaXMuX2NvbnRlbnRGb290ZXJSb3dEZWZzKSxcbiAgICAgIHRoaXMuX2N1c3RvbUZvb3RlclJvd0RlZnMsXG4gICAgKTtcbiAgICB0aGlzLl9yb3dEZWZzID0gbWVyZ2VBcnJheUFuZFNldCh0aGlzLl9nZXRPd25EZWZzKHRoaXMuX2NvbnRlbnRSb3dEZWZzKSwgdGhpcy5fY3VzdG9tUm93RGVmcyk7XG5cbiAgICAvLyBBZnRlciBhbGwgcm93IGRlZmluaXRpb25zIGFyZSBkZXRlcm1pbmVkLCBmaW5kIHRoZSByb3cgZGVmaW5pdGlvbiB0byBiZSBjb25zaWRlcmVkIGRlZmF1bHQuXG4gICAgY29uc3QgZGVmYXVsdFJvd0RlZnMgPSB0aGlzLl9yb3dEZWZzLmZpbHRlcihkZWYgPT4gIWRlZi53aGVuKTtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5tdWx0aVRlbXBsYXRlRGF0YVJvd3MgJiZcbiAgICAgIGRlZmF1bHRSb3dEZWZzLmxlbmd0aCA+IDEgJiZcbiAgICAgICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpXG4gICAgKSB7XG4gICAgICB0aHJvdyBnZXRUYWJsZU11bHRpcGxlRGVmYXVsdFJvd0RlZnNFcnJvcigpO1xuICAgIH1cbiAgICB0aGlzLl9kZWZhdWx0Um93RGVmID0gZGVmYXVsdFJvd0RlZnNbMF07XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2sgaWYgdGhlIGhlYWRlciwgZGF0YSwgb3IgZm9vdGVyIHJvd3MgaGF2ZSBjaGFuZ2VkIHdoYXQgY29sdW1ucyB0aGV5IHdhbnQgdG8gZGlzcGxheSBvclxuICAgKiB3aGV0aGVyIHRoZSBzdGlja3kgc3RhdGVzIGhhdmUgY2hhbmdlZCBmb3IgdGhlIGhlYWRlciBvciBmb290ZXIuIElmIHRoZXJlIGlzIGEgZGlmZiwgdGhlblxuICAgKiByZS1yZW5kZXIgdGhhdCBzZWN0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfcmVuZGVyVXBkYXRlZENvbHVtbnMoKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY29sdW1uc0RpZmZSZWR1Y2VyID0gKGFjYzogYm9vbGVhbiwgZGVmOiBCYXNlUm93RGVmKSA9PiBhY2MgfHwgISFkZWYuZ2V0Q29sdW1uc0RpZmYoKTtcblxuICAgIC8vIEZvcmNlIHJlLXJlbmRlciBkYXRhIHJvd3MgaWYgdGhlIGxpc3Qgb2YgY29sdW1uIGRlZmluaXRpb25zIGhhdmUgY2hhbmdlZC5cbiAgICBjb25zdCBkYXRhQ29sdW1uc0NoYW5nZWQgPSB0aGlzLl9yb3dEZWZzLnJlZHVjZShjb2x1bW5zRGlmZlJlZHVjZXIsIGZhbHNlKTtcbiAgICBpZiAoZGF0YUNvbHVtbnNDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9mb3JjZVJlbmRlckRhdGFSb3dzKCk7XG4gICAgfVxuXG4gICAgLy8gRm9yY2UgcmUtcmVuZGVyIGhlYWRlci9mb290ZXIgcm93cyBpZiB0aGUgbGlzdCBvZiBjb2x1bW4gZGVmaW5pdGlvbnMgaGF2ZSBjaGFuZ2VkLlxuICAgIGNvbnN0IGhlYWRlckNvbHVtbnNDaGFuZ2VkID0gdGhpcy5faGVhZGVyUm93RGVmcy5yZWR1Y2UoY29sdW1uc0RpZmZSZWR1Y2VyLCBmYWxzZSk7XG4gICAgaWYgKGhlYWRlckNvbHVtbnNDaGFuZ2VkKSB7XG4gICAgICB0aGlzLl9mb3JjZVJlbmRlckhlYWRlclJvd3MoKTtcbiAgICB9XG5cbiAgICBjb25zdCBmb290ZXJDb2x1bW5zQ2hhbmdlZCA9IHRoaXMuX2Zvb3RlclJvd0RlZnMucmVkdWNlKGNvbHVtbnNEaWZmUmVkdWNlciwgZmFsc2UpO1xuICAgIGlmIChmb290ZXJDb2x1bW5zQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fZm9yY2VSZW5kZXJGb290ZXJSb3dzKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGRhdGFDb2x1bW5zQ2hhbmdlZCB8fCBoZWFkZXJDb2x1bW5zQ2hhbmdlZCB8fCBmb290ZXJDb2x1bW5zQ2hhbmdlZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0Y2ggdG8gdGhlIHByb3ZpZGVkIGRhdGEgc291cmNlIGJ5IHJlc2V0dGluZyB0aGUgZGF0YSBhbmQgdW5zdWJzY3JpYmluZyBmcm9tIHRoZSBjdXJyZW50XG4gICAqIHJlbmRlciBjaGFuZ2Ugc3Vic2NyaXB0aW9uIGlmIG9uZSBleGlzdHMuIElmIHRoZSBkYXRhIHNvdXJjZSBpcyBudWxsLCBpbnRlcnByZXQgdGhpcyBieVxuICAgKiBjbGVhcmluZyB0aGUgcm93IG91dGxldC4gT3RoZXJ3aXNlIHN0YXJ0IGxpc3RlbmluZyBmb3IgbmV3IGRhdGEuXG4gICAqL1xuICBwcml2YXRlIF9zd2l0Y2hEYXRhU291cmNlKGRhdGFTb3VyY2U6IENka1RhYmxlRGF0YVNvdXJjZUlucHV0PFQ+KSB7XG4gICAgdGhpcy5fZGF0YSA9IFtdO1xuXG4gICAgaWYgKGlzRGF0YVNvdXJjZSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICB0aGlzLmRhdGFTb3VyY2UuZGlzY29ubmVjdCh0aGlzKTtcbiAgICB9XG5cbiAgICAvLyBTdG9wIGxpc3RlbmluZyBmb3IgZGF0YSBmcm9tIHRoZSBwcmV2aW91cyBkYXRhIHNvdXJjZS5cbiAgICBpZiAodGhpcy5fcmVuZGVyQ2hhbmdlU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLl9yZW5kZXJDaGFuZ2VTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMuX3JlbmRlckNoYW5nZVN1YnNjcmlwdGlvbiA9IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKCFkYXRhU291cmNlKSB7XG4gICAgICBpZiAodGhpcy5fZGF0YURpZmZlcikge1xuICAgICAgICB0aGlzLl9kYXRhRGlmZmVyLmRpZmYoW10pO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMuX3Jvd091dGxldCkge1xuICAgICAgICB0aGlzLl9yb3dPdXRsZXQudmlld0NvbnRhaW5lci5jbGVhcigpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2RhdGFTb3VyY2UgPSBkYXRhU291cmNlO1xuICB9XG5cbiAgLyoqIFNldCB1cCBhIHN1YnNjcmlwdGlvbiBmb3IgdGhlIGRhdGEgcHJvdmlkZWQgYnkgdGhlIGRhdGEgc291cmNlLiAqL1xuICBwcml2YXRlIF9vYnNlcnZlUmVuZGVyQ2hhbmdlcygpIHtcbiAgICAvLyBJZiBubyBkYXRhIHNvdXJjZSBoYXMgYmVlbiBzZXQsIHRoZXJlIGlzIG5vdGhpbmcgdG8gb2JzZXJ2ZSBmb3IgY2hhbmdlcy5cbiAgICBpZiAoIXRoaXMuZGF0YVNvdXJjZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBkYXRhU3RyZWFtOiBPYnNlcnZhYmxlPHJlYWRvbmx5IFRbXT4gfCB1bmRlZmluZWQ7XG5cbiAgICBpZiAoaXNEYXRhU291cmNlKHRoaXMuZGF0YVNvdXJjZSkpIHtcbiAgICAgIGRhdGFTdHJlYW0gPSB0aGlzLmRhdGFTb3VyY2UuY29ubmVjdCh0aGlzKTtcbiAgICB9IGVsc2UgaWYgKGlzT2JzZXJ2YWJsZSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICBkYXRhU3RyZWFtID0gdGhpcy5kYXRhU291cmNlO1xuICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmRhdGFTb3VyY2UpKSB7XG4gICAgICBkYXRhU3RyZWFtID0gb2JzZXJ2YWJsZU9mKHRoaXMuZGF0YVNvdXJjZSk7XG4gICAgfVxuXG4gICAgaWYgKGRhdGFTdHJlYW0gPT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgdGhyb3cgZ2V0VGFibGVVbmtub3duRGF0YVNvdXJjZUVycm9yKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fcmVuZGVyQ2hhbmdlU3Vic2NyaXB0aW9uID0gZGF0YVN0cmVhbSFcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICAgICAgLnN1YnNjcmliZShkYXRhID0+IHtcbiAgICAgICAgdGhpcy5fZGF0YSA9IGRhdGEgfHwgW107XG4gICAgICAgIHRoaXMucmVuZGVyUm93cygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIGFueSBleGlzdGluZyBjb250ZW50IGluIHRoZSBoZWFkZXIgcm93IG91dGxldCBhbmQgY3JlYXRlcyBhIG5ldyBlbWJlZGRlZCB2aWV3XG4gICAqIGluIHRoZSBvdXRsZXQgdXNpbmcgdGhlIGhlYWRlciByb3cgZGVmaW5pdGlvbi5cbiAgICovXG4gIHByaXZhdGUgX2ZvcmNlUmVuZGVySGVhZGVyUm93cygpIHtcbiAgICAvLyBDbGVhciB0aGUgaGVhZGVyIHJvdyBvdXRsZXQgaWYgYW55IGNvbnRlbnQgZXhpc3RzLlxuICAgIGlmICh0aGlzLl9oZWFkZXJSb3dPdXRsZXQudmlld0NvbnRhaW5lci5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9oZWFkZXJSb3dPdXRsZXQudmlld0NvbnRhaW5lci5jbGVhcigpO1xuICAgIH1cblxuICAgIHRoaXMuX2hlYWRlclJvd0RlZnMuZm9yRWFjaCgoZGVmLCBpKSA9PiB0aGlzLl9yZW5kZXJSb3codGhpcy5faGVhZGVyUm93T3V0bGV0LCBkZWYsIGkpKTtcbiAgICB0aGlzLnVwZGF0ZVN0aWNreUhlYWRlclJvd1N0eWxlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBhbnkgZXhpc3RpbmcgY29udGVudCBpbiB0aGUgZm9vdGVyIHJvdyBvdXRsZXQgYW5kIGNyZWF0ZXMgYSBuZXcgZW1iZWRkZWQgdmlld1xuICAgKiBpbiB0aGUgb3V0bGV0IHVzaW5nIHRoZSBmb290ZXIgcm93IGRlZmluaXRpb24uXG4gICAqL1xuICBwcml2YXRlIF9mb3JjZVJlbmRlckZvb3RlclJvd3MoKSB7XG4gICAgLy8gQ2xlYXIgdGhlIGZvb3RlciByb3cgb3V0bGV0IGlmIGFueSBjb250ZW50IGV4aXN0cy5cbiAgICBpZiAodGhpcy5fZm9vdGVyUm93T3V0bGV0LnZpZXdDb250YWluZXIubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5fZm9vdGVyUm93T3V0bGV0LnZpZXdDb250YWluZXIuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9mb290ZXJSb3dEZWZzLmZvckVhY2goKGRlZiwgaSkgPT4gdGhpcy5fcmVuZGVyUm93KHRoaXMuX2Zvb3RlclJvd091dGxldCwgZGVmLCBpKSk7XG4gICAgdGhpcy51cGRhdGVTdGlja3lGb290ZXJSb3dTdHlsZXMoKTtcbiAgfVxuXG4gIC8qKiBBZGRzIHRoZSBzdGlja3kgY29sdW1uIHN0eWxlcyBmb3IgdGhlIHJvd3MgYWNjb3JkaW5nIHRvIHRoZSBjb2x1bW5zJyBzdGljayBzdGF0ZXMuICovXG4gIHByaXZhdGUgX2FkZFN0aWNreUNvbHVtblN0eWxlcyhyb3dzOiBIVE1MRWxlbWVudFtdLCByb3dEZWY6IEJhc2VSb3dEZWYpIHtcbiAgICBjb25zdCBjb2x1bW5EZWZzID0gQXJyYXkuZnJvbShyb3dEZWYuY29sdW1ucyB8fCBbXSkubWFwKGNvbHVtbk5hbWUgPT4ge1xuICAgICAgY29uc3QgY29sdW1uRGVmID0gdGhpcy5fY29sdW1uRGVmc0J5TmFtZS5nZXQoY29sdW1uTmFtZSk7XG4gICAgICBpZiAoIWNvbHVtbkRlZiAmJiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgICB0aHJvdyBnZXRUYWJsZVVua25vd25Db2x1bW5FcnJvcihjb2x1bW5OYW1lKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjb2x1bW5EZWYhO1xuICAgIH0pO1xuICAgIGNvbnN0IHN0aWNreVN0YXJ0U3RhdGVzID0gY29sdW1uRGVmcy5tYXAoY29sdW1uRGVmID0+IGNvbHVtbkRlZi5zdGlja3kpO1xuICAgIGNvbnN0IHN0aWNreUVuZFN0YXRlcyA9IGNvbHVtbkRlZnMubWFwKGNvbHVtbkRlZiA9PiBjb2x1bW5EZWYuc3RpY2t5RW5kKTtcbiAgICB0aGlzLl9zdGlja3lTdHlsZXIudXBkYXRlU3RpY2t5Q29sdW1ucyhcbiAgICAgIHJvd3MsXG4gICAgICBzdGlja3lTdGFydFN0YXRlcyxcbiAgICAgIHN0aWNreUVuZFN0YXRlcyxcbiAgICAgICF0aGlzLl9maXhlZExheW91dCB8fCB0aGlzLl9mb3JjZVJlY2FsY3VsYXRlQ2VsbFdpZHRocyxcbiAgICApO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIGxpc3Qgb2Ygcm93cyB0aGF0IGhhdmUgYmVlbiByZW5kZXJlZCBpbiB0aGUgcm93IG91dGxldC4gKi9cbiAgX2dldFJlbmRlcmVkUm93cyhyb3dPdXRsZXQ6IFJvd091dGxldCk6IEhUTUxFbGVtZW50W10ge1xuICAgIGNvbnN0IHJlbmRlcmVkUm93czogSFRNTEVsZW1lbnRbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dPdXRsZXQudmlld0NvbnRhaW5lci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgdmlld1JlZiA9IHJvd091dGxldC52aWV3Q29udGFpbmVyLmdldChpKSEgYXMgRW1iZWRkZWRWaWV3UmVmPGFueT47XG4gICAgICByZW5kZXJlZFJvd3MucHVzaCh2aWV3UmVmLnJvb3ROb2Rlc1swXSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlbmRlcmVkUm93cztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG1hdGNoaW5nIHJvdyBkZWZpbml0aW9ucyB0aGF0IHNob3VsZCBiZSB1c2VkIGZvciB0aGlzIHJvdyBkYXRhLiBJZiB0aGVyZSBpcyBvbmx5XG4gICAqIG9uZSByb3cgZGVmaW5pdGlvbiwgaXQgaXMgcmV0dXJuZWQuIE90aGVyd2lzZSwgZmluZCB0aGUgcm93IGRlZmluaXRpb25zIHRoYXQgaGFzIGEgd2hlblxuICAgKiBwcmVkaWNhdGUgdGhhdCByZXR1cm5zIHRydWUgd2l0aCB0aGUgZGF0YS4gSWYgbm9uZSByZXR1cm4gdHJ1ZSwgcmV0dXJuIHRoZSBkZWZhdWx0IHJvd1xuICAgKiBkZWZpbml0aW9uLlxuICAgKi9cbiAgX2dldFJvd0RlZnMoZGF0YTogVCwgZGF0YUluZGV4OiBudW1iZXIpOiBDZGtSb3dEZWY8VD5bXSB7XG4gICAgaWYgKHRoaXMuX3Jvd0RlZnMubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiBbdGhpcy5fcm93RGVmc1swXV07XG4gICAgfVxuXG4gICAgbGV0IHJvd0RlZnM6IENka1Jvd0RlZjxUPltdID0gW107XG4gICAgaWYgKHRoaXMubXVsdGlUZW1wbGF0ZURhdGFSb3dzKSB7XG4gICAgICByb3dEZWZzID0gdGhpcy5fcm93RGVmcy5maWx0ZXIoZGVmID0+ICFkZWYud2hlbiB8fCBkZWYud2hlbihkYXRhSW5kZXgsIGRhdGEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJvd0RlZiA9XG4gICAgICAgIHRoaXMuX3Jvd0RlZnMuZmluZChkZWYgPT4gZGVmLndoZW4gJiYgZGVmLndoZW4oZGF0YUluZGV4LCBkYXRhKSkgfHwgdGhpcy5fZGVmYXVsdFJvd0RlZjtcbiAgICAgIGlmIChyb3dEZWYpIHtcbiAgICAgICAgcm93RGVmcy5wdXNoKHJvd0RlZik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFyb3dEZWZzLmxlbmd0aCAmJiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgdGhyb3cgZ2V0VGFibGVNaXNzaW5nTWF0Y2hpbmdSb3dEZWZFcnJvcihkYXRhKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93RGVmcztcbiAgfVxuXG4gIHByaXZhdGUgX2dldEVtYmVkZGVkVmlld0FyZ3MoXG4gICAgcmVuZGVyUm93OiBSZW5kZXJSb3c8VD4sXG4gICAgaW5kZXg6IG51bWJlcixcbiAgKTogX1ZpZXdSZXBlYXRlckl0ZW1JbnNlcnRBcmdzPFJvd0NvbnRleHQ8VD4+IHtcbiAgICBjb25zdCByb3dEZWYgPSByZW5kZXJSb3cucm93RGVmO1xuICAgIGNvbnN0IGNvbnRleHQ6IFJvd0NvbnRleHQ8VD4gPSB7JGltcGxpY2l0OiByZW5kZXJSb3cuZGF0YX07XG4gICAgcmV0dXJuIHtcbiAgICAgIHRlbXBsYXRlUmVmOiByb3dEZWYudGVtcGxhdGUsXG4gICAgICBjb250ZXh0LFxuICAgICAgaW5kZXgsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IHJvdyB0ZW1wbGF0ZSBpbiB0aGUgb3V0bGV0IGFuZCBmaWxscyBpdCB3aXRoIHRoZSBzZXQgb2YgY2VsbCB0ZW1wbGF0ZXMuXG4gICAqIE9wdGlvbmFsbHkgdGFrZXMgYSBjb250ZXh0IHRvIHByb3ZpZGUgdG8gdGhlIHJvdyBhbmQgY2VsbHMsIGFzIHdlbGwgYXMgYW4gb3B0aW9uYWwgaW5kZXhcbiAgICogb2Ygd2hlcmUgdG8gcGxhY2UgdGhlIG5ldyByb3cgdGVtcGxhdGUgaW4gdGhlIG91dGxldC5cbiAgICovXG4gIHByaXZhdGUgX3JlbmRlclJvdyhcbiAgICBvdXRsZXQ6IFJvd091dGxldCxcbiAgICByb3dEZWY6IEJhc2VSb3dEZWYsXG4gICAgaW5kZXg6IG51bWJlcixcbiAgICBjb250ZXh0OiBSb3dDb250ZXh0PFQ+ID0ge30sXG4gICk6IEVtYmVkZGVkVmlld1JlZjxSb3dDb250ZXh0PFQ+PiB7XG4gICAgLy8gVE9ETyhhbmRyZXdzZWd1aW4pOiBlbmZvcmNlIHRoYXQgb25lIG91dGxldCB3YXMgaW5zdGFudGlhdGVkIGZyb20gY3JlYXRlRW1iZWRkZWRWaWV3XG4gICAgY29uc3QgdmlldyA9IG91dGxldC52aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyhyb3dEZWYudGVtcGxhdGUsIGNvbnRleHQsIGluZGV4KTtcbiAgICB0aGlzLl9yZW5kZXJDZWxsVGVtcGxhdGVGb3JJdGVtKHJvd0RlZiwgY29udGV4dCk7XG4gICAgcmV0dXJuIHZpZXc7XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJDZWxsVGVtcGxhdGVGb3JJdGVtKHJvd0RlZjogQmFzZVJvd0RlZiwgY29udGV4dDogUm93Q29udGV4dDxUPikge1xuICAgIGZvciAobGV0IGNlbGxUZW1wbGF0ZSBvZiB0aGlzLl9nZXRDZWxsVGVtcGxhdGVzKHJvd0RlZikpIHtcbiAgICAgIGlmIChDZGtDZWxsT3V0bGV0Lm1vc3RSZWNlbnRDZWxsT3V0bGV0KSB7XG4gICAgICAgIENka0NlbGxPdXRsZXQubW9zdFJlY2VudENlbGxPdXRsZXQuX3ZpZXdDb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KGNlbGxUZW1wbGF0ZSwgY29udGV4dCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgaW5kZXgtcmVsYXRlZCBjb250ZXh0IGZvciBlYWNoIHJvdyB0byByZWZsZWN0IGFueSBjaGFuZ2VzIGluIHRoZSBpbmRleCBvZiB0aGUgcm93cyxcbiAgICogZS5nLiBmaXJzdC9sYXN0L2V2ZW4vb2RkLlxuICAgKi9cbiAgcHJpdmF0ZSBfdXBkYXRlUm93SW5kZXhDb250ZXh0KCkge1xuICAgIGNvbnN0IHZpZXdDb250YWluZXIgPSB0aGlzLl9yb3dPdXRsZXQudmlld0NvbnRhaW5lcjtcbiAgICBmb3IgKGxldCByZW5kZXJJbmRleCA9IDAsIGNvdW50ID0gdmlld0NvbnRhaW5lci5sZW5ndGg7IHJlbmRlckluZGV4IDwgY291bnQ7IHJlbmRlckluZGV4KyspIHtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSB2aWV3Q29udGFpbmVyLmdldChyZW5kZXJJbmRleCkgYXMgUm93Vmlld1JlZjxUPjtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB2aWV3UmVmLmNvbnRleHQgYXMgUm93Q29udGV4dDxUPjtcbiAgICAgIGNvbnRleHQuY291bnQgPSBjb3VudDtcbiAgICAgIGNvbnRleHQuZmlyc3QgPSByZW5kZXJJbmRleCA9PT0gMDtcbiAgICAgIGNvbnRleHQubGFzdCA9IHJlbmRlckluZGV4ID09PSBjb3VudCAtIDE7XG4gICAgICBjb250ZXh0LmV2ZW4gPSByZW5kZXJJbmRleCAlIDIgPT09IDA7XG4gICAgICBjb250ZXh0Lm9kZCA9ICFjb250ZXh0LmV2ZW47XG5cbiAgICAgIGlmICh0aGlzLm11bHRpVGVtcGxhdGVEYXRhUm93cykge1xuICAgICAgICBjb250ZXh0LmRhdGFJbmRleCA9IHRoaXMuX3JlbmRlclJvd3NbcmVuZGVySW5kZXhdLmRhdGFJbmRleDtcbiAgICAgICAgY29udGV4dC5yZW5kZXJJbmRleCA9IHJlbmRlckluZGV4O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29udGV4dC5pbmRleCA9IHRoaXMuX3JlbmRlclJvd3NbcmVuZGVySW5kZXhdLmRhdGFJbmRleDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogR2V0cyB0aGUgY29sdW1uIGRlZmluaXRpb25zIGZvciB0aGUgcHJvdmlkZWQgcm93IGRlZi4gKi9cbiAgcHJpdmF0ZSBfZ2V0Q2VsbFRlbXBsYXRlcyhyb3dEZWY6IEJhc2VSb3dEZWYpOiBUZW1wbGF0ZVJlZjxhbnk+W10ge1xuICAgIGlmICghcm93RGVmIHx8ICFyb3dEZWYuY29sdW1ucykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICByZXR1cm4gQXJyYXkuZnJvbShyb3dEZWYuY29sdW1ucywgY29sdW1uSWQgPT4ge1xuICAgICAgY29uc3QgY29sdW1uID0gdGhpcy5fY29sdW1uRGVmc0J5TmFtZS5nZXQoY29sdW1uSWQpO1xuXG4gICAgICBpZiAoIWNvbHVtbiAmJiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgICB0aHJvdyBnZXRUYWJsZVVua25vd25Db2x1bW5FcnJvcihjb2x1bW5JZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByb3dEZWYuZXh0cmFjdENlbGxUZW1wbGF0ZShjb2x1bW4hKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JjZXMgYSByZS1yZW5kZXIgb2YgdGhlIGRhdGEgcm93cy4gU2hvdWxkIGJlIGNhbGxlZCBpbiBjYXNlcyB3aGVyZSB0aGVyZSBoYXMgYmVlbiBhbiBpbnB1dFxuICAgKiBjaGFuZ2UgdGhhdCBhZmZlY3RzIHRoZSBldmFsdWF0aW9uIG9mIHdoaWNoIHJvd3Mgc2hvdWxkIGJlIHJlbmRlcmVkLCBlLmcuIHRvZ2dsaW5nXG4gICAqIGBtdWx0aVRlbXBsYXRlRGF0YVJvd3NgIG9yIGFkZGluZy9yZW1vdmluZyByb3cgZGVmaW5pdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIF9mb3JjZVJlbmRlckRhdGFSb3dzKCkge1xuICAgIHRoaXMuX2RhdGFEaWZmZXIuZGlmZihbXSk7XG4gICAgdGhpcy5fcm93T3V0bGV0LnZpZXdDb250YWluZXIuY2xlYXIoKTtcbiAgICB0aGlzLnJlbmRlclJvd3MoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlcmUgaGFzIGJlZW4gYSBjaGFuZ2UgaW4gc3RpY2t5IHN0YXRlcyBzaW5jZSBsYXN0IGNoZWNrIGFuZCBhcHBsaWVzIHRoZSBjb3JyZWN0XG4gICAqIHN0aWNreSBzdHlsZXMuIFNpbmNlIGNoZWNraW5nIHJlc2V0cyB0aGUgXCJkaXJ0eVwiIHN0YXRlLCB0aGlzIHNob3VsZCBvbmx5IGJlIHBlcmZvcm1lZCBvbmNlXG4gICAqIGR1cmluZyBhIGNoYW5nZSBkZXRlY3Rpb24gYW5kIGFmdGVyIHRoZSBpbnB1dHMgYXJlIHNldHRsZWQgKGFmdGVyIGNvbnRlbnQgY2hlY2spLlxuICAgKi9cbiAgcHJpdmF0ZSBfY2hlY2tTdGlja3lTdGF0ZXMoKSB7XG4gICAgY29uc3Qgc3RpY2t5Q2hlY2tSZWR1Y2VyID0gKFxuICAgICAgYWNjOiBib29sZWFuLFxuICAgICAgZDogQ2RrSGVhZGVyUm93RGVmIHwgQ2RrRm9vdGVyUm93RGVmIHwgQ2RrQ29sdW1uRGVmLFxuICAgICkgPT4ge1xuICAgICAgcmV0dXJuIGFjYyB8fCBkLmhhc1N0aWNreUNoYW5nZWQoKTtcbiAgICB9O1xuXG4gICAgLy8gTm90ZSB0aGF0IHRoZSBjaGVjayBuZWVkcyB0byBvY2N1ciBmb3IgZXZlcnkgZGVmaW5pdGlvbiBzaW5jZSBpdCBub3RpZmllcyB0aGUgZGVmaW5pdGlvblxuICAgIC8vIHRoYXQgaXQgY2FuIHJlc2V0IGl0cyBkaXJ0eSBzdGF0ZS4gVXNpbmcgYW5vdGhlciBvcGVyYXRvciBsaWtlIGBzb21lYCBtYXkgc2hvcnQtY2lyY3VpdFxuICAgIC8vIHJlbWFpbmluZyBkZWZpbml0aW9ucyBhbmQgbGVhdmUgdGhlbSBpbiBhbiB1bmNoZWNrZWQgc3RhdGUuXG5cbiAgICBpZiAodGhpcy5faGVhZGVyUm93RGVmcy5yZWR1Y2Uoc3RpY2t5Q2hlY2tSZWR1Y2VyLCBmYWxzZSkpIHtcbiAgICAgIHRoaXMudXBkYXRlU3RpY2t5SGVhZGVyUm93U3R5bGVzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2Zvb3RlclJvd0RlZnMucmVkdWNlKHN0aWNreUNoZWNrUmVkdWNlciwgZmFsc2UpKSB7XG4gICAgICB0aGlzLnVwZGF0ZVN0aWNreUZvb3RlclJvd1N0eWxlcygpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5mcm9tKHRoaXMuX2NvbHVtbkRlZnNCeU5hbWUudmFsdWVzKCkpLnJlZHVjZShzdGlja3lDaGVja1JlZHVjZXIsIGZhbHNlKSkge1xuICAgICAgdGhpcy5fc3RpY2t5Q29sdW1uU3R5bGVzTmVlZFJlc2V0ID0gdHJ1ZTtcbiAgICAgIHRoaXMudXBkYXRlU3RpY2t5Q29sdW1uU3R5bGVzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIHN0aWNreSBzdHlsZXIgdGhhdCB3aWxsIGJlIHVzZWQgZm9yIHN0aWNreSByb3dzIGFuZCBjb2x1bW5zLiBMaXN0ZW5zXG4gICAqIGZvciBkaXJlY3Rpb25hbGl0eSBjaGFuZ2VzIGFuZCBwcm92aWRlcyB0aGUgbGF0ZXN0IGRpcmVjdGlvbiB0byB0aGUgc3R5bGVyLiBSZS1hcHBsaWVzIGNvbHVtblxuICAgKiBzdGlja2luZXNzIHdoZW4gZGlyZWN0aW9uYWxpdHkgY2hhbmdlcy5cbiAgICovXG4gIHByaXZhdGUgX3NldHVwU3RpY2t5U3R5bGVyKCkge1xuICAgIGNvbnN0IGRpcmVjdGlvbjogRGlyZWN0aW9uID0gdGhpcy5fZGlyID8gdGhpcy5fZGlyLnZhbHVlIDogJ2x0cic7XG4gICAgdGhpcy5fc3RpY2t5U3R5bGVyID0gbmV3IFN0aWNreVN0eWxlcihcbiAgICAgIHRoaXMuX2lzTmF0aXZlSHRtbFRhYmxlLFxuICAgICAgdGhpcy5zdGlja3lDc3NDbGFzcyxcbiAgICAgIGRpcmVjdGlvbixcbiAgICAgIHRoaXMuX2NvYWxlc2NlZFN0eWxlU2NoZWR1bGVyLFxuICAgICAgdGhpcy5fcGxhdGZvcm0uaXNCcm93c2VyLFxuICAgICAgdGhpcy5uZWVkc1Bvc2l0aW9uU3RpY2t5T25FbGVtZW50LFxuICAgICAgdGhpcy5fc3RpY2t5UG9zaXRpb25pbmdMaXN0ZW5lcixcbiAgICApO1xuICAgICh0aGlzLl9kaXIgPyB0aGlzLl9kaXIuY2hhbmdlIDogb2JzZXJ2YWJsZU9mPERpcmVjdGlvbj4oKSlcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLl9vbkRlc3Ryb3kpKVxuICAgICAgLnN1YnNjcmliZSh2YWx1ZSA9PiB7XG4gICAgICAgIHRoaXMuX3N0aWNreVN0eWxlci5kaXJlY3Rpb24gPSB2YWx1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVTdGlja3lDb2x1bW5TdHlsZXMoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqIEZpbHRlcnMgZGVmaW5pdGlvbnMgdGhhdCBiZWxvbmcgdG8gdGhpcyB0YWJsZSBmcm9tIGEgUXVlcnlMaXN0LiAqL1xuICBwcml2YXRlIF9nZXRPd25EZWZzPEkgZXh0ZW5kcyB7X3RhYmxlPzogYW55fT4oaXRlbXM6IFF1ZXJ5TGlzdDxJPik6IElbXSB7XG4gICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihpdGVtID0+ICFpdGVtLl90YWJsZSB8fCBpdGVtLl90YWJsZSA9PT0gdGhpcyk7XG4gIH1cblxuICAvKiogQ3JlYXRlcyBvciByZW1vdmVzIHRoZSBubyBkYXRhIHJvdywgZGVwZW5kaW5nIG9uIHdoZXRoZXIgYW55IGRhdGEgaXMgYmVpbmcgc2hvd24uICovXG4gIHByaXZhdGUgX3VwZGF0ZU5vRGF0YVJvdygpIHtcbiAgICBjb25zdCBub0RhdGFSb3cgPSB0aGlzLl9jdXN0b21Ob0RhdGFSb3cgfHwgdGhpcy5fbm9EYXRhUm93O1xuXG4gICAgaWYgKCFub0RhdGFSb3cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzaG91bGRTaG93ID0gdGhpcy5fcm93T3V0bGV0LnZpZXdDb250YWluZXIubGVuZ3RoID09PSAwO1xuXG4gICAgaWYgKHNob3VsZFNob3cgPT09IHRoaXMuX2lzU2hvd2luZ05vRGF0YVJvdykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGNvbnRhaW5lciA9IHRoaXMuX25vRGF0YVJvd091dGxldC52aWV3Q29udGFpbmVyO1xuXG4gICAgaWYgKHNob3VsZFNob3cpIHtcbiAgICAgIGNvbnN0IHZpZXcgPSBjb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KG5vRGF0YVJvdy50ZW1wbGF0ZVJlZik7XG4gICAgICBjb25zdCByb290Tm9kZTogSFRNTEVsZW1lbnQgfCB1bmRlZmluZWQgPSB2aWV3LnJvb3ROb2Rlc1swXTtcblxuICAgICAgLy8gT25seSBhZGQgdGhlIGF0dHJpYnV0ZXMgaWYgd2UgaGF2ZSBhIHNpbmdsZSByb290IG5vZGUgc2luY2UgaXQncyBoYXJkXG4gICAgICAvLyB0byBmaWd1cmUgb3V0IHdoaWNoIG9uZSB0byBhZGQgaXQgdG8gd2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUuXG4gICAgICBpZiAodmlldy5yb290Tm9kZXMubGVuZ3RoID09PSAxICYmIHJvb3ROb2RlPy5ub2RlVHlwZSA9PT0gdGhpcy5fZG9jdW1lbnQuRUxFTUVOVF9OT0RFKSB7XG4gICAgICAgIHJvb3ROb2RlLnNldEF0dHJpYnV0ZSgncm9sZScsICdyb3cnKTtcbiAgICAgICAgcm9vdE5vZGUuY2xhc3NMaXN0LmFkZChub0RhdGFSb3cuX2NvbnRlbnRDbGFzc05hbWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb250YWluZXIuY2xlYXIoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9pc1Nob3dpbmdOb0RhdGFSb3cgPSBzaG91bGRTaG93O1xuXG4gICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cbn1cblxuLyoqIFV0aWxpdHkgZnVuY3Rpb24gdGhhdCBnZXRzIGEgbWVyZ2VkIGxpc3Qgb2YgdGhlIGVudHJpZXMgaW4gYW4gYXJyYXkgYW5kIHZhbHVlcyBvZiBhIFNldC4gKi9cbmZ1bmN0aW9uIG1lcmdlQXJyYXlBbmRTZXQ8VD4oYXJyYXk6IFRbXSwgc2V0OiBTZXQ8VD4pOiBUW10ge1xuICByZXR1cm4gYXJyYXkuY29uY2F0KEFycmF5LmZyb20oc2V0KSk7XG59XG5cbi8qKlxuICogRmluZHMgdGhlIGNsb3Nlc3QgdGFibGUgc2VjdGlvbiB0byBhbiBvdXRsZXQuIFdlIGNhbid0IHVzZSBgSFRNTEVsZW1lbnQuY2xvc2VzdGAgZm9yIHRoaXMsXG4gKiBiZWNhdXNlIHRoZSBub2RlIHJlcHJlc2VudGluZyB0aGUgb3V0bGV0IGlzIGEgY29tbWVudC5cbiAqL1xuZnVuY3Rpb24gY2xvc2VzdFRhYmxlU2VjdGlvbihvdXRsZXQ6IFJvd091dGxldCwgc2VjdGlvbjogc3RyaW5nKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgY29uc3QgdXBwZXJjYXNlU2VjdGlvbiA9IHNlY3Rpb24udG9VcHBlckNhc2UoKTtcbiAgbGV0IGN1cnJlbnQ6IE5vZGUgfCBudWxsID0gb3V0bGV0LnZpZXdDb250YWluZXIuZWxlbWVudC5uYXRpdmVFbGVtZW50O1xuXG4gIHdoaWxlIChjdXJyZW50KSB7XG4gICAgLy8gMSBpcyBhbiBlbGVtZW50IG5vZGUuXG4gICAgY29uc3Qgbm9kZU5hbWUgPSBjdXJyZW50Lm5vZGVUeXBlID09PSAxID8gKGN1cnJlbnQgYXMgSFRNTEVsZW1lbnQpLm5vZGVOYW1lIDogbnVsbDtcbiAgICBpZiAobm9kZU5hbWUgPT09IHVwcGVyY2FzZVNlY3Rpb24pIHtcbiAgICAgIHJldHVybiBjdXJyZW50IGFzIEhUTUxFbGVtZW50O1xuICAgIH0gZWxzZSBpZiAobm9kZU5hbWUgPT09ICdUQUJMRScpIHtcbiAgICAgIC8vIFN0b3AgdHJhdmVyc2luZyBwYXN0IHRoZSBgdGFibGVgIG5vZGUuXG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50Tm9kZTtcbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl19
|