@mediusinc/mng-commons 0.9.1-rc.2 → 0.9.1
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/dev-scripts/version-info.js +2 -0
- package/esm2020/lib/api/models/builders/query-param.builder.mjs +58 -58
- package/esm2020/lib/api/models/filter-match-type.model.mjs +24 -24
- package/esm2020/lib/api/models/filter-param.model.mjs +32 -32
- package/esm2020/lib/api/models/index.mjs +8 -8
- package/esm2020/lib/api/models/mappers.mjs +12 -12
- package/esm2020/lib/api/models/query-mode.model.mjs +17 -17
- package/esm2020/lib/api/models/query-param.model.mjs +67 -67
- package/esm2020/lib/api/models/query-result.model.mjs +17 -17
- package/esm2020/lib/api/models/serialization.model.mjs +1 -1
- package/esm2020/lib/api/services/api.abstract.service.mjs +55 -55
- package/esm2020/lib/api/services/crud-api.abstract.service.mjs +66 -66
- package/esm2020/lib/api/services/get-all-api.abstract.service.mjs +22 -22
- package/esm2020/lib/api/services/index.mjs +3 -3
- package/esm2020/lib/api/utils/index.mjs +2 -2
- package/esm2020/lib/api/utils/medius-rest.util.mjs +151 -151
- package/esm2020/lib/api/utils/object-serializer.util.mjs +243 -243
- package/esm2020/lib/components/action/action.component.mjs +177 -177
- package/esm2020/lib/components/action/editor/action-editor.component.mjs +247 -247
- package/esm2020/lib/components/action/index.mjs +3 -3
- package/esm2020/lib/components/action/models/action-confirmation-service.model.mjs +1 -1
- package/esm2020/lib/components/action/models/action-execution.model.mjs +234 -234
- package/esm2020/lib/components/action/models/index.mjs +2 -2
- package/esm2020/lib/components/action/route/action-route.component.mjs +124 -124
- package/esm2020/lib/components/form/autocomplete/autocomplete.component.mjs +268 -268
- package/esm2020/lib/components/form/dropdown/dropdown.component.mjs +160 -160
- package/esm2020/lib/components/form/editor/form-editor.component.mjs +189 -189
- package/esm2020/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.mjs +18 -18
- package/esm2020/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.mjs +42 -42
- package/esm2020/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.mjs +24 -24
- package/esm2020/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.mjs +96 -96
- package/esm2020/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.mjs +16 -16
- package/esm2020/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.mjs +178 -178
- package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.mjs +154 -154
- package/esm2020/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.mjs +126 -126
- package/esm2020/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.mjs +16 -16
- package/esm2020/lib/components/form/formly/fields/index.mjs +9 -9
- package/esm2020/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.mjs +14 -14
- package/esm2020/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.mjs +14 -14
- package/esm2020/lib/components/form/formly/wrappers/index.mjs +2 -2
- package/esm2020/lib/components/form/index.mjs +3 -3
- package/esm2020/lib/components/form/models/form-editor.event.mjs +33 -33
- package/esm2020/lib/components/form/models/index.mjs +1 -1
- package/esm2020/lib/components/layout/breadcrumb.component.mjs +16 -16
- package/esm2020/lib/components/layout/footer.component.mjs +17 -17
- package/esm2020/lib/components/layout/index.mjs +7 -7
- package/esm2020/lib/components/layout/main-layout.component.mjs +51 -51
- package/esm2020/lib/components/layout/menu-item.component.mjs +216 -216
- package/esm2020/lib/components/layout/menu.component.mjs +21 -21
- package/esm2020/lib/components/layout/services/index.mjs +1 -1
- package/esm2020/lib/components/layout/services/main-layout.component.service.mjs +192 -192
- package/esm2020/lib/components/layout/topbar.component.mjs +57 -57
- package/esm2020/lib/components/layout/version.component.mjs +57 -57
- package/esm2020/lib/components/tableview/index.mjs +6 -6
- package/esm2020/lib/components/tableview/models/index.mjs +1 -1
- package/esm2020/lib/components/tableview/models/table.event.mjs +15 -15
- package/esm2020/lib/components/tableview/route/tableview-route.abstract.component.mjs +57 -57
- package/esm2020/lib/components/tableview/route/tableview-route.component.mjs +61 -54
- package/esm2020/lib/components/tableview/table/column-filter/column-filter.component.mjs +102 -102
- package/esm2020/lib/components/tableview/table/column-value/column-value.component.mjs +70 -70
- package/esm2020/lib/components/tableview/table/table.component.mjs +433 -428
- package/esm2020/lib/components/tableview/tableview.component.mjs +91 -91
- package/esm2020/lib/config/formly.config.mjs +180 -180
- package/esm2020/lib/config/index.mjs +1 -1
- package/esm2020/lib/config/models/index.mjs +1 -1
- package/esm2020/lib/config/models/mng-config.model.mjs +1 -1
- package/esm2020/lib/data-providers/base.data-provider.mjs +16 -16
- package/esm2020/lib/data-providers/editor.data-provider.mjs +36 -36
- package/esm2020/lib/data-providers/index.mjs +5 -5
- package/esm2020/lib/data-providers/lookup.data-provider.mjs +15 -15
- package/esm2020/lib/data-providers/table.data-provider.mjs +16 -16
- package/esm2020/lib/data-providers/tableview.data-provider.mjs +16 -16
- package/esm2020/lib/descriptors/action.descriptor.mjs +565 -565
- package/esm2020/lib/descriptors/column.descriptor.mjs +265 -261
- package/esm2020/lib/descriptors/editor.descriptor.mjs +146 -146
- package/esm2020/lib/descriptors/field-validation.descriptor.mjs +20 -20
- package/esm2020/lib/descriptors/field.descriptor.mjs +806 -800
- package/esm2020/lib/descriptors/filter.descriptor.mjs +289 -262
- package/esm2020/lib/descriptors/index.mjs +9 -9
- package/esm2020/lib/descriptors/interfaces/field-config.interface.mjs +1 -1
- package/esm2020/lib/descriptors/interfaces/index.mjs +2 -2
- package/esm2020/lib/descriptors/interfaces/lookup-descriptor.interface.mjs +1 -1
- package/esm2020/lib/descriptors/model.descriptor.mjs +33 -33
- package/esm2020/lib/descriptors/table.descriptor.mjs +198 -197
- package/esm2020/lib/descriptors/tableview.descriptor.mjs +134 -134
- package/esm2020/lib/descriptors/types/action.type.mjs +52 -52
- package/esm2020/lib/descriptors/types/column.type.mjs +10 -10
- package/esm2020/lib/descriptors/types/editor.type.mjs +7 -7
- package/esm2020/lib/descriptors/types/field.type.mjs +52 -52
- package/esm2020/lib/descriptors/types/filter.type.mjs +30 -30
- package/esm2020/lib/descriptors/types/index.mjs +6 -6
- package/esm2020/lib/descriptors/types/table.type.mjs +16 -16
- package/esm2020/lib/directives/component.directive.mjs +43 -43
- package/esm2020/lib/directives/index.mjs +2 -2
- package/esm2020/lib/directives/template.directive.mjs +27 -27
- package/esm2020/lib/mng-commons.module.mjs +437 -437
- package/esm2020/lib/models/column-value.model.mjs +1 -1
- package/esm2020/lib/models/enum.model.mjs +1 -1
- package/esm2020/lib/models/error.model.mjs +1 -1
- package/esm2020/lib/models/index.mjs +7 -7
- package/esm2020/lib/models/menu.model.mjs +1 -1
- package/esm2020/lib/models/user.model.mjs +1 -1
- package/esm2020/lib/models/version.model.mjs +1 -1
- package/esm2020/lib/models/view-container.model.mjs +1 -1
- package/esm2020/lib/pipes/boolean.pipe.mjs +26 -26
- package/esm2020/lib/pipes/enum.pipe.mjs +24 -24
- package/esm2020/lib/pipes/i18n-property.pipe.mjs +17 -17
- package/esm2020/lib/pipes/index.mjs +5 -5
- package/esm2020/lib/pipes/json-path.pipe.mjs +79 -79
- package/esm2020/lib/pipes/link-formatter.pipe.mjs +38 -38
- package/esm2020/lib/router/index.mjs +1 -1
- package/esm2020/lib/router/models/index.mjs +1 -1
- package/esm2020/lib/router/models/router.model.mjs +1 -1
- package/esm2020/lib/router/route-builder.mjs +431 -431
- package/esm2020/lib/services/action-executor.service.mjs +536 -536
- package/esm2020/lib/services/commons.service.mjs +331 -331
- package/esm2020/lib/services/configuration.service.mjs +110 -110
- package/esm2020/lib/services/error-mapper.service.mjs +13 -13
- package/esm2020/lib/services/index.mjs +6 -6
- package/esm2020/lib/services/internal/commons-init.provider.mjs +3 -3
- package/esm2020/lib/services/internal/commons-init.service.mjs +43 -43
- package/esm2020/lib/services/internal/index.mjs +2 -2
- package/esm2020/lib/services/navigation.service.mjs +47 -47
- package/esm2020/lib/services/providers/config-service.provider.mjs +29 -29
- package/esm2020/lib/services/providers/formly-config.provider.mjs +30 -30
- package/esm2020/lib/services/providers/index.mjs +2 -2
- package/esm2020/lib/services/tokens/browser-storage.token.mjs +5 -5
- package/esm2020/lib/services/tokens/commons-init.token.mjs +2 -2
- package/esm2020/lib/services/tokens/default-setting.token.mjs +2 -2
- package/esm2020/lib/services/tokens/index.mjs +4 -4
- package/esm2020/lib/services/tokens/module-config.token.mjs +2 -2
- package/esm2020/lib/services/version.service.mjs +37 -37
- package/esm2020/lib/services/view-container.component.service.mjs +34 -34
- package/esm2020/lib/types/index.mjs +2 -2
- package/esm2020/lib/types/type.decorator.mjs +12 -12
- package/esm2020/lib/types/type.model.mjs +1 -1
- package/esm2020/lib/utils/action-data-provider.util.mjs +144 -144
- package/esm2020/lib/utils/editor-formly.util.mjs +210 -210
- package/esm2020/lib/utils/enum.util.mjs +81 -81
- package/esm2020/lib/utils/i18n.util.mjs +232 -232
- package/esm2020/lib/utils/index.mjs +7 -7
- package/esm2020/lib/utils/model.util.mjs +59 -59
- package/esm2020/lib/utils/notification.util.mjs +45 -45
- package/esm2020/lib/utils/route.util.mjs +23 -23
- package/esm2020/lib/utils/styles.util.mjs +40 -40
- package/esm2020/lib/utils/type.util.mjs +76 -76
- package/esm2020/mediusinc-mng-commons.mjs +4 -4
- package/esm2020/public-api.mjs +41 -41
- package/fesm2015/mediusinc-mng-commons.mjs +10001 -9950
- package/fesm2015/mediusinc-mng-commons.mjs.map +1 -1
- package/fesm2020/mediusinc-mng-commons.mjs +9861 -9812
- package/fesm2020/mediusinc-mng-commons.mjs.map +1 -1
- package/lib/api/models/builders/query-param.builder.d.ts +13 -13
- package/lib/api/models/filter-match-type.model.d.ts +23 -23
- package/lib/api/models/filter-param.model.d.ts +23 -23
- package/lib/api/models/index.d.ts +8 -8
- package/lib/api/models/mappers.d.ts +6 -6
- package/lib/api/models/query-mode.model.d.ts +16 -16
- package/lib/api/models/query-param.model.d.ts +31 -31
- package/lib/api/models/query-result.model.d.ts +23 -23
- package/lib/api/models/serialization.model.d.ts +8 -8
- package/lib/api/services/api.abstract.service.d.ts +24 -24
- package/lib/api/services/crud-api.abstract.service.d.ts +22 -22
- package/lib/api/services/get-all-api.abstract.service.d.ts +14 -14
- package/lib/api/services/index.d.ts +3 -3
- package/lib/api/utils/index.d.ts +2 -2
- package/lib/api/utils/medius-rest.util.d.ts +15 -15
- package/lib/api/utils/object-serializer.util.d.ts +33 -33
- package/lib/components/action/action.component.d.ts +69 -69
- package/lib/components/action/editor/action-editor.component.d.ts +64 -64
- package/lib/components/action/index.d.ts +3 -3
- package/lib/components/action/models/action-confirmation-service.model.d.ts +6 -6
- package/lib/components/action/models/action-execution.model.d.ts +129 -129
- package/lib/components/action/models/index.d.ts +2 -2
- package/lib/components/action/route/action-route.component.d.ts +31 -31
- package/lib/components/form/autocomplete/autocomplete.component.d.ts +53 -53
- package/lib/components/form/dropdown/dropdown.component.d.ts +44 -44
- package/lib/components/form/editor/form-editor.component.d.ts +45 -45
- package/lib/components/form/formly/fields/formly-field-autocomplete/formly-field-autocomplete.component.d.ts +12 -12
- package/lib/components/form/formly/fields/formly-field-dropdown/formly-field-dropdown.component.d.ts +14 -14
- package/lib/components/form/formly/fields/formly-field-fieldset/formly-field-fieldset.component.d.ts +13 -13
- package/lib/components/form/formly/fields/formly-field-input/formly-field-input.component.d.ts +21 -21
- package/lib/components/form/formly/fields/formly-field-label/formly-field-label.component.d.ts +6 -6
- package/lib/components/form/formly/fields/formly-field-lookup-dialog/formly-field-lookup-dialog.component.d.ts +45 -45
- package/lib/components/form/formly/fields/formly-field-table-dialog-form/formly-field-table-dialog-form.component.d.ts +22 -22
- package/lib/components/form/formly/fields/formly-field-table-dialog-multiselect/formly-field-table-dialog-multiselect.component.d.ts +37 -37
- package/lib/components/form/formly/fields/formly-field-tabs/formly-field-tabs.component.d.ts +6 -6
- package/lib/components/form/formly/fields/index.d.ts +9 -9
- package/lib/components/form/formly/wrappers/formly-field-wrapper/formly-field-wrapper.component.d.ts +6 -6
- package/lib/components/form/formly/wrappers/formly-table-wrapper/formly-table-wrapper.component.d.ts +6 -6
- package/lib/components/form/formly/wrappers/index.d.ts +2 -2
- package/lib/components/form/index.d.ts +3 -3
- package/lib/components/form/models/form-editor.event.d.ts +37 -37
- package/lib/components/form/models/index.d.ts +1 -1
- package/lib/components/layout/breadcrumb.component.d.ts +8 -8
- package/lib/components/layout/footer.component.d.ts +9 -9
- package/lib/components/layout/index.d.ts +7 -7
- package/lib/components/layout/main-layout.component.d.ts +20 -20
- package/lib/components/layout/menu-item.component.d.ts +37 -37
- package/lib/components/layout/menu.component.d.ts +10 -10
- package/lib/components/layout/services/index.d.ts +1 -1
- package/lib/components/layout/services/main-layout.component.service.d.ts +65 -65
- package/lib/components/layout/topbar.component.d.ts +24 -24
- package/lib/components/layout/version.component.d.ts +19 -19
- package/lib/components/tableview/index.d.ts +6 -6
- package/lib/components/tableview/models/index.d.ts +1 -1
- package/lib/components/tableview/models/table.event.d.ts +17 -17
- package/lib/components/tableview/route/tableview-route.abstract.component.d.ts +20 -20
- package/lib/components/tableview/route/tableview-route.component.d.ts +21 -18
- package/lib/components/tableview/table/column-filter/column-filter.component.d.ts +32 -32
- package/lib/components/tableview/table/column-value/column-value.component.d.ts +29 -29
- package/lib/components/tableview/table/table.component.d.ts +105 -105
- package/lib/components/tableview/tableview.component.d.ts +41 -41
- package/lib/config/formly.config.d.ts +15 -15
- package/lib/config/index.d.ts +1 -1
- package/lib/config/models/index.d.ts +1 -1
- package/lib/config/models/mng-config.model.d.ts +36 -36
- package/lib/data-providers/base.data-provider.d.ts +14 -14
- package/lib/data-providers/editor.data-provider.d.ts +25 -25
- package/lib/data-providers/index.d.ts +5 -5
- package/lib/data-providers/lookup.data-provider.d.ts +14 -14
- package/lib/data-providers/table.data-provider.d.ts +14 -14
- package/lib/data-providers/tableview.data-provider.d.ts +15 -15
- package/lib/descriptors/action.descriptor.d.ts +227 -227
- package/lib/descriptors/column.descriptor.d.ts +82 -81
- package/lib/descriptors/editor.descriptor.d.ts +37 -37
- package/lib/descriptors/field-validation.descriptor.d.ts +18 -18
- package/lib/descriptors/field.descriptor.d.ts +289 -287
- package/lib/descriptors/filter.descriptor.d.ts +106 -97
- package/lib/descriptors/index.d.ts +9 -9
- package/lib/descriptors/interfaces/field-config.interface.d.ts +9 -9
- package/lib/descriptors/interfaces/index.d.ts +2 -2
- package/lib/descriptors/interfaces/lookup-descriptor.interface.d.ts +17 -17
- package/lib/descriptors/model.descriptor.d.ts +15 -15
- package/lib/descriptors/table.descriptor.d.ts +66 -66
- package/lib/descriptors/tableview.descriptor.d.ts +42 -42
- package/lib/descriptors/types/action.type.d.ts +45 -45
- package/lib/descriptors/types/column.type.d.ts +9 -9
- package/lib/descriptors/types/editor.type.d.ts +6 -6
- package/lib/descriptors/types/field.type.d.ts +44 -44
- package/lib/descriptors/types/filter.type.d.ts +27 -27
- package/lib/descriptors/types/index.d.ts +6 -6
- package/lib/descriptors/types/table.type.d.ts +13 -13
- package/lib/directives/component.directive.d.ts +16 -16
- package/lib/directives/index.d.ts +2 -2
- package/lib/directives/template.directive.d.ts +13 -13
- package/lib/mng-commons.module.d.ts +87 -87
- package/lib/models/column-value.model.d.ts +4 -4
- package/lib/models/enum.model.d.ts +6 -6
- package/lib/models/error.model.d.ts +14 -14
- package/lib/models/index.d.ts +7 -7
- package/lib/models/menu.model.d.ts +25 -25
- package/lib/models/user.model.d.ts +8 -8
- package/lib/models/version.model.d.ts +18 -18
- package/lib/models/view-container.model.d.ts +6 -6
- package/lib/pipes/boolean.pipe.d.ts +7 -7
- package/lib/pipes/enum.pipe.d.ts +8 -8
- package/lib/pipes/i18n-property.pipe.d.ts +8 -8
- package/lib/pipes/index.d.ts +5 -5
- package/lib/pipes/json-path.pipe.d.ts +13 -13
- package/lib/pipes/link-formatter.pipe.d.ts +11 -11
- package/lib/router/index.d.ts +1 -1
- package/lib/router/models/index.d.ts +1 -1
- package/lib/router/models/router.model.d.ts +22 -22
- package/lib/router/route-builder.d.ts +86 -86
- package/lib/services/action-executor.service.d.ts +149 -149
- package/lib/services/commons.service.d.ts +73 -73
- package/lib/services/configuration.service.d.ts +36 -36
- package/lib/services/error-mapper.service.d.ts +7 -7
- package/lib/services/index.d.ts +6 -6
- package/lib/services/internal/commons-init.provider.d.ts +3 -3
- package/lib/services/internal/commons-init.service.d.ts +16 -16
- package/lib/services/internal/index.d.ts +2 -2
- package/lib/services/navigation.service.d.ts +14 -14
- package/lib/services/providers/config-service.provider.d.ts +6 -6
- package/lib/services/providers/formly-config.provider.d.ts +4 -4
- package/lib/services/providers/index.d.ts +2 -2
- package/lib/services/tokens/browser-storage.token.d.ts +2 -2
- package/lib/services/tokens/commons-init.token.d.ts +3 -3
- package/lib/services/tokens/default-setting.token.d.ts +2 -2
- package/lib/services/tokens/index.d.ts +4 -4
- package/lib/services/tokens/module-config.token.d.ts +3 -3
- package/lib/services/version.service.d.ts +13 -13
- package/lib/services/view-container.component.service.d.ts +22 -22
- package/lib/types/index.d.ts +2 -2
- package/lib/types/type.decorator.d.ts +4 -4
- package/lib/types/type.model.d.ts +20 -20
- package/lib/utils/action-data-provider.util.d.ts +20 -20
- package/lib/utils/editor-formly.util.d.ts +10 -10
- package/lib/utils/enum.util.d.ts +50 -50
- package/lib/utils/i18n.util.d.ts +56 -56
- package/lib/utils/index.d.ts +7 -7
- package/lib/utils/model.util.d.ts +8 -8
- package/lib/utils/notification.util.d.ts +11 -11
- package/lib/utils/route.util.d.ts +4 -4
- package/lib/utils/styles.util.d.ts +14 -14
- package/lib/utils/type.util.d.ts +36 -36
- package/mediusinc-mng-commons.d.ts +5 -5
- package/package.json +6 -6
- package/public-api.d.ts +30 -30
- package/scss/mng-overrides/_theme_tableview.scss +0 -4
- package/version-info.json +6 -6
- package/mediusinc-mng-commons-0.9.1-rc.2.tgz +0 -0
|
@@ -1,432 +1,432 @@
|
|
|
1
|
-
import { MngActionRouteComponent } from '../components/action';
|
|
2
|
-
import { MngMainLayoutComponent } from '../components/layout';
|
|
3
|
-
import { MngTableviewRouteComponent } from '../components/tableview';
|
|
4
|
-
import { RouteUtil } from '../utils/route.util';
|
|
5
|
-
export class RoutesBuilder {
|
|
6
|
-
constructor(layoutRoute) {
|
|
7
|
-
this.routes = [];
|
|
8
|
-
this.layoutRoute = layoutRoute?.withRoot(this);
|
|
9
|
-
this.currentRoute = layoutRoute;
|
|
10
|
-
}
|
|
11
|
-
static create() {
|
|
12
|
-
return new RoutesBuilder();
|
|
13
|
-
}
|
|
14
|
-
static createWithLayout(layoutComponent = MngMainLayoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent) {
|
|
15
|
-
const layoutRoute = RouteBuilder.createLayoutRoute('', layoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent);
|
|
16
|
-
return new RoutesBuilder(layoutRoute);
|
|
17
|
-
}
|
|
18
|
-
addAngularRoute(route) {
|
|
19
|
-
return this.addRouteBuilder(RouteBuilder.createFromRoute(route));
|
|
20
|
-
}
|
|
21
|
-
addRouteRedirect(path, redirectTo, pathMatch = 'prefix') {
|
|
22
|
-
return this.addRouteBuilder(RouteBuilder.createRedirect(path, redirectTo, pathMatch));
|
|
23
|
-
}
|
|
24
|
-
addLazyRoute(path, loadChildren, canLoad) {
|
|
25
|
-
return this.addRouteBuilder(RouteBuilder.createLazyRoute(path, loadChildren, canLoad));
|
|
26
|
-
}
|
|
27
|
-
addRoute(path, component) {
|
|
28
|
-
return this.addRouteBuilder(RouteBuilder.create(path, component));
|
|
29
|
-
}
|
|
30
|
-
addTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
31
|
-
return this.addRouteBuilder(RouteBuilder.createTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails, hasEdit, hasAdd));
|
|
32
|
-
}
|
|
33
|
-
addTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
34
|
-
return this.addRouteBuilder(RouteBuilder.createTableviewRoutesFromComponent(path, component, hasDetails, hasEdit, hasAdd));
|
|
35
|
-
}
|
|
36
|
-
addRouteBuilder(routeBuilder) {
|
|
37
|
-
this.currentRoute = routeBuilder.withRoot(this);
|
|
38
|
-
this.routes.push(routeBuilder);
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
toRoute() {
|
|
42
|
-
if (!this.currentRoute) {
|
|
43
|
-
throw new Error('No routes were added!');
|
|
44
|
-
}
|
|
45
|
-
return this.currentRoute;
|
|
46
|
-
}
|
|
47
|
-
buildRoutes() {
|
|
48
|
-
let angularRoutes = [];
|
|
49
|
-
for (const route of this.routes) {
|
|
50
|
-
angularRoutes.push(route.buildRoute());
|
|
51
|
-
}
|
|
52
|
-
if (this.layoutRoute) {
|
|
53
|
-
const layoutAngularRoute = this.layoutRoute.buildRoute();
|
|
54
|
-
if (angularRoutes.length > 0) {
|
|
55
|
-
layoutAngularRoute.children = angularRoutes;
|
|
56
|
-
}
|
|
57
|
-
angularRoutes = [layoutAngularRoute];
|
|
58
|
-
}
|
|
59
|
-
return angularRoutes;
|
|
60
|
-
}
|
|
61
|
-
buildMenu() {
|
|
62
|
-
const menuItems = [];
|
|
63
|
-
for (const route of this.routes) {
|
|
64
|
-
menuItems.push(...route.buildMenu());
|
|
65
|
-
}
|
|
66
|
-
return menuItems.flat();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
export class RouteBuilder {
|
|
70
|
-
constructor(route) {
|
|
71
|
-
this.routePath = [];
|
|
72
|
-
this.children = [];
|
|
73
|
-
this.menuItemChildren = [];
|
|
74
|
-
if (!route.data) {
|
|
75
|
-
route.data = {};
|
|
76
|
-
}
|
|
77
|
-
if (!route.data['breadcrumb']) {
|
|
78
|
-
route.data['breadcrumb'] = null;
|
|
79
|
-
}
|
|
80
|
-
this.route = route;
|
|
81
|
-
if (this.route.path && this.route.path.length > 0) {
|
|
82
|
-
this.routePath = [this.route.path];
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
static create(path, component) {
|
|
86
|
-
return new RouteBuilder({
|
|
87
|
-
path: path,
|
|
88
|
-
component: component
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
static createRedirect(path, redirectTo, pathMatch = 'prefix') {
|
|
92
|
-
return new RouteBuilder({
|
|
93
|
-
path: path,
|
|
94
|
-
redirectTo: redirectTo,
|
|
95
|
-
pathMatch: pathMatch
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
static createLazyRoute(path, loadChildren, canLoad) {
|
|
99
|
-
const route = { path: path, loadChildren: loadChildren };
|
|
100
|
-
if (canLoad?.length) {
|
|
101
|
-
route.canLoad = canLoad;
|
|
102
|
-
}
|
|
103
|
-
return new RouteBuilder(route);
|
|
104
|
-
}
|
|
105
|
-
static createFromRoute(route) {
|
|
106
|
-
return new RouteBuilder(route);
|
|
107
|
-
}
|
|
108
|
-
static createLayoutRoute(path, layoutComponent = MngMainLayoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent) {
|
|
109
|
-
const layoutRoute = RouteBuilder.create(path, layoutComponent);
|
|
110
|
-
if (topbarComponent || breadcrumbComponent || menuComponent || footerComponent) {
|
|
111
|
-
const dataBuilder = RouteDataBuilder.create();
|
|
112
|
-
if (topbarComponent) {
|
|
113
|
-
dataBuilder.withTopbarComponent(topbarComponent);
|
|
114
|
-
}
|
|
115
|
-
if (breadcrumbComponent) {
|
|
116
|
-
dataBuilder.withBreadcrumbComponent(breadcrumbComponent);
|
|
117
|
-
}
|
|
118
|
-
if (menuComponent) {
|
|
119
|
-
dataBuilder.withMenuComponent(menuComponent);
|
|
120
|
-
}
|
|
121
|
-
if (footerComponent) {
|
|
122
|
-
dataBuilder.withFooterComponent(footerComponent);
|
|
123
|
-
}
|
|
124
|
-
layoutRoute.withDataBuilder(dataBuilder);
|
|
125
|
-
}
|
|
126
|
-
return layoutRoute;
|
|
127
|
-
}
|
|
128
|
-
static createTableviewRoutes(path, descriptor, dataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
129
|
-
const tableviewRoute = RouteBuilder.createFromRoute({
|
|
130
|
-
data: RouteDataBuilder.create().withTableview(descriptor, dataProvider, actions).build(),
|
|
131
|
-
path: path,
|
|
132
|
-
component: MngTableviewRouteComponent
|
|
133
|
-
});
|
|
134
|
-
RouteBuilder.addActionsSubroutesToTableviewParent(tableviewRoute, hasDetails, hasEdit, hasAdd);
|
|
135
|
-
return tableviewRoute;
|
|
136
|
-
}
|
|
137
|
-
static createTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
138
|
-
const actionCrudRoute = RouteBuilder.create(path, component);
|
|
139
|
-
RouteBuilder.addActionsSubroutesToTableviewParent(actionCrudRoute, hasDetails, hasEdit, hasAdd);
|
|
140
|
-
return actionCrudRoute;
|
|
141
|
-
}
|
|
142
|
-
static addActionsSubroutesToTableviewParent(parentRoute, hasDetails, hasEdit, hasAdd) {
|
|
143
|
-
parentRoute.addChild('', MngActionRouteComponent);
|
|
144
|
-
if (hasAdd) {
|
|
145
|
-
parentRoute.addChild('add', MngActionRouteComponent);
|
|
146
|
-
}
|
|
147
|
-
if (hasDetails) {
|
|
148
|
-
parentRoute.addChild(':itemId', MngActionRouteComponent);
|
|
149
|
-
}
|
|
150
|
-
if (hasEdit) {
|
|
151
|
-
parentRoute.addChild(':itemId/edit', MngActionRouteComponent);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
withRoot(routesBuilder) {
|
|
155
|
-
this.root = routesBuilder;
|
|
156
|
-
return this;
|
|
157
|
-
}
|
|
158
|
-
withParent(parent) {
|
|
159
|
-
this.parent = parent;
|
|
160
|
-
this.routePath = RouteUtil.removeEmptyPathSegments([...this.parent.routePath, this.route.path ?? '']);
|
|
161
|
-
return this;
|
|
162
|
-
}
|
|
163
|
-
withBreadcrumb(breadcrumb) {
|
|
164
|
-
this.breadcrumb = breadcrumb;
|
|
165
|
-
this.route.data['breadcrumb'] = breadcrumb;
|
|
166
|
-
return this;
|
|
167
|
-
}
|
|
168
|
-
withPageTitle(pageTitle) {
|
|
169
|
-
this.pageTitle = pageTitle;
|
|
170
|
-
this.route.data['pageTitle'] = pageTitle;
|
|
171
|
-
return this;
|
|
172
|
-
}
|
|
173
|
-
withRedirectTo(redirectTo) {
|
|
174
|
-
this.route.redirectTo = redirectTo;
|
|
175
|
-
return this;
|
|
176
|
-
}
|
|
177
|
-
withPathMatch(pathMatch) {
|
|
178
|
-
this.route.pathMatch = pathMatch;
|
|
179
|
-
return this;
|
|
180
|
-
}
|
|
181
|
-
withTitle(title) {
|
|
182
|
-
this.withPageTitle(title);
|
|
183
|
-
this.withBreadcrumb(title);
|
|
184
|
-
return this;
|
|
185
|
-
}
|
|
186
|
-
withCanActivate(diToken) {
|
|
187
|
-
if (!this.route.canActivate) {
|
|
188
|
-
this.route.canActivate = [];
|
|
189
|
-
}
|
|
190
|
-
this.route.canActivate.push(diToken);
|
|
191
|
-
return this;
|
|
192
|
-
}
|
|
193
|
-
withCanDeactivate(diToken) {
|
|
194
|
-
if (!this.route.canDeactivate) {
|
|
195
|
-
this.route.canDeactivate = [];
|
|
196
|
-
}
|
|
197
|
-
this.route.canDeactivate.push(diToken);
|
|
198
|
-
return this;
|
|
199
|
-
}
|
|
200
|
-
withResolver(diToken, name) {
|
|
201
|
-
if (!this.route.resolve) {
|
|
202
|
-
this.route.resolve = {};
|
|
203
|
-
}
|
|
204
|
-
this.route.resolve[name] = diToken;
|
|
205
|
-
return this;
|
|
206
|
-
}
|
|
207
|
-
withData(data) {
|
|
208
|
-
this.route.data = data;
|
|
209
|
-
return this;
|
|
210
|
-
}
|
|
211
|
-
withDataBuilder(dataBuilder) {
|
|
212
|
-
this.route.data = dataBuilder.build();
|
|
213
|
-
return this;
|
|
214
|
-
}
|
|
215
|
-
withMngMenuItem(menuItem) {
|
|
216
|
-
this.menuItem = menuItem;
|
|
217
|
-
return this;
|
|
218
|
-
}
|
|
219
|
-
withMenuItem(icon, label, routerLink) {
|
|
220
|
-
this.menuItem = this.createMenuItem(icon, label, routerLink);
|
|
221
|
-
return this;
|
|
222
|
-
}
|
|
223
|
-
withMenuItemChild(label, icon, routerLink) {
|
|
224
|
-
this.menuItemChildren.push(this.createMenuItem(icon, label, routerLink));
|
|
225
|
-
return this;
|
|
226
|
-
}
|
|
227
|
-
withMenuItemChildren(routesBuilder) {
|
|
228
|
-
const menu = routesBuilder.buildMenu();
|
|
229
|
-
this.adjustMenuRouterLinksFromBuilder(menu);
|
|
230
|
-
this.menuItemChildren.push(...menu);
|
|
231
|
-
return this;
|
|
232
|
-
}
|
|
233
|
-
addChild(path, component) {
|
|
234
|
-
const childRouteBuilder = RouteBuilder.create(path, component);
|
|
235
|
-
this.addChildBuilder(childRouteBuilder);
|
|
236
|
-
return childRouteBuilder;
|
|
237
|
-
}
|
|
238
|
-
addChildBuilder(routeBuilder) {
|
|
239
|
-
routeBuilder.withParent(this);
|
|
240
|
-
if (this.root) {
|
|
241
|
-
routeBuilder.withRoot(this.root);
|
|
242
|
-
}
|
|
243
|
-
this.children.push(routeBuilder);
|
|
244
|
-
return this;
|
|
245
|
-
}
|
|
246
|
-
addTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
247
|
-
const routeBuilder = RouteBuilder.createTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails, hasEdit, hasAdd);
|
|
248
|
-
this.addChildBuilder(routeBuilder);
|
|
249
|
-
return routeBuilder;
|
|
250
|
-
}
|
|
251
|
-
addTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
252
|
-
const routeBuilder = RouteBuilder.createTableviewRoutesFromComponent(path, component, hasDetails, hasEdit, hasAdd);
|
|
253
|
-
this.addChildBuilder(routeBuilder);
|
|
254
|
-
return routeBuilder;
|
|
255
|
-
}
|
|
256
|
-
toParent() {
|
|
257
|
-
if (!this.parent) {
|
|
258
|
-
throw new Error('Parent was not provided.');
|
|
259
|
-
}
|
|
260
|
-
return this.parent;
|
|
261
|
-
}
|
|
262
|
-
toRoot() {
|
|
263
|
-
if (!this.root) {
|
|
264
|
-
throw new Error('Root was not provided.');
|
|
265
|
-
}
|
|
266
|
-
return this.root;
|
|
267
|
-
}
|
|
268
|
-
finish() {
|
|
269
|
-
return this.toRoot();
|
|
270
|
-
}
|
|
271
|
-
buildRoute() {
|
|
272
|
-
const angularRoute = {
|
|
273
|
-
...this.route
|
|
274
|
-
};
|
|
275
|
-
if ((this.route.children?.length ?? 0) > 0 || this.children.length > 0) {
|
|
276
|
-
// route has children
|
|
277
|
-
angularRoute.children = [];
|
|
278
|
-
if (this.route.children?.length) {
|
|
279
|
-
angularRoute.children.push(...this.route.children);
|
|
280
|
-
}
|
|
281
|
-
if (this.children.length) {
|
|
282
|
-
for (const childRoute of this.children) {
|
|
283
|
-
angularRoute.children.push(childRoute.buildRoute());
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
if (this.route.canActivate) {
|
|
288
|
-
angularRoute.canActivate = [...this.route.canActivate];
|
|
289
|
-
}
|
|
290
|
-
if (this.route.canActivateChild) {
|
|
291
|
-
angularRoute.canActivateChild = [...this.route.canActivateChild];
|
|
292
|
-
}
|
|
293
|
-
if (this.route.canLoad) {
|
|
294
|
-
angularRoute.canLoad = [...this.route.canLoad];
|
|
295
|
-
}
|
|
296
|
-
if (this.route.canDeactivate) {
|
|
297
|
-
angularRoute.canDeactivate = [...this.route.canDeactivate];
|
|
298
|
-
}
|
|
299
|
-
if (this.route.resolve) {
|
|
300
|
-
angularRoute.resolve = { ...this.route.resolve };
|
|
301
|
-
}
|
|
302
|
-
return angularRoute;
|
|
303
|
-
}
|
|
304
|
-
buildMenu() {
|
|
305
|
-
const menuItemBuild = this.menuItem ? { ...this.menuItem } : null;
|
|
306
|
-
const routeChildrenMenuItems = this.children.flatMap(child => child.buildMenu());
|
|
307
|
-
const menuItemChildren = [];
|
|
308
|
-
const menuItemChildrenBuild = [];
|
|
309
|
-
if (menuItemBuild?.items) {
|
|
310
|
-
menuItemChildrenBuild.push(...menuItemBuild.items);
|
|
311
|
-
}
|
|
312
|
-
for (const menuItemChild of this.menuItemChildren) {
|
|
313
|
-
const finalMenuItemChild = { ...menuItemChild };
|
|
314
|
-
if (!finalMenuItemChild.routerLink) {
|
|
315
|
-
finalMenuItemChild.routerLink = this.routePath;
|
|
316
|
-
}
|
|
317
|
-
if (typeof finalMenuItemChild.routerLink === 'string') {
|
|
318
|
-
finalMenuItemChild.routerLink = [finalMenuItemChild.routerLink];
|
|
319
|
-
}
|
|
320
|
-
finalMenuItemChild.routerLink = RouteUtil.removeEmptyPathSegments(finalMenuItemChild.routerLink);
|
|
321
|
-
menuItemChildren.push(finalMenuItemChild);
|
|
322
|
-
}
|
|
323
|
-
menuItemChildrenBuild.push(...menuItemChildren, ...routeChildrenMenuItems);
|
|
324
|
-
if (!menuItemBuild) {
|
|
325
|
-
return menuItemChildrenBuild;
|
|
326
|
-
}
|
|
327
|
-
menuItemBuild.label = menuItemBuild.label ?? this.pageTitle;
|
|
328
|
-
if (typeof menuItemBuild.routerLink === 'string') {
|
|
329
|
-
menuItemBuild.routerLink = [menuItemBuild.routerLink];
|
|
330
|
-
}
|
|
331
|
-
menuItemBuild.routerLink = RouteUtil.removeEmptyPathSegments(menuItemBuild.routerLink ?? this.routePath);
|
|
332
|
-
if (menuItemChildrenBuild.length > 0) {
|
|
333
|
-
menuItemBuild.items = menuItemChildrenBuild;
|
|
334
|
-
}
|
|
335
|
-
if (!menuItemBuild.guards) {
|
|
336
|
-
const guards = this.findMenuItemGuards();
|
|
337
|
-
if (guards.length > 0) {
|
|
338
|
-
menuItemBuild.guards = guards;
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
return [menuItemBuild];
|
|
342
|
-
}
|
|
343
|
-
createMenuItem(icon, label, routerLink) {
|
|
344
|
-
const menuItem = {};
|
|
345
|
-
if (icon) {
|
|
346
|
-
menuItem.icon = icon;
|
|
347
|
-
}
|
|
348
|
-
if (label) {
|
|
349
|
-
menuItem.label = label;
|
|
350
|
-
}
|
|
351
|
-
if (routerLink) {
|
|
352
|
-
menuItem.routerLink = routerLink;
|
|
353
|
-
}
|
|
354
|
-
return menuItem;
|
|
355
|
-
}
|
|
356
|
-
adjustMenuRouterLinksFromBuilder(menuItems) {
|
|
357
|
-
for (const menuItem of menuItems) {
|
|
358
|
-
if (menuItem.routerLink) {
|
|
359
|
-
menuItem.routerLink = RouteUtil.appendPathToBasePath(this.routePath, typeof menuItem.routerLink === 'string' ? [menuItem.routerLink] : menuItem.routerLink);
|
|
360
|
-
}
|
|
361
|
-
if (Array.isArray(menuItem.items)) {
|
|
362
|
-
this.adjustMenuRouterLinksFromBuilder(menuItem.items);
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
findMenuItemGuards() {
|
|
367
|
-
const guards = [];
|
|
368
|
-
if (this.route.canActivate?.length) {
|
|
369
|
-
guards.push(...this.route.canActivate);
|
|
370
|
-
}
|
|
371
|
-
if (this.parent) {
|
|
372
|
-
// Check for parent guards that should be included in decision to hide menu item!
|
|
373
|
-
// Some parent routes might have guards, but no menu items, so this guards must be taken into account here,
|
|
374
|
-
// because there is no parent menu item to hide.
|
|
375
|
-
this.parent.findMenuItemGuards().forEach(g => {
|
|
376
|
-
if (guards.indexOf(g) < 0) {
|
|
377
|
-
guards.push(g);
|
|
378
|
-
}
|
|
379
|
-
});
|
|
380
|
-
}
|
|
381
|
-
return guards;
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
export class RouteDataBuilder {
|
|
385
|
-
constructor(init) {
|
|
386
|
-
this.data = init ?? {};
|
|
387
|
-
if (!this.data.breadcrumb) {
|
|
388
|
-
this.data.breadcrumb = null;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
static create(data) {
|
|
392
|
-
return new RouteDataBuilder(data);
|
|
393
|
-
}
|
|
394
|
-
withBreadcrumb(breadcrumb) {
|
|
395
|
-
this.data.breadcrumb = breadcrumb;
|
|
396
|
-
return this;
|
|
397
|
-
}
|
|
398
|
-
withPageTitle(pageTitle) {
|
|
399
|
-
this.data.pageTitle = pageTitle;
|
|
400
|
-
return this;
|
|
401
|
-
}
|
|
402
|
-
withTableview(descriptor, dataProvider, actions) {
|
|
403
|
-
this.data.tableview = {
|
|
404
|
-
descriptor: descriptor,
|
|
405
|
-
dataProvider: dataProvider
|
|
406
|
-
};
|
|
407
|
-
if (actions) {
|
|
408
|
-
this.data.tableview.actions = actions;
|
|
409
|
-
}
|
|
410
|
-
return this;
|
|
411
|
-
}
|
|
412
|
-
withTopbarComponent(component) {
|
|
413
|
-
this.data.topbarComponent = component;
|
|
414
|
-
return this;
|
|
415
|
-
}
|
|
416
|
-
withBreadcrumbComponent(component) {
|
|
417
|
-
this.data.breadcrumbComponent = component;
|
|
418
|
-
return this;
|
|
419
|
-
}
|
|
420
|
-
withMenuComponent(component) {
|
|
421
|
-
this.data.menuComponent = component;
|
|
422
|
-
return this;
|
|
423
|
-
}
|
|
424
|
-
withFooterComponent(component) {
|
|
425
|
-
this.data.footerComponent = component;
|
|
426
|
-
return this;
|
|
427
|
-
}
|
|
428
|
-
build() {
|
|
429
|
-
return this.data;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
1
|
+
import { MngActionRouteComponent } from '../components/action';
|
|
2
|
+
import { MngMainLayoutComponent } from '../components/layout';
|
|
3
|
+
import { MngTableviewRouteComponent } from '../components/tableview';
|
|
4
|
+
import { RouteUtil } from '../utils/route.util';
|
|
5
|
+
export class RoutesBuilder {
|
|
6
|
+
constructor(layoutRoute) {
|
|
7
|
+
this.routes = [];
|
|
8
|
+
this.layoutRoute = layoutRoute?.withRoot(this);
|
|
9
|
+
this.currentRoute = layoutRoute;
|
|
10
|
+
}
|
|
11
|
+
static create() {
|
|
12
|
+
return new RoutesBuilder();
|
|
13
|
+
}
|
|
14
|
+
static createWithLayout(layoutComponent = MngMainLayoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent) {
|
|
15
|
+
const layoutRoute = RouteBuilder.createLayoutRoute('', layoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent);
|
|
16
|
+
return new RoutesBuilder(layoutRoute);
|
|
17
|
+
}
|
|
18
|
+
addAngularRoute(route) {
|
|
19
|
+
return this.addRouteBuilder(RouteBuilder.createFromRoute(route));
|
|
20
|
+
}
|
|
21
|
+
addRouteRedirect(path, redirectTo, pathMatch = 'prefix') {
|
|
22
|
+
return this.addRouteBuilder(RouteBuilder.createRedirect(path, redirectTo, pathMatch));
|
|
23
|
+
}
|
|
24
|
+
addLazyRoute(path, loadChildren, canLoad) {
|
|
25
|
+
return this.addRouteBuilder(RouteBuilder.createLazyRoute(path, loadChildren, canLoad));
|
|
26
|
+
}
|
|
27
|
+
addRoute(path, component) {
|
|
28
|
+
return this.addRouteBuilder(RouteBuilder.create(path, component));
|
|
29
|
+
}
|
|
30
|
+
addTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
31
|
+
return this.addRouteBuilder(RouteBuilder.createTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails, hasEdit, hasAdd));
|
|
32
|
+
}
|
|
33
|
+
addTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
34
|
+
return this.addRouteBuilder(RouteBuilder.createTableviewRoutesFromComponent(path, component, hasDetails, hasEdit, hasAdd));
|
|
35
|
+
}
|
|
36
|
+
addRouteBuilder(routeBuilder) {
|
|
37
|
+
this.currentRoute = routeBuilder.withRoot(this);
|
|
38
|
+
this.routes.push(routeBuilder);
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
toRoute() {
|
|
42
|
+
if (!this.currentRoute) {
|
|
43
|
+
throw new Error('No routes were added!');
|
|
44
|
+
}
|
|
45
|
+
return this.currentRoute;
|
|
46
|
+
}
|
|
47
|
+
buildRoutes() {
|
|
48
|
+
let angularRoutes = [];
|
|
49
|
+
for (const route of this.routes) {
|
|
50
|
+
angularRoutes.push(route.buildRoute());
|
|
51
|
+
}
|
|
52
|
+
if (this.layoutRoute) {
|
|
53
|
+
const layoutAngularRoute = this.layoutRoute.buildRoute();
|
|
54
|
+
if (angularRoutes.length > 0) {
|
|
55
|
+
layoutAngularRoute.children = angularRoutes;
|
|
56
|
+
}
|
|
57
|
+
angularRoutes = [layoutAngularRoute];
|
|
58
|
+
}
|
|
59
|
+
return angularRoutes;
|
|
60
|
+
}
|
|
61
|
+
buildMenu() {
|
|
62
|
+
const menuItems = [];
|
|
63
|
+
for (const route of this.routes) {
|
|
64
|
+
menuItems.push(...route.buildMenu());
|
|
65
|
+
}
|
|
66
|
+
return menuItems.flat();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export class RouteBuilder {
|
|
70
|
+
constructor(route) {
|
|
71
|
+
this.routePath = [];
|
|
72
|
+
this.children = [];
|
|
73
|
+
this.menuItemChildren = [];
|
|
74
|
+
if (!route.data) {
|
|
75
|
+
route.data = {};
|
|
76
|
+
}
|
|
77
|
+
if (!route.data['breadcrumb']) {
|
|
78
|
+
route.data['breadcrumb'] = null;
|
|
79
|
+
}
|
|
80
|
+
this.route = route;
|
|
81
|
+
if (this.route.path && this.route.path.length > 0) {
|
|
82
|
+
this.routePath = [this.route.path];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
static create(path, component) {
|
|
86
|
+
return new RouteBuilder({
|
|
87
|
+
path: path,
|
|
88
|
+
component: component
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
static createRedirect(path, redirectTo, pathMatch = 'prefix') {
|
|
92
|
+
return new RouteBuilder({
|
|
93
|
+
path: path,
|
|
94
|
+
redirectTo: redirectTo,
|
|
95
|
+
pathMatch: pathMatch
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
static createLazyRoute(path, loadChildren, canLoad) {
|
|
99
|
+
const route = { path: path, loadChildren: loadChildren };
|
|
100
|
+
if (canLoad?.length) {
|
|
101
|
+
route.canLoad = canLoad;
|
|
102
|
+
}
|
|
103
|
+
return new RouteBuilder(route);
|
|
104
|
+
}
|
|
105
|
+
static createFromRoute(route) {
|
|
106
|
+
return new RouteBuilder(route);
|
|
107
|
+
}
|
|
108
|
+
static createLayoutRoute(path, layoutComponent = MngMainLayoutComponent, topbarComponent, breadcrumbComponent, menuComponent, footerComponent) {
|
|
109
|
+
const layoutRoute = RouteBuilder.create(path, layoutComponent);
|
|
110
|
+
if (topbarComponent || breadcrumbComponent || menuComponent || footerComponent) {
|
|
111
|
+
const dataBuilder = RouteDataBuilder.create();
|
|
112
|
+
if (topbarComponent) {
|
|
113
|
+
dataBuilder.withTopbarComponent(topbarComponent);
|
|
114
|
+
}
|
|
115
|
+
if (breadcrumbComponent) {
|
|
116
|
+
dataBuilder.withBreadcrumbComponent(breadcrumbComponent);
|
|
117
|
+
}
|
|
118
|
+
if (menuComponent) {
|
|
119
|
+
dataBuilder.withMenuComponent(menuComponent);
|
|
120
|
+
}
|
|
121
|
+
if (footerComponent) {
|
|
122
|
+
dataBuilder.withFooterComponent(footerComponent);
|
|
123
|
+
}
|
|
124
|
+
layoutRoute.withDataBuilder(dataBuilder);
|
|
125
|
+
}
|
|
126
|
+
return layoutRoute;
|
|
127
|
+
}
|
|
128
|
+
static createTableviewRoutes(path, descriptor, dataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
129
|
+
const tableviewRoute = RouteBuilder.createFromRoute({
|
|
130
|
+
data: RouteDataBuilder.create().withTableview(descriptor, dataProvider, actions).build(),
|
|
131
|
+
path: path,
|
|
132
|
+
component: MngTableviewRouteComponent
|
|
133
|
+
});
|
|
134
|
+
RouteBuilder.addActionsSubroutesToTableviewParent(tableviewRoute, hasDetails, hasEdit, hasAdd);
|
|
135
|
+
return tableviewRoute;
|
|
136
|
+
}
|
|
137
|
+
static createTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
138
|
+
const actionCrudRoute = RouteBuilder.create(path, component);
|
|
139
|
+
RouteBuilder.addActionsSubroutesToTableviewParent(actionCrudRoute, hasDetails, hasEdit, hasAdd);
|
|
140
|
+
return actionCrudRoute;
|
|
141
|
+
}
|
|
142
|
+
static addActionsSubroutesToTableviewParent(parentRoute, hasDetails, hasEdit, hasAdd) {
|
|
143
|
+
parentRoute.addChild('', MngActionRouteComponent);
|
|
144
|
+
if (hasAdd) {
|
|
145
|
+
parentRoute.addChild('add', MngActionRouteComponent);
|
|
146
|
+
}
|
|
147
|
+
if (hasDetails) {
|
|
148
|
+
parentRoute.addChild(':itemId', MngActionRouteComponent);
|
|
149
|
+
}
|
|
150
|
+
if (hasEdit) {
|
|
151
|
+
parentRoute.addChild(':itemId/edit', MngActionRouteComponent);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
withRoot(routesBuilder) {
|
|
155
|
+
this.root = routesBuilder;
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
withParent(parent) {
|
|
159
|
+
this.parent = parent;
|
|
160
|
+
this.routePath = RouteUtil.removeEmptyPathSegments([...this.parent.routePath, this.route.path ?? '']);
|
|
161
|
+
return this;
|
|
162
|
+
}
|
|
163
|
+
withBreadcrumb(breadcrumb) {
|
|
164
|
+
this.breadcrumb = breadcrumb;
|
|
165
|
+
this.route.data['breadcrumb'] = breadcrumb;
|
|
166
|
+
return this;
|
|
167
|
+
}
|
|
168
|
+
withPageTitle(pageTitle) {
|
|
169
|
+
this.pageTitle = pageTitle;
|
|
170
|
+
this.route.data['pageTitle'] = pageTitle;
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
withRedirectTo(redirectTo) {
|
|
174
|
+
this.route.redirectTo = redirectTo;
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
withPathMatch(pathMatch) {
|
|
178
|
+
this.route.pathMatch = pathMatch;
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
withTitle(title) {
|
|
182
|
+
this.withPageTitle(title);
|
|
183
|
+
this.withBreadcrumb(title);
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
withCanActivate(diToken) {
|
|
187
|
+
if (!this.route.canActivate) {
|
|
188
|
+
this.route.canActivate = [];
|
|
189
|
+
}
|
|
190
|
+
this.route.canActivate.push(diToken);
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
withCanDeactivate(diToken) {
|
|
194
|
+
if (!this.route.canDeactivate) {
|
|
195
|
+
this.route.canDeactivate = [];
|
|
196
|
+
}
|
|
197
|
+
this.route.canDeactivate.push(diToken);
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
withResolver(diToken, name) {
|
|
201
|
+
if (!this.route.resolve) {
|
|
202
|
+
this.route.resolve = {};
|
|
203
|
+
}
|
|
204
|
+
this.route.resolve[name] = diToken;
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
withData(data) {
|
|
208
|
+
this.route.data = data;
|
|
209
|
+
return this;
|
|
210
|
+
}
|
|
211
|
+
withDataBuilder(dataBuilder) {
|
|
212
|
+
this.route.data = dataBuilder.build();
|
|
213
|
+
return this;
|
|
214
|
+
}
|
|
215
|
+
withMngMenuItem(menuItem) {
|
|
216
|
+
this.menuItem = menuItem;
|
|
217
|
+
return this;
|
|
218
|
+
}
|
|
219
|
+
withMenuItem(icon, label, routerLink) {
|
|
220
|
+
this.menuItem = this.createMenuItem(icon, label, routerLink);
|
|
221
|
+
return this;
|
|
222
|
+
}
|
|
223
|
+
withMenuItemChild(label, icon, routerLink) {
|
|
224
|
+
this.menuItemChildren.push(this.createMenuItem(icon, label, routerLink));
|
|
225
|
+
return this;
|
|
226
|
+
}
|
|
227
|
+
withMenuItemChildren(routesBuilder) {
|
|
228
|
+
const menu = routesBuilder.buildMenu();
|
|
229
|
+
this.adjustMenuRouterLinksFromBuilder(menu);
|
|
230
|
+
this.menuItemChildren.push(...menu);
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
addChild(path, component) {
|
|
234
|
+
const childRouteBuilder = RouteBuilder.create(path, component);
|
|
235
|
+
this.addChildBuilder(childRouteBuilder);
|
|
236
|
+
return childRouteBuilder;
|
|
237
|
+
}
|
|
238
|
+
addChildBuilder(routeBuilder) {
|
|
239
|
+
routeBuilder.withParent(this);
|
|
240
|
+
if (this.root) {
|
|
241
|
+
routeBuilder.withRoot(this.root);
|
|
242
|
+
}
|
|
243
|
+
this.children.push(routeBuilder);
|
|
244
|
+
return this;
|
|
245
|
+
}
|
|
246
|
+
addTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
247
|
+
const routeBuilder = RouteBuilder.createTableviewRoutes(path, descriptor, tableviewDataProvider, actions, hasDetails, hasEdit, hasAdd);
|
|
248
|
+
this.addChildBuilder(routeBuilder);
|
|
249
|
+
return routeBuilder;
|
|
250
|
+
}
|
|
251
|
+
addTableviewRoutesFromComponent(path, component, hasDetails = true, hasEdit = true, hasAdd = true) {
|
|
252
|
+
const routeBuilder = RouteBuilder.createTableviewRoutesFromComponent(path, component, hasDetails, hasEdit, hasAdd);
|
|
253
|
+
this.addChildBuilder(routeBuilder);
|
|
254
|
+
return routeBuilder;
|
|
255
|
+
}
|
|
256
|
+
toParent() {
|
|
257
|
+
if (!this.parent) {
|
|
258
|
+
throw new Error('Parent was not provided.');
|
|
259
|
+
}
|
|
260
|
+
return this.parent;
|
|
261
|
+
}
|
|
262
|
+
toRoot() {
|
|
263
|
+
if (!this.root) {
|
|
264
|
+
throw new Error('Root was not provided.');
|
|
265
|
+
}
|
|
266
|
+
return this.root;
|
|
267
|
+
}
|
|
268
|
+
finish() {
|
|
269
|
+
return this.toRoot();
|
|
270
|
+
}
|
|
271
|
+
buildRoute() {
|
|
272
|
+
const angularRoute = {
|
|
273
|
+
...this.route
|
|
274
|
+
};
|
|
275
|
+
if ((this.route.children?.length ?? 0) > 0 || this.children.length > 0) {
|
|
276
|
+
// route has children
|
|
277
|
+
angularRoute.children = [];
|
|
278
|
+
if (this.route.children?.length) {
|
|
279
|
+
angularRoute.children.push(...this.route.children);
|
|
280
|
+
}
|
|
281
|
+
if (this.children.length) {
|
|
282
|
+
for (const childRoute of this.children) {
|
|
283
|
+
angularRoute.children.push(childRoute.buildRoute());
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (this.route.canActivate) {
|
|
288
|
+
angularRoute.canActivate = [...this.route.canActivate];
|
|
289
|
+
}
|
|
290
|
+
if (this.route.canActivateChild) {
|
|
291
|
+
angularRoute.canActivateChild = [...this.route.canActivateChild];
|
|
292
|
+
}
|
|
293
|
+
if (this.route.canLoad) {
|
|
294
|
+
angularRoute.canLoad = [...this.route.canLoad];
|
|
295
|
+
}
|
|
296
|
+
if (this.route.canDeactivate) {
|
|
297
|
+
angularRoute.canDeactivate = [...this.route.canDeactivate];
|
|
298
|
+
}
|
|
299
|
+
if (this.route.resolve) {
|
|
300
|
+
angularRoute.resolve = { ...this.route.resolve };
|
|
301
|
+
}
|
|
302
|
+
return angularRoute;
|
|
303
|
+
}
|
|
304
|
+
buildMenu() {
|
|
305
|
+
const menuItemBuild = this.menuItem ? { ...this.menuItem } : null;
|
|
306
|
+
const routeChildrenMenuItems = this.children.flatMap(child => child.buildMenu());
|
|
307
|
+
const menuItemChildren = [];
|
|
308
|
+
const menuItemChildrenBuild = [];
|
|
309
|
+
if (menuItemBuild?.items) {
|
|
310
|
+
menuItemChildrenBuild.push(...menuItemBuild.items);
|
|
311
|
+
}
|
|
312
|
+
for (const menuItemChild of this.menuItemChildren) {
|
|
313
|
+
const finalMenuItemChild = { ...menuItemChild };
|
|
314
|
+
if (!finalMenuItemChild.routerLink) {
|
|
315
|
+
finalMenuItemChild.routerLink = this.routePath;
|
|
316
|
+
}
|
|
317
|
+
if (typeof finalMenuItemChild.routerLink === 'string') {
|
|
318
|
+
finalMenuItemChild.routerLink = [finalMenuItemChild.routerLink];
|
|
319
|
+
}
|
|
320
|
+
finalMenuItemChild.routerLink = RouteUtil.removeEmptyPathSegments(finalMenuItemChild.routerLink);
|
|
321
|
+
menuItemChildren.push(finalMenuItemChild);
|
|
322
|
+
}
|
|
323
|
+
menuItemChildrenBuild.push(...menuItemChildren, ...routeChildrenMenuItems);
|
|
324
|
+
if (!menuItemBuild) {
|
|
325
|
+
return menuItemChildrenBuild;
|
|
326
|
+
}
|
|
327
|
+
menuItemBuild.label = menuItemBuild.label ?? this.pageTitle;
|
|
328
|
+
if (typeof menuItemBuild.routerLink === 'string') {
|
|
329
|
+
menuItemBuild.routerLink = [menuItemBuild.routerLink];
|
|
330
|
+
}
|
|
331
|
+
menuItemBuild.routerLink = RouteUtil.removeEmptyPathSegments(menuItemBuild.routerLink ?? this.routePath);
|
|
332
|
+
if (menuItemChildrenBuild.length > 0) {
|
|
333
|
+
menuItemBuild.items = menuItemChildrenBuild;
|
|
334
|
+
}
|
|
335
|
+
if (!menuItemBuild.guards) {
|
|
336
|
+
const guards = this.findMenuItemGuards();
|
|
337
|
+
if (guards.length > 0) {
|
|
338
|
+
menuItemBuild.guards = guards;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return [menuItemBuild];
|
|
342
|
+
}
|
|
343
|
+
createMenuItem(icon, label, routerLink) {
|
|
344
|
+
const menuItem = {};
|
|
345
|
+
if (icon) {
|
|
346
|
+
menuItem.icon = icon;
|
|
347
|
+
}
|
|
348
|
+
if (label) {
|
|
349
|
+
menuItem.label = label;
|
|
350
|
+
}
|
|
351
|
+
if (routerLink) {
|
|
352
|
+
menuItem.routerLink = routerLink;
|
|
353
|
+
}
|
|
354
|
+
return menuItem;
|
|
355
|
+
}
|
|
356
|
+
adjustMenuRouterLinksFromBuilder(menuItems) {
|
|
357
|
+
for (const menuItem of menuItems) {
|
|
358
|
+
if (menuItem.routerLink) {
|
|
359
|
+
menuItem.routerLink = RouteUtil.appendPathToBasePath(this.routePath, typeof menuItem.routerLink === 'string' ? [menuItem.routerLink] : menuItem.routerLink);
|
|
360
|
+
}
|
|
361
|
+
if (Array.isArray(menuItem.items)) {
|
|
362
|
+
this.adjustMenuRouterLinksFromBuilder(menuItem.items);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
findMenuItemGuards() {
|
|
367
|
+
const guards = [];
|
|
368
|
+
if (this.route.canActivate?.length) {
|
|
369
|
+
guards.push(...this.route.canActivate);
|
|
370
|
+
}
|
|
371
|
+
if (this.parent) {
|
|
372
|
+
// Check for parent guards that should be included in decision to hide menu item!
|
|
373
|
+
// Some parent routes might have guards, but no menu items, so this guards must be taken into account here,
|
|
374
|
+
// because there is no parent menu item to hide.
|
|
375
|
+
this.parent.findMenuItemGuards().forEach(g => {
|
|
376
|
+
if (guards.indexOf(g) < 0) {
|
|
377
|
+
guards.push(g);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
return guards;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
export class RouteDataBuilder {
|
|
385
|
+
constructor(init) {
|
|
386
|
+
this.data = init ?? {};
|
|
387
|
+
if (!this.data.breadcrumb) {
|
|
388
|
+
this.data.breadcrumb = null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
static create(data) {
|
|
392
|
+
return new RouteDataBuilder(data);
|
|
393
|
+
}
|
|
394
|
+
withBreadcrumb(breadcrumb) {
|
|
395
|
+
this.data.breadcrumb = breadcrumb;
|
|
396
|
+
return this;
|
|
397
|
+
}
|
|
398
|
+
withPageTitle(pageTitle) {
|
|
399
|
+
this.data.pageTitle = pageTitle;
|
|
400
|
+
return this;
|
|
401
|
+
}
|
|
402
|
+
withTableview(descriptor, dataProvider, actions) {
|
|
403
|
+
this.data.tableview = {
|
|
404
|
+
descriptor: descriptor,
|
|
405
|
+
dataProvider: dataProvider
|
|
406
|
+
};
|
|
407
|
+
if (actions) {
|
|
408
|
+
this.data.tableview.actions = actions;
|
|
409
|
+
}
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
withTopbarComponent(component) {
|
|
413
|
+
this.data.topbarComponent = component;
|
|
414
|
+
return this;
|
|
415
|
+
}
|
|
416
|
+
withBreadcrumbComponent(component) {
|
|
417
|
+
this.data.breadcrumbComponent = component;
|
|
418
|
+
return this;
|
|
419
|
+
}
|
|
420
|
+
withMenuComponent(component) {
|
|
421
|
+
this.data.menuComponent = component;
|
|
422
|
+
return this;
|
|
423
|
+
}
|
|
424
|
+
withFooterComponent(component) {
|
|
425
|
+
this.data.footerComponent = component;
|
|
426
|
+
return this;
|
|
427
|
+
}
|
|
428
|
+
build() {
|
|
429
|
+
return this.data;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
432
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUtYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcm91dGVyL3JvdXRlLWJ1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDN0QsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFDLDBCQUEwQixFQUFDLE1BQU0seUJBQXlCLENBQUM7QUFJbkUsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBRzlDLE1BQU0sT0FBTyxhQUFhO0lBS3RCLFlBQW9CLFdBQTBCO1FBSHRDLFdBQU0sR0FBd0IsRUFBRSxDQUFDO1FBSXJDLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQztJQUNwQyxDQUFDO0lBRU0sTUFBTSxDQUFDLE1BQU07UUFDaEIsT0FBTyxJQUFJLGFBQWEsRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFTSxNQUFNLENBQUMsZ0JBQWdCLENBQzFCLGVBQWUsR0FBRyxzQkFBc0IsRUFDeEMsZUFBMkIsRUFDM0IsbUJBQStCLEVBQy9CLGFBQXlCLEVBQ3pCLGVBQTJCO1FBRTNCLE1BQU0sV0FBVyxHQUFHLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDOUksT0FBTyxJQUFJLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRU0sZUFBZSxDQUFDLEtBQVk7UUFDL0IsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRU0sZ0JBQWdCLENBQUMsSUFBWSxFQUFFLFVBQWtCLEVBQUUsWUFBK0IsUUFBUTtRQUM3RixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDMUYsQ0FBQztJQUVNLFlBQVksQ0FBQyxJQUFZLEVBQUUsWUFBMEIsRUFBRSxPQUFvQjtRQUM5RSxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDM0YsQ0FBQztJQUVNLFFBQVEsQ0FBQyxJQUFZLEVBQUUsU0FBb0I7UUFDOUMsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVNLGtCQUFrQixDQUNyQixJQUFZLEVBQ1osVUFBa0MsRUFDbEMscUJBQW1ELEVBQ25ELE9BQW9DLEVBQ3BDLFVBQVUsR0FBRyxJQUFJLEVBQ2pCLE9BQU8sR0FBRyxJQUFJLEVBQ2QsTUFBTSxHQUFHLElBQUk7UUFFYixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUscUJBQXFCLEVBQUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNuSixDQUFDO0lBRU0sK0JBQStCLENBQUMsSUFBWSxFQUFFLFNBQW9CLEVBQUUsVUFBVSxHQUFHLElBQUksRUFBRSxPQUFPLEdBQUcsSUFBSSxFQUFFLE1BQU0sR0FBRyxJQUFJO1FBQ3ZILE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUMsa0NBQWtDLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDL0gsQ0FBQztJQUVNLGVBQWUsQ0FBQyxZQUEwQjtRQUM3QyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDaEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDL0IsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVNLE9BQU87UUFDVixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNwQixNQUFNLElBQUksS0FBSyxDQUFDLHVCQUF1QixDQUFDLENBQUM7U0FDNUM7UUFDRCxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDN0IsQ0FBQztJQUVNLFdBQVc7UUFDZCxJQUFJLGFBQWEsR0FBVyxFQUFFLENBQUM7UUFDL0IsS0FBSyxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQzdCLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7U0FDMUM7UUFFRCxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDbEIsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3pELElBQUksYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzFCLGtCQUFrQixDQUFDLFFBQVEsR0FBRyxhQUFhLENBQUM7YUFDL0M7WUFDRCxhQUFhLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1NBQ3hDO1FBRUQsT0FBTyxhQUFhLENBQUM7SUFDekIsQ0FBQztJQUVNLFNBQVM7UUFDWixNQUFNLFNBQVMsR0FBdUIsRUFBRSxDQUFDO1FBQ3pDLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUM3QixTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7U0FDeEM7UUFDRCxPQUFPLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM1QixDQUFDO0NBQ0o7QUFFRCxNQUFNLE9BQU8sWUFBWTtJQVlyQixZQUFvQixLQUFZO1FBVnhCLGNBQVMsR0FBa0IsRUFBRSxDQUFDO1FBRzlCLGFBQVEsR0FBd0IsRUFBRSxDQUFDO1FBRW5DLHFCQUFnQixHQUF1QixFQUFFLENBQUM7UUFNOUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUU7WUFDYixLQUFLLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztTQUNuQjtRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFO1lBQzNCLEtBQUssQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsSUFBSSxDQUFDO1NBQ25DO1FBQ0QsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQy9DLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3RDO0lBQ0wsQ0FBQztJQUVNLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBWSxFQUFFLFNBQW9CO1FBQ25ELE9BQU8sSUFBSSxZQUFZLENBQUM7WUFDcEIsSUFBSSxFQUFFLElBQUk7WUFDVixTQUFTLEVBQUUsU0FBUztTQUN2QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFZLEVBQUUsVUFBa0IsRUFBRSxZQUErQixRQUFRO1FBQ2xHLE9BQU8sSUFBSSxZQUFZLENBQUM7WUFDcEIsSUFBSSxFQUFFLElBQUk7WUFDVixVQUFVLEVBQUUsVUFBVTtZQUN0QixTQUFTLEVBQUUsU0FBUztTQUN2QixDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU0sTUFBTSxDQUFDLGVBQWUsQ0FBQyxJQUFZLEVBQUUsWUFBMEIsRUFBRSxPQUFvQjtRQUN4RixNQUFNLEtBQUssR0FBVSxFQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBQyxDQUFDO1FBQzlELElBQUksT0FBTyxFQUFFLE1BQU0sRUFBRTtZQUNqQixLQUFLLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztTQUMzQjtRQUNELE9BQU8sSUFBSSxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVNLE1BQU0sQ0FBQyxlQUFlLENBQUMsS0FBWTtRQUN0QyxPQUFPLElBQUksWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFTSxNQUFNLENBQUMsaUJBQWlCLENBQzNCLElBQVksRUFDWixlQUFlLEdBQUcsc0JBQXNCLEVBQ3hDLGVBQTJCLEVBQzNCLG1CQUErQixFQUMvQixhQUF5QixFQUN6QixlQUEyQjtRQUUzQixNQUFNLFdBQVcsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxlQUFlLENBQUMsQ0FBQztRQUMvRCxJQUFJLGVBQWUsSUFBSSxtQkFBbUIsSUFBSSxhQUFhLElBQUksZUFBZSxFQUFFO1lBQzVFLE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzlDLElBQUksZUFBZSxFQUFFO2dCQUNqQixXQUFXLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7YUFDcEQ7WUFDRCxJQUFJLG1CQUFtQixFQUFFO2dCQUNyQixXQUFXLENBQUMsdUJBQXVCLENBQUMsbUJBQW1CLENBQUMsQ0FBQzthQUM1RDtZQUNELElBQUksYUFBYSxFQUFFO2dCQUNmLFdBQVcsQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUNoRDtZQUNELElBQUksZUFBZSxFQUFFO2dCQUNqQixXQUFXLENBQUMsbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7YUFDcEQ7WUFDRCxXQUFXLENBQUMsZUFBZSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQzVDO1FBQ0QsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVNLE1BQU0sQ0FBQyxxQkFBcUIsQ0FDL0IsSUFBWSxFQUNaLFVBQWtDLEVBQ2xDLFlBQTBDLEVBQzFDLE9BQW9DLEVBQ3BDLFVBQVUsR0FBRyxJQUFJLEVBQ2pCLE9BQU8sR0FBRyxJQUFJLEVBQ2QsTUFBTSxHQUFHLElBQUk7UUFFYixNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsZUFBZSxDQUFDO1lBQ2hELElBQUksRUFBRSxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxFQUFFLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUU7WUFDeEYsSUFBSSxFQUFFLElBQUk7WUFDVixTQUFTLEVBQUUsMEJBQTBCO1NBQ3hDLENBQUMsQ0FBQztRQUNILFlBQVksQ0FBQyxvQ0FBb0MsQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvRixPQUFPLGNBQWMsQ0FBQztJQUMxQixDQUFDO0lBRU0sTUFBTSxDQUFDLGtDQUFrQyxDQUFDLElBQVksRUFBRSxTQUFvQixFQUFFLFVBQVUsR0FBRyxJQUFJLEVBQUUsT0FBTyxHQUFHLElBQUksRUFBRSxNQUFNLEdBQUcsSUFBSTtRQUNqSSxNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztRQUM3RCxZQUFZLENBQUMsb0NBQW9DLENBQUMsZUFBZSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEcsT0FBTyxlQUFlLENBQUM7SUFDM0IsQ0FBQztJQUVPLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxXQUF5QixFQUFFLFVBQW1CLEVBQUUsT0FBZ0IsRUFBRSxNQUFlO1FBQ2pJLFdBQVcsQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLHVCQUF1QixDQUFDLENBQUM7UUFFbEQsSUFBSSxNQUFNLEVBQUU7WUFDUixXQUFXLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1NBQ3hEO1FBQ0QsSUFBSSxVQUFVLEVBQUU7WUFDWixXQUFXLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1NBQzVEO1FBQ0QsSUFBSSxPQUFPLEVBQUU7WUFDVCxXQUFXLENBQUMsUUFBUSxDQUFDLGNBQWMsRUFBRSx1QkFBdUIsQ0FBQyxDQUFDO1NBQ2pFO0lBQ0wsQ0FBQztJQUVELFFBQVEsQ0FBQyxhQUE0QjtRQUNqQyxJQUFJLENBQUMsSUFBSSxHQUFHLGFBQWEsQ0FBQztRQUMxQixPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsVUFBVSxDQUFDLE1BQW9CO1FBQzNCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDLHVCQUF1QixDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxjQUFjLENBQUMsVUFBMEI7UUFDckMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsVUFBVSxDQUFDO1FBQzVDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxhQUFhLENBQUMsU0FBaUI7UUFDM0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsU0FBUyxDQUFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxjQUFjLENBQUMsVUFBa0I7UUFDN0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO1FBQ25DLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxhQUFhLENBQUMsU0FBNEI7UUFDdEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNuQixJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0IsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELGVBQWUsQ0FBQyxPQUFZO1FBQ3hCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRTtZQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7U0FDL0I7UUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELGlCQUFpQixDQUFDLE9BQVk7UUFDMUIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQztTQUNqQztRQUNELElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2QyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsWUFBWSxDQUFDLE9BQVksRUFBRSxJQUFZO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNyQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7U0FDM0I7UUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxPQUFPLENBQUM7UUFDbkMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELFFBQVEsQ0FBQyxJQUFTO1FBQ2QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxlQUFlLENBQUMsV0FBNkI7UUFDekMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxlQUFlLENBQUMsUUFBcUI7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELFlBQVksQ0FBQyxJQUFhLEVBQUUsS0FBYyxFQUFFLFVBQTBCO1FBQ2xFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxLQUFhLEVBQUUsSUFBYSxFQUFFLFVBQTBCO1FBQ3RFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDekUsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELG9CQUFvQixDQUFDLGFBQTRCO1FBQzdDLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsZ0NBQWdDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQ3BDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFTSxRQUFRLENBQUMsSUFBWSxFQUFFLFNBQW9CO1FBQzlDLE1BQU0saUJBQWlCLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8saUJBQWlCLENBQUM7SUFDN0IsQ0FBQztJQUVNLGVBQWUsQ0FBQyxZQUEwQjtRQUM3QyxZQUFZLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzlCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtZQUNYLFlBQVksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3BDO1FBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDakMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVNLGtCQUFrQixDQUNyQixJQUFZLEVBQ1osVUFBa0MsRUFDbEMscUJBQW1ELEVBQ25ELE9BQW9DLEVBQ3BDLFVBQVUsR0FBRyxJQUFJLEVBQ2pCLE9BQU8sR0FBRyxJQUFJLEVBQ2QsTUFBTSxHQUFHLElBQUk7UUFFYixNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMscUJBQXFCLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRSxxQkFBcUIsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUN2SSxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ25DLE9BQU8sWUFBWSxDQUFDO0lBQ3hCLENBQUM7SUFFTSwrQkFBK0IsQ0FBQyxJQUFZLEVBQUUsU0FBb0IsRUFBRSxVQUFVLEdBQUcsSUFBSSxFQUFFLE9BQU8sR0FBRyxJQUFJLEVBQUUsTUFBTSxHQUFHLElBQUk7UUFDdkgsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLGtDQUFrQyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNuSCxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ25DLE9BQU8sWUFBWSxDQUFDO0lBQ3hCLENBQUM7SUFFTSxRQUFRO1FBQ1gsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDZCxNQUFNLElBQUksS0FBSyxDQUFDLDBCQUEwQixDQUFDLENBQUM7U0FDL0M7UUFDRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUM7SUFDdkIsQ0FBQztJQUVNLE1BQU07UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNaLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztTQUM3QztRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyQixDQUFDO0lBRU0sTUFBTTtRQUNULE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTSxVQUFVO1FBQ2IsTUFBTSxZQUFZLEdBQVU7WUFDeEIsR0FBRyxJQUFJLENBQUMsS0FBSztTQUNoQixDQUFDO1FBRUYsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3BFLHFCQUFxQjtZQUNyQixZQUFZLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztZQUMzQixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRTtnQkFDN0IsWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQ3REO1lBQ0QsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRTtnQkFDdEIsS0FBSyxNQUFNLFVBQVUsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO29CQUNwQyxZQUFZLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQztpQkFDdkQ7YUFDSjtTQUNKO1FBRUQsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRTtZQUN4QixZQUFZLENBQUMsV0FBVyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFDO1NBQzFEO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFO1lBQzdCLFlBQVksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1NBQ3BFO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNwQixZQUFZLENBQUMsT0FBTyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ2xEO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRTtZQUMxQixZQUFZLENBQUMsYUFBYSxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1NBQzlEO1FBQ0QsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRTtZQUNwQixZQUFZLENBQUMsT0FBTyxHQUFHLEVBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBQyxDQUFDO1NBQ2xEO1FBRUQsT0FBTyxZQUFZLENBQUM7SUFDeEIsQ0FBQztJQUVNLFNBQVM7UUFDWixNQUFNLGFBQWEsR0FBdUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBQyxHQUFHLElBQUksQ0FBQyxRQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ3BGLE1BQU0sc0JBQXNCLEdBQXVCLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDckcsTUFBTSxnQkFBZ0IsR0FBdUIsRUFBRSxDQUFDO1FBQ2hELE1BQU0scUJBQXFCLEdBQXVCLEVBQUUsQ0FBQztRQUVyRCxJQUFJLGFBQWEsRUFBRSxLQUFLLEVBQUU7WUFDdEIscUJBQXFCLENBQUMsSUFBSSxDQUFDLEdBQUcsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQ3REO1FBRUQsS0FBSyxNQUFNLGFBQWEsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUU7WUFDL0MsTUFBTSxrQkFBa0IsR0FBZ0IsRUFBQyxHQUFHLGFBQWEsRUFBQyxDQUFDO1lBQzNELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLEVBQUU7Z0JBQ2hDLGtCQUFrQixDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO2FBQ2xEO1lBQ0QsSUFBSSxPQUFPLGtCQUFrQixDQUFDLFVBQVUsS0FBSyxRQUFRLEVBQUU7Z0JBQ25ELGtCQUFrQixDQUFDLFVBQVUsR0FBRyxDQUFDLGtCQUFrQixDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ25FO1lBQ0Qsa0JBQWtCLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyx1QkFBdUIsQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQztZQUNqRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztTQUM3QztRQUVELHFCQUFxQixDQUFDLElBQUksQ0FBQyxHQUFHLGdCQUFnQixFQUFFLEdBQUcsc0JBQXNCLENBQUMsQ0FBQztRQUUzRSxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ2hCLE9BQU8scUJBQXFCLENBQUM7U0FDaEM7UUFFRCxhQUFhLENBQUMsS0FBSyxHQUFHLGFBQWEsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM1RCxJQUFJLE9BQU8sYUFBYSxDQUFDLFVBQVUsS0FBSyxRQUFRLEVBQUU7WUFDOUMsYUFBYSxDQUFDLFVBQVUsR0FBRyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUN6RDtRQUNELGFBQWEsQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pHLElBQUkscUJBQXFCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNsQyxhQUFhLENBQUMsS0FBSyxHQUFHLHFCQUFxQixDQUFDO1NBQy9DO1FBRUQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUU7WUFDdkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDekMsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtnQkFDbkIsYUFBYSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7YUFDakM7U0FDSjtRQUVELE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRU8sY0FBYyxDQUFDLElBQWEsRUFBRSxLQUFjLEVBQUUsVUFBMEI7UUFDNUUsTUFBTSxRQUFRLEdBQWdCLEVBQUUsQ0FBQztRQUNqQyxJQUFJLElBQUksRUFBRTtZQUNOLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1NBQ3hCO1FBQ0QsSUFBSSxLQUFLLEVBQUU7WUFDUCxRQUFRLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztTQUMxQjtRQUNELElBQUksVUFBVSxFQUFFO1lBQ1osUUFBUSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7U0FDcEM7UUFDRCxPQUFPLFFBQVEsQ0FBQztJQUNwQixDQUFDO0lBRU8sZ0NBQWdDLENBQUMsU0FBNkI7UUFDbEUsS0FBSyxNQUFNLFFBQVEsSUFBSSxTQUFTLEVBQUU7WUFDOUIsSUFBSSxRQUFRLENBQUMsVUFBVSxFQUFFO2dCQUNyQixRQUFRLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLE9BQU8sUUFBUSxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDL0o7WUFDRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxFQUFFO2dCQUMvQixJQUFJLENBQUMsZ0NBQWdDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3pEO1NBQ0o7SUFDTCxDQUFDO0lBRU8sa0JBQWtCO1FBQ3RCLE1BQU0sTUFBTSxHQUFlLEVBQUUsQ0FBQztRQUM5QixJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFLE1BQU0sRUFBRTtZQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQztTQUMxQztRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLGlGQUFpRjtZQUNqRiwyR0FBMkc7WUFDM0csZ0RBQWdEO1lBQ2hELElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3pDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUU7b0JBQ3ZCLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7aUJBQ2xCO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDTjtRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2xCLENBQUM7Q0FDSjtBQUVELE1BQU0sT0FBTyxnQkFBZ0I7SUFHekIsWUFBWSxJQUFXO1FBQ25CLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1NBQy9CO0lBQ0wsQ0FBQztJQUVNLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBVztRQUM1QixPQUFPLElBQUksZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdEMsQ0FBQztJQUVELGNBQWMsQ0FBQyxVQUEwQjtRQUNyQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDbEMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELGFBQWEsQ0FBQyxTQUFpQjtRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDaEMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELGFBQWEsQ0FBQyxVQUFvQyxFQUFFLFlBQThDLEVBQUUsT0FBc0M7UUFDdEksSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDbEIsVUFBVSxFQUFFLFVBQVU7WUFDdEIsWUFBWSxFQUFFLFlBQVk7U0FDN0IsQ0FBQztRQUNGLElBQUksT0FBTyxFQUFFO1lBQ1QsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztTQUN6QztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxTQUFvQjtRQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUM7UUFDdEMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELHVCQUF1QixDQUFDLFNBQW9CO1FBQ3hDLElBQUksQ0FBQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDO1FBQzFDLE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxTQUFvQjtRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxTQUFTLENBQUM7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDaEIsQ0FBQztJQUVELG1CQUFtQixDQUFDLFNBQW9CO1FBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxHQUFHLFNBQVMsQ0FBQztRQUN0QyxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsS0FBSztRQUNELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQztJQUNyQixDQUFDO0NBQ0oiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1R5cGV9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtEYXRhLCBMb2FkQ2hpbGRyZW4sIFJvdXRlLCBSb3V0ZXN9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7TW5nQWN0aW9uUm91dGVDb21wb25lbnR9IGZyb20gJy4uL2NvbXBvbmVudHMvYWN0aW9uJztcbmltcG9ydCB7TW5nTWFpbkxheW91dENvbXBvbmVudH0gZnJvbSAnLi4vY29tcG9uZW50cy9sYXlvdXQnO1xuaW1wb3J0IHtNbmdUYWJsZXZpZXdSb3V0ZUNvbXBvbmVudH0gZnJvbSAnLi4vY29tcG9uZW50cy90YWJsZXZpZXcnO1xuaW1wb3J0IHtJVGFibGV2aWV3RGF0YVByb3ZpZGVyfSBmcm9tICcuLi9kYXRhLXByb3ZpZGVycyc7XG5pbXBvcnQge0FjdGlvbkRlc2NyaXB0b3IsIFRhYmxldmlld0Rlc2NyaXB0b3J9IGZyb20gJy4uL2Rlc2NyaXB0b3JzJztcbmltcG9ydCB7TW5nTWVudUl0ZW19IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQge1JvdXRlVXRpbH0gZnJvbSAnLi4vdXRpbHMvcm91dGUudXRpbCc7XG5pbXBvcnQge0JyZWFkY3J1bWJUeXBlLCBNbmdSb3V0ZXJEYXRhfSBmcm9tICcuL21vZGVscyc7XG5cbmV4cG9ydCBjbGFzcyBSb3V0ZXNCdWlsZGVyIHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IGxheW91dFJvdXRlPzogUm91dGVCdWlsZGVyO1xuICAgIHByaXZhdGUgcm91dGVzOiBBcnJheTxSb3V0ZUJ1aWxkZXI+ID0gW107XG4gICAgcHJpdmF0ZSBjdXJyZW50Um91dGU/OiBSb3V0ZUJ1aWxkZXI7XG5cbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKGxheW91dFJvdXRlPzogUm91dGVCdWlsZGVyKSB7XG4gICAgICAgIHRoaXMubGF5b3V0Um91dGUgPSBsYXlvdXRSb3V0ZT8ud2l0aFJvb3QodGhpcyk7XG4gICAgICAgIHRoaXMuY3VycmVudFJvdXRlID0gbGF5b3V0Um91dGU7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGUoKTogUm91dGVzQnVpbGRlciB7XG4gICAgICAgIHJldHVybiBuZXcgUm91dGVzQnVpbGRlcigpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlV2l0aExheW91dChcbiAgICAgICAgbGF5b3V0Q29tcG9uZW50ID0gTW5nTWFpbkxheW91dENvbXBvbmVudCxcbiAgICAgICAgdG9wYmFyQ29tcG9uZW50PzogVHlwZTxhbnk+LFxuICAgICAgICBicmVhZGNydW1iQ29tcG9uZW50PzogVHlwZTxhbnk+LFxuICAgICAgICBtZW51Q29tcG9uZW50PzogVHlwZTxhbnk+LFxuICAgICAgICBmb290ZXJDb21wb25lbnQ/OiBUeXBlPGFueT5cbiAgICApOiBSb3V0ZXNCdWlsZGVyIHtcbiAgICAgICAgY29uc3QgbGF5b3V0Um91dGUgPSBSb3V0ZUJ1aWxkZXIuY3JlYXRlTGF5b3V0Um91dGUoJycsIGxheW91dENvbXBvbmVudCwgdG9wYmFyQ29tcG9uZW50LCBicmVhZGNydW1iQ29tcG9uZW50LCBtZW51Q29tcG9uZW50LCBmb290ZXJDb21wb25lbnQpO1xuICAgICAgICByZXR1cm4gbmV3IFJvdXRlc0J1aWxkZXIobGF5b3V0Um91dGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRBbmd1bGFyUm91dGUocm91dGU6IFJvdXRlKTogdGhpcyB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFJvdXRlQnVpbGRlcihSb3V0ZUJ1aWxkZXIuY3JlYXRlRnJvbVJvdXRlKHJvdXRlKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFJvdXRlUmVkaXJlY3QocGF0aDogc3RyaW5nLCByZWRpcmVjdFRvOiBzdHJpbmcsIHBhdGhNYXRjaDogJ2Z1bGwnIHwgJ3ByZWZpeCcgPSAncHJlZml4Jyk6IHRoaXMge1xuICAgICAgICByZXR1cm4gdGhpcy5hZGRSb3V0ZUJ1aWxkZXIoUm91dGVCdWlsZGVyLmNyZWF0ZVJlZGlyZWN0KHBhdGgsIHJlZGlyZWN0VG8sIHBhdGhNYXRjaCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRMYXp5Um91dGUocGF0aDogc3RyaW5nLCBsb2FkQ2hpbGRyZW46IExvYWRDaGlsZHJlbiwgY2FuTG9hZD86IEFycmF5PGFueT4pOiB0aGlzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkUm91dGVCdWlsZGVyKFJvdXRlQnVpbGRlci5jcmVhdGVMYXp5Um91dGUocGF0aCwgbG9hZENoaWxkcmVuLCBjYW5Mb2FkKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFJvdXRlKHBhdGg6IHN0cmluZywgY29tcG9uZW50OiBUeXBlPGFueT4pOiB0aGlzIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWRkUm91dGVCdWlsZGVyKFJvdXRlQnVpbGRlci5jcmVhdGUocGF0aCwgY29tcG9uZW50KSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFRhYmxldmlld1JvdXRlczxULCBTPihcbiAgICAgICAgcGF0aDogc3RyaW5nLFxuICAgICAgICBkZXNjcmlwdG9yOiBUYWJsZXZpZXdEZXNjcmlwdG9yPFQ+LFxuICAgICAgICB0YWJsZXZpZXdEYXRhUHJvdmlkZXI6IElUYWJsZXZpZXdEYXRhUHJvdmlkZXI8VCwgUz4sXG4gICAgICAgIGFjdGlvbnM/OiBBcnJheTxBY3Rpb25EZXNjcmlwdG9yPFQ+PixcbiAgICAgICAgaGFzRGV0YWlscyA9IHRydWUsXG4gICAgICAgIGhhc0VkaXQgPSB0cnVlLFxuICAgICAgICBoYXNBZGQgPSB0cnVlXG4gICAgKTogdGhpcyB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFJvdXRlQnVpbGRlcihSb3V0ZUJ1aWxkZXIuY3JlYXRlVGFibGV2aWV3Um91dGVzKHBhdGgsIGRlc2NyaXB0b3IsIHRhYmxldmlld0RhdGFQcm92aWRlciwgYWN0aW9ucywgaGFzRGV0YWlscywgaGFzRWRpdCwgaGFzQWRkKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZFRhYmxldmlld1JvdXRlc0Zyb21Db21wb25lbnQocGF0aDogc3RyaW5nLCBjb21wb25lbnQ6IFR5cGU8YW55PiwgaGFzRGV0YWlscyA9IHRydWUsIGhhc0VkaXQgPSB0cnVlLCBoYXNBZGQgPSB0cnVlKTogdGhpcyB7XG4gICAgICAgIHJldHVybiB0aGlzLmFkZFJvdXRlQnVpbGRlcihSb3V0ZUJ1aWxkZXIuY3JlYXRlVGFibGV2aWV3Um91dGVzRnJvbUNvbXBvbmVudChwYXRoLCBjb21wb25lbnQsIGhhc0RldGFpbHMsIGhhc0VkaXQsIGhhc0FkZCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRSb3V0ZUJ1aWxkZXIocm91dGVCdWlsZGVyOiBSb3V0ZUJ1aWxkZXIpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5jdXJyZW50Um91dGUgPSByb3V0ZUJ1aWxkZXIud2l0aFJvb3QodGhpcyk7XG4gICAgICAgIHRoaXMucm91dGVzLnB1c2gocm91dGVCdWlsZGVyKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcHVibGljIHRvUm91dGUoKTogUm91dGVCdWlsZGVyIHtcbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRSb3V0ZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdObyByb3V0ZXMgd2VyZSBhZGRlZCEnKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50Um91dGU7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkUm91dGVzKCk6IFJvdXRlcyB7XG4gICAgICAgIGxldCBhbmd1bGFyUm91dGVzOiBSb3V0ZXMgPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCByb3V0ZSBvZiB0aGlzLnJvdXRlcykge1xuICAgICAgICAgICAgYW5ndWxhclJvdXRlcy5wdXNoKHJvdXRlLmJ1aWxkUm91dGUoKSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5sYXlvdXRSb3V0ZSkge1xuICAgICAgICAgICAgY29uc3QgbGF5b3V0QW5ndWxhclJvdXRlID0gdGhpcy5sYXlvdXRSb3V0ZS5idWlsZFJvdXRlKCk7XG4gICAgICAgICAgICBpZiAoYW5ndWxhclJvdXRlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbGF5b3V0QW5ndWxhclJvdXRlLmNoaWxkcmVuID0gYW5ndWxhclJvdXRlcztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGFuZ3VsYXJSb3V0ZXMgPSBbbGF5b3V0QW5ndWxhclJvdXRlXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhbmd1bGFyUm91dGVzO1xuICAgIH1cblxuICAgIHB1YmxpYyBidWlsZE1lbnUoKTogQXJyYXk8TW5nTWVudUl0ZW0+IHtcbiAgICAgICAgY29uc3QgbWVudUl0ZW1zOiBBcnJheTxNbmdNZW51SXRlbT4gPSBbXTtcbiAgICAgICAgZm9yIChjb25zdCByb3V0ZSBvZiB0aGlzLnJvdXRlcykge1xuICAgICAgICAgICAgbWVudUl0ZW1zLnB1c2goLi4ucm91dGUuYnVpbGRNZW51KCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBtZW51SXRlbXMuZmxhdCgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNsYXNzIFJvdXRlQnVpbGRlciB7XG4gICAgcHJpdmF0ZSByZWFkb25seSByb3V0ZTogUm91dGU7XG4gICAgcHJpdmF0ZSByb3V0ZVBhdGg6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgICBwcml2YXRlIHJvb3Q/OiBSb3V0ZXNCdWlsZGVyO1xuICAgIHByaXZhdGUgcGFyZW50PzogUm91dGVCdWlsZGVyO1xuICAgIHByaXZhdGUgY2hpbGRyZW46IEFycmF5PFJvdXRlQnVpbGRlcj4gPSBbXTtcbiAgICBwcml2YXRlIG1lbnVJdGVtPzogTW5nTWVudUl0ZW07XG4gICAgcHJpdmF0ZSBtZW51SXRlbUNoaWxkcmVuOiBBcnJheTxNbmdNZW51SXRlbT4gPSBbXTtcblxuICAgIHByaXZhdGUgYnJlYWRjcnVtYj86IEJyZWFkY3J1bWJUeXBlO1xuICAgIHByaXZhdGUgcGFnZVRpdGxlPzogc3RyaW5nO1xuXG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihyb3V0ZTogUm91dGUpIHtcbiAgICAgICAgaWYgKCFyb3V0ZS5kYXRhKSB7XG4gICAgICAgICAgICByb3V0ZS5kYXRhID0ge307XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyb3V0ZS5kYXRhWydicmVhZGNydW1iJ10pIHtcbiAgICAgICAgICAgIHJvdXRlLmRhdGFbJ2JyZWFkY3J1bWInXSA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5yb3V0ZSA9IHJvdXRlO1xuICAgICAgICBpZiAodGhpcy5yb3V0ZS5wYXRoICYmIHRoaXMucm91dGUucGF0aC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLnJvdXRlUGF0aCA9IFt0aGlzLnJvdXRlLnBhdGhdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGUocGF0aDogc3RyaW5nLCBjb21wb25lbnQ6IFR5cGU8YW55Pik6IFJvdXRlQnVpbGRlciB7XG4gICAgICAgIHJldHVybiBuZXcgUm91dGVCdWlsZGVyKHtcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICBjb21wb25lbnQ6IGNvbXBvbmVudFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZVJlZGlyZWN0KHBhdGg6IHN0cmluZywgcmVkaXJlY3RUbzogc3RyaW5nLCBwYXRoTWF0Y2g6ICdmdWxsJyB8ICdwcmVmaXgnID0gJ3ByZWZpeCcpOiBSb3V0ZUJ1aWxkZXIge1xuICAgICAgICByZXR1cm4gbmV3IFJvdXRlQnVpbGRlcih7XG4gICAgICAgICAgICBwYXRoOiBwYXRoLFxuICAgICAgICAgICAgcmVkaXJlY3RUbzogcmVkaXJlY3RUbyxcbiAgICAgICAgICAgIHBhdGhNYXRjaDogcGF0aE1hdGNoXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlTGF6eVJvdXRlKHBhdGg6IHN0cmluZywgbG9hZENoaWxkcmVuOiBMb2FkQ2hpbGRyZW4sIGNhbkxvYWQ/OiBBcnJheTxhbnk+KTogUm91dGVCdWlsZGVyIHtcbiAgICAgICAgY29uc3Qgcm91dGU6IFJvdXRlID0ge3BhdGg6IHBhdGgsIGxvYWRDaGlsZHJlbjogbG9hZENoaWxkcmVufTtcbiAgICAgICAgaWYgKGNhbkxvYWQ/Lmxlbmd0aCkge1xuICAgICAgICAgICAgcm91dGUuY2FuTG9hZCA9IGNhbkxvYWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBSb3V0ZUJ1aWxkZXIocm91dGUpO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlRnJvbVJvdXRlKHJvdXRlOiBSb3V0ZSk6IFJvdXRlQnVpbGRlciB7XG4gICAgICAgIHJldHVybiBuZXcgUm91dGVCdWlsZGVyKHJvdXRlKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIGNyZWF0ZUxheW91dFJvdXRlKFxuICAgICAgICBwYXRoOiBzdHJpbmcsXG4gICAgICAgIGxheW91dENvbXBvbmVudCA9IE1uZ01haW5MYXlvdXRDb21wb25lbnQsXG4gICAgICAgIHRvcGJhckNvbXBvbmVudD86IFR5cGU8YW55PixcbiAgICAgICAgYnJlYWRjcnVtYkNvbXBvbmVudD86IFR5cGU8YW55PixcbiAgICAgICAgbWVudUNvbXBvbmVudD86IFR5cGU8YW55PixcbiAgICAgICAgZm9vdGVyQ29tcG9uZW50PzogVHlwZTxhbnk+XG4gICAgKTogUm91dGVCdWlsZGVyIHtcbiAgICAgICAgY29uc3QgbGF5b3V0Um91dGUgPSBSb3V0ZUJ1aWxkZXIuY3JlYXRlKHBhdGgsIGxheW91dENvbXBvbmVudCk7XG4gICAgICAgIGlmICh0b3BiYXJDb21wb25lbnQgfHwgYnJlYWRjcnVtYkNvbXBvbmVudCB8fCBtZW51Q29tcG9uZW50IHx8IGZvb3RlckNvbXBvbmVudCkge1xuICAgICAgICAgICAgY29uc3QgZGF0YUJ1aWxkZXIgPSBSb3V0ZURhdGFCdWlsZGVyLmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKHRvcGJhckNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGRhdGFCdWlsZGVyLndpdGhUb3BiYXJDb21wb25lbnQodG9wYmFyQ29tcG9uZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChicmVhZGNydW1iQ29tcG9uZW50KSB7XG4gICAgICAgICAgICAgICAgZGF0YUJ1aWxkZXIud2l0aEJyZWFkY3J1bWJDb21wb25lbnQoYnJlYWRjcnVtYkNvbXBvbmVudCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobWVudUNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGRhdGFCdWlsZGVyLndpdGhNZW51Q29tcG9uZW50KG1lbnVDb21wb25lbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGZvb3RlckNvbXBvbmVudCkge1xuICAgICAgICAgICAgICAgIGRhdGFCdWlsZGVyLndpdGhGb290ZXJDb21wb25lbnQoZm9vdGVyQ29tcG9uZW50KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGxheW91dFJvdXRlLndpdGhEYXRhQnVpbGRlcihkYXRhQnVpbGRlcik7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxheW91dFJvdXRlO1xuICAgIH1cblxuICAgIHB1YmxpYyBzdGF0aWMgY3JlYXRlVGFibGV2aWV3Um91dGVzPFQsIFM+KFxuICAgICAgICBwYXRoOiBzdHJpbmcsXG4gICAgICAgIGRlc2NyaXB0b3I6IFRhYmxldmlld0Rlc2NyaXB0b3I8VD4sXG4gICAgICAgIGRhdGFQcm92aWRlcjogSVRhYmxldmlld0RhdGFQcm92aWRlcjxULCBTPixcbiAgICAgICAgYWN0aW9ucz86IEFycmF5PEFjdGlvbkRlc2NyaXB0b3I8VD4+LFxuICAgICAgICBoYXNEZXRhaWxzID0gdHJ1ZSxcbiAgICAgICAgaGFzRWRpdCA9IHRydWUsXG4gICAgICAgIGhhc0FkZCA9IHRydWVcbiAgICApOiBSb3V0ZUJ1aWxkZXIge1xuICAgICAgICBjb25zdCB0YWJsZXZpZXdSb3V0ZSA9IFJvdXRlQnVpbGRlci5jcmVhdGVGcm9tUm91dGUoe1xuICAgICAgICAgICAgZGF0YTogUm91dGVEYXRhQnVpbGRlci5jcmVhdGUoKS53aXRoVGFibGV2aWV3KGRlc2NyaXB0b3IsIGRhdGFQcm92aWRlciwgYWN0aW9ucykuYnVpbGQoKSxcbiAgICAgICAgICAgIHBhdGg6IHBhdGgsXG4gICAgICAgICAgICBjb21wb25lbnQ6IE1uZ1RhYmxldmlld1JvdXRlQ29tcG9uZW50XG4gICAgICAgIH0pO1xuICAgICAgICBSb3V0ZUJ1aWxkZXIuYWRkQWN0aW9uc1N1YnJvdXRlc1RvVGFibGV2aWV3UGFyZW50KHRhYmxldmlld1JvdXRlLCBoYXNEZXRhaWxzLCBoYXNFZGl0LCBoYXNBZGQpO1xuICAgICAgICByZXR1cm4gdGFibGV2aWV3Um91dGU7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGVUYWJsZXZpZXdSb3V0ZXNGcm9tQ29tcG9uZW50KHBhdGg6IHN0cmluZywgY29tcG9uZW50OiBUeXBlPGFueT4sIGhhc0RldGFpbHMgPSB0cnVlLCBoYXNFZGl0ID0gdHJ1ZSwgaGFzQWRkID0gdHJ1ZSk6IFJvdXRlQnVpbGRlciB7XG4gICAgICAgIGNvbnN0IGFjdGlvbkNydWRSb3V0ZSA9IFJvdXRlQnVpbGRlci5jcmVhdGUocGF0aCwgY29tcG9uZW50KTtcbiAgICAgICAgUm91dGVCdWlsZGVyLmFkZEFjdGlvbnNTdWJyb3V0ZXNUb1RhYmxldmlld1BhcmVudChhY3Rpb25DcnVkUm91dGUsIGhhc0RldGFpbHMsIGhhc0VkaXQsIGhhc0FkZCk7XG4gICAgICAgIHJldHVybiBhY3Rpb25DcnVkUm91dGU7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYWRkQWN0aW9uc1N1YnJvdXRlc1RvVGFibGV2aWV3UGFyZW50KHBhcmVudFJvdXRlOiBSb3V0ZUJ1aWxkZXIsIGhhc0RldGFpbHM6IGJvb2xlYW4sIGhhc0VkaXQ6IGJvb2xlYW4sIGhhc0FkZDogYm9vbGVhbikge1xuICAgICAgICBwYXJlbnRSb3V0ZS5hZGRDaGlsZCgnJywgTW5nQWN0aW9uUm91dGVDb21wb25lbnQpO1xuXG4gICAgICAgIGlmIChoYXNBZGQpIHtcbiAgICAgICAgICAgIHBhcmVudFJvdXRlLmFkZENoaWxkKCdhZGQnLCBNbmdBY3Rpb25Sb3V0ZUNvbXBvbmVudCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGhhc0RldGFpbHMpIHtcbiAgICAgICAgICAgIHBhcmVudFJvdXRlLmFkZENoaWxkKCc6aXRlbUlkJywgTW5nQWN0aW9uUm91dGVDb21wb25lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYXNFZGl0KSB7XG4gICAgICAgICAgICBwYXJlbnRSb3V0ZS5hZGRDaGlsZCgnOml0ZW1JZC9lZGl0JywgTW5nQWN0aW9uUm91dGVDb21wb25lbnQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgd2l0aFJvb3Qocm91dGVzQnVpbGRlcjogUm91dGVzQnVpbGRlcik6IHRoaXMge1xuICAgICAgICB0aGlzLnJvb3QgPSByb3V0ZXNCdWlsZGVyO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoUGFyZW50KHBhcmVudDogUm91dGVCdWlsZGVyKTogdGhpcyB7XG4gICAgICAgIHRoaXMucGFyZW50ID0gcGFyZW50O1xuICAgICAgICB0aGlzLnJvdXRlUGF0aCA9IFJvdXRlVXRpbC5yZW1vdmVFbXB0eVBhdGhTZWdtZW50cyhbLi4udGhpcy5wYXJlbnQucm91dGVQYXRoLCB0aGlzLnJvdXRlLnBhdGggPz8gJyddKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aEJyZWFkY3J1bWIoYnJlYWRjcnVtYjogQnJlYWRjcnVtYlR5cGUpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5icmVhZGNydW1iID0gYnJlYWRjcnVtYjtcbiAgICAgICAgdGhpcy5yb3V0ZS5kYXRhIVsnYnJlYWRjcnVtYiddID0gYnJlYWRjcnVtYjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aFBhZ2VUaXRsZShwYWdlVGl0bGU6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLnBhZ2VUaXRsZSA9IHBhZ2VUaXRsZTtcbiAgICAgICAgdGhpcy5yb3V0ZS5kYXRhIVsncGFnZVRpdGxlJ10gPSBwYWdlVGl0bGU7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHdpdGhSZWRpcmVjdFRvKHJlZGlyZWN0VG86IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLnJvdXRlLnJlZGlyZWN0VG8gPSByZWRpcmVjdFRvO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoUGF0aE1hdGNoKHBhdGhNYXRjaDogJ2Z1bGwnIHwgJ3ByZWZpeCcpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5yb3V0ZS5wYXRoTWF0Y2ggPSBwYXRoTWF0Y2g7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHdpdGhUaXRsZSh0aXRsZTogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIHRoaXMud2l0aFBhZ2VUaXRsZSh0aXRsZSk7XG4gICAgICAgIHRoaXMud2l0aEJyZWFkY3J1bWIodGl0bGUpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoQ2FuQWN0aXZhdGUoZGlUb2tlbjogYW55KTogdGhpcyB7XG4gICAgICAgIGlmICghdGhpcy5yb3V0ZS5jYW5BY3RpdmF0ZSkge1xuICAgICAgICAgICAgdGhpcy5yb3V0ZS5jYW5BY3RpdmF0ZSA9IFtdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucm91dGUuY2FuQWN0aXZhdGUucHVzaChkaVRva2VuKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aENhbkRlYWN0aXZhdGUoZGlUb2tlbjogYW55KTogdGhpcyB7XG4gICAgICAgIGlmICghdGhpcy5yb3V0ZS5jYW5EZWFjdGl2YXRlKSB7XG4gICAgICAgICAgICB0aGlzLnJvdXRlLmNhbkRlYWN0aXZhdGUgPSBbXTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJvdXRlLmNhbkRlYWN0aXZhdGUucHVzaChkaVRva2VuKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aFJlc29sdmVyKGRpVG9rZW46IGFueSwgbmFtZTogc3RyaW5nKTogdGhpcyB7XG4gICAgICAgIGlmICghdGhpcy5yb3V0ZS5yZXNvbHZlKSB7XG4gICAgICAgICAgICB0aGlzLnJvdXRlLnJlc29sdmUgPSB7fTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnJvdXRlLnJlc29sdmVbbmFtZV0gPSBkaVRva2VuO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoRGF0YShkYXRhOiBhbnkpOiB0aGlzIHtcbiAgICAgICAgdGhpcy5yb3V0ZS5kYXRhID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aERhdGFCdWlsZGVyKGRhdGFCdWlsZGVyOiBSb3V0ZURhdGFCdWlsZGVyKTogdGhpcyB7XG4gICAgICAgIHRoaXMucm91dGUuZGF0YSA9IGRhdGFCdWlsZGVyLmJ1aWxkKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHdpdGhNbmdNZW51SXRlbShtZW51SXRlbTogTW5nTWVudUl0ZW0pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbSA9IG1lbnVJdGVtO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoTWVudUl0ZW0oaWNvbj86IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHJvdXRlckxpbms/OiBBcnJheTxzdHJpbmc+KTogdGhpcyB7XG4gICAgICAgIHRoaXMubWVudUl0ZW0gPSB0aGlzLmNyZWF0ZU1lbnVJdGVtKGljb24sIGxhYmVsLCByb3V0ZXJMaW5rKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aE1lbnVJdGVtQ2hpbGQobGFiZWw6IHN0cmluZywgaWNvbj86IHN0cmluZywgcm91dGVyTGluaz86IEFycmF5PHN0cmluZz4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5tZW51SXRlbUNoaWxkcmVuLnB1c2godGhpcy5jcmVhdGVNZW51SXRlbShpY29uLCBsYWJlbCwgcm91dGVyTGluaykpO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoTWVudUl0ZW1DaGlsZHJlbihyb3V0ZXNCdWlsZGVyOiBSb3V0ZXNCdWlsZGVyKTogdGhpcyB7XG4gICAgICAgIGNvbnN0IG1lbnUgPSByb3V0ZXNCdWlsZGVyLmJ1aWxkTWVudSgpO1xuICAgICAgICB0aGlzLmFkanVzdE1lbnVSb3V0ZXJMaW5rc0Zyb21CdWlsZGVyKG1lbnUpO1xuICAgICAgICB0aGlzLm1lbnVJdGVtQ2hpbGRyZW4ucHVzaCguLi5tZW51KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZENoaWxkKHBhdGg6IHN0cmluZywgY29tcG9uZW50OiBUeXBlPGFueT4pOiBSb3V0ZUJ1aWxkZXIge1xuICAgICAgICBjb25zdCBjaGlsZFJvdXRlQnVpbGRlciA9IFJvdXRlQnVpbGRlci5jcmVhdGUocGF0aCwgY29tcG9uZW50KTtcbiAgICAgICAgdGhpcy5hZGRDaGlsZEJ1aWxkZXIoY2hpbGRSb3V0ZUJ1aWxkZXIpO1xuICAgICAgICByZXR1cm4gY2hpbGRSb3V0ZUJ1aWxkZXI7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZENoaWxkQnVpbGRlcihyb3V0ZUJ1aWxkZXI6IFJvdXRlQnVpbGRlcik6IHRoaXMge1xuICAgICAgICByb3V0ZUJ1aWxkZXIud2l0aFBhcmVudCh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMucm9vdCkge1xuICAgICAgICAgICAgcm91dGVCdWlsZGVyLndpdGhSb290KHRoaXMucm9vdCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jaGlsZHJlbi5wdXNoKHJvdXRlQnVpbGRlcik7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRUYWJsZXZpZXdSb3V0ZXM8VCwgUz4oXG4gICAgICAgIHBhdGg6IHN0cmluZyxcbiAgICAgICAgZGVzY3JpcHRvcjogVGFibGV2aWV3RGVzY3JpcHRvcjxUPixcbiAgICAgICAgdGFibGV2aWV3RGF0YVByb3ZpZGVyOiBJVGFibGV2aWV3RGF0YVByb3ZpZGVyPFQsIFM+LFxuICAgICAgICBhY3Rpb25zPzogQXJyYXk8QWN0aW9uRGVzY3JpcHRvcjxUPj4sXG4gICAgICAgIGhhc0RldGFpbHMgPSB0cnVlLFxuICAgICAgICBoYXNFZGl0ID0gdHJ1ZSxcbiAgICAgICAgaGFzQWRkID0gdHJ1ZVxuICAgICk6IFJvdXRlQnVpbGRlciB7XG4gICAgICAgIGNvbnN0IHJvdXRlQnVpbGRlciA9IFJvdXRlQnVpbGRlci5jcmVhdGVUYWJsZXZpZXdSb3V0ZXMocGF0aCwgZGVzY3JpcHRvciwgdGFibGV2aWV3RGF0YVByb3ZpZGVyLCBhY3Rpb25zLCBoYXNEZXRhaWxzLCBoYXNFZGl0LCBoYXNBZGQpO1xuICAgICAgICB0aGlzLmFkZENoaWxkQnVpbGRlcihyb3V0ZUJ1aWxkZXIpO1xuICAgICAgICByZXR1cm4gcm91dGVCdWlsZGVyO1xuICAgIH1cblxuICAgIHB1YmxpYyBhZGRUYWJsZXZpZXdSb3V0ZXNGcm9tQ29tcG9uZW50KHBhdGg6IHN0cmluZywgY29tcG9uZW50OiBUeXBlPGFueT4sIGhhc0RldGFpbHMgPSB0cnVlLCBoYXNFZGl0ID0gdHJ1ZSwgaGFzQWRkID0gdHJ1ZSk6IFJvdXRlQnVpbGRlciB7XG4gICAgICAgIGNvbnN0IHJvdXRlQnVpbGRlciA9IFJvdXRlQnVpbGRlci5jcmVhdGVUYWJsZXZpZXdSb3V0ZXNGcm9tQ29tcG9uZW50KHBhdGgsIGNvbXBvbmVudCwgaGFzRGV0YWlscywgaGFzRWRpdCwgaGFzQWRkKTtcbiAgICAgICAgdGhpcy5hZGRDaGlsZEJ1aWxkZXIocm91dGVCdWlsZGVyKTtcbiAgICAgICAgcmV0dXJuIHJvdXRlQnVpbGRlcjtcbiAgICB9XG5cbiAgICBwdWJsaWMgdG9QYXJlbnQoKTogUm91dGVCdWlsZGVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnBhcmVudCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQYXJlbnQgd2FzIG5vdCBwcm92aWRlZC4nKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5wYXJlbnQ7XG4gICAgfVxuXG4gICAgcHVibGljIHRvUm9vdCgpOiBSb3V0ZXNCdWlsZGVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnJvb3QpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignUm9vdCB3YXMgbm90IHByb3ZpZGVkLicpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLnJvb3Q7XG4gICAgfVxuXG4gICAgcHVibGljIGZpbmlzaCgpOiBSb3V0ZXNCdWlsZGVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9Sb290KCk7XG4gICAgfVxuXG4gICAgcHVibGljIGJ1aWxkUm91dGUoKTogUm91dGUge1xuICAgICAgICBjb25zdCBhbmd1bGFyUm91dGU6IFJvdXRlID0ge1xuICAgICAgICAgICAgLi4udGhpcy5yb3V0ZVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICgodGhpcy5yb3V0ZS5jaGlsZHJlbj8ubGVuZ3RoID8/IDApID4gMCB8fCB0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIHJvdXRlIGhhcyBjaGlsZHJlblxuICAgICAgICAgICAgYW5ndWxhclJvdXRlLmNoaWxkcmVuID0gW107XG4gICAgICAgICAgICBpZiAodGhpcy5yb3V0ZS5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgYW5ndWxhclJvdXRlLmNoaWxkcmVuLnB1c2goLi4udGhpcy5yb3V0ZS5jaGlsZHJlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAodGhpcy5jaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGNoaWxkUm91dGUgb2YgdGhpcy5jaGlsZHJlbikge1xuICAgICAgICAgICAgICAgICAgICBhbmd1bGFyUm91dGUuY2hpbGRyZW4ucHVzaChjaGlsZFJvdXRlLmJ1aWxkUm91dGUoKSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMucm91dGUuY2FuQWN0aXZhdGUpIHtcbiAgICAgICAgICAgIGFuZ3VsYXJSb3V0ZS5jYW5BY3RpdmF0ZSA9IFsuLi50aGlzLnJvdXRlLmNhbkFjdGl2YXRlXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yb3V0ZS5jYW5BY3RpdmF0ZUNoaWxkKSB7XG4gICAgICAgICAgICBhbmd1bGFyUm91dGUuY2FuQWN0aXZhdGVDaGlsZCA9IFsuLi50aGlzLnJvdXRlLmNhbkFjdGl2YXRlQ2hpbGRdO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnJvdXRlLmNhbkxvYWQpIHtcbiAgICAgICAgICAgIGFuZ3VsYXJSb3V0ZS5jYW5Mb2FkID0gWy4uLnRoaXMucm91dGUuY2FuTG9hZF07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMucm91dGUuY2FuRGVhY3RpdmF0ZSkge1xuICAgICAgICAgICAgYW5ndWxhclJvdXRlLmNhbkRlYWN0aXZhdGUgPSBbLi4udGhpcy5yb3V0ZS5jYW5EZWFjdGl2YXRlXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5yb3V0ZS5yZXNvbHZlKSB7XG4gICAgICAgICAgICBhbmd1bGFyUm91dGUucmVzb2x2ZSA9IHsuLi50aGlzLnJvdXRlLnJlc29sdmV9O1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFuZ3VsYXJSb3V0ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgYnVpbGRNZW51KCk6IEFycmF5PE1uZ01lbnVJdGVtPiB7XG4gICAgICAgIGNvbnN0IG1lbnVJdGVtQnVpbGQ6IE1uZ01lbnVJdGVtIHwgbnVsbCA9IHRoaXMubWVudUl0ZW0gPyB7Li4udGhpcy5tZW51SXRlbX0gOiBudWxsO1xuICAgICAgICBjb25zdCByb3V0ZUNoaWxkcmVuTWVudUl0ZW1zOiBBcnJheTxNbmdNZW51SXRlbT4gPSB0aGlzLmNoaWxkcmVuLmZsYXRNYXAoY2hpbGQgPT4gY2hpbGQuYnVpbGRNZW51KCkpO1xuICAgICAgICBjb25zdCBtZW51SXRlbUNoaWxkcmVuOiBBcnJheTxNbmdNZW51SXRlbT4gPSBbXTtcbiAgICAgICAgY29uc3QgbWVudUl0ZW1DaGlsZHJlbkJ1aWxkOiBBcnJheTxNbmdNZW51SXRlbT4gPSBbXTtcblxuICAgICAgICBpZiAobWVudUl0ZW1CdWlsZD8uaXRlbXMpIHtcbiAgICAgICAgICAgIG1lbnVJdGVtQ2hpbGRyZW5CdWlsZC5wdXNoKC4uLm1lbnVJdGVtQnVpbGQuaXRlbXMpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCBtZW51SXRlbUNoaWxkIG9mIHRoaXMubWVudUl0ZW1DaGlsZHJlbikge1xuICAgICAgICAgICAgY29uc3QgZmluYWxNZW51SXRlbUNoaWxkOiBNbmdNZW51SXRlbSA9IHsuLi5tZW51SXRlbUNoaWxkfTtcbiAgICAgICAgICAgIGlmICghZmluYWxNZW51SXRlbUNoaWxkLnJvdXRlckxpbmspIHtcbiAgICAgICAgICAgICAgICBmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGluayA9IHRoaXMucm91dGVQYXRoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHR5cGVvZiBmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGluayA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICBmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGluayA9IFtmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGlua107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGluayA9IFJvdXRlVXRpbC5yZW1vdmVFbXB0eVBhdGhTZWdtZW50cyhmaW5hbE1lbnVJdGVtQ2hpbGQucm91dGVyTGluayk7XG4gICAgICAgICAgICBtZW51SXRlbUNoaWxkcmVuLnB1c2goZmluYWxNZW51SXRlbUNoaWxkKTtcbiAgICAgICAgfVxuXG4gICAgICAgIG1lbnVJdGVtQ2hpbGRyZW5CdWlsZC5wdXNoKC4uLm1lbnVJdGVtQ2hpbGRyZW4sIC4uLnJvdXRlQ2hpbGRyZW5NZW51SXRlbXMpO1xuXG4gICAgICAgIGlmICghbWVudUl0ZW1CdWlsZCkge1xuICAgICAgICAgICAgcmV0dXJuIG1lbnVJdGVtQ2hpbGRyZW5CdWlsZDtcbiAgICAgICAgfVxuXG4gICAgICAgIG1lbnVJdGVtQnVpbGQubGFiZWwgPSBtZW51SXRlbUJ1aWxkLmxhYmVsID8/IHRoaXMucGFnZVRpdGxlO1xuICAgICAgICBpZiAodHlwZW9mIG1lbnVJdGVtQnVpbGQucm91dGVyTGluayA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIG1lbnVJdGVtQnVpbGQucm91dGVyTGluayA9IFttZW51SXRlbUJ1aWxkLnJvdXRlckxpbmtdO1xuICAgICAgICB9XG4gICAgICAgIG1lbnVJdGVtQnVpbGQucm91dGVyTGluayA9IFJvdXRlVXRpbC5yZW1vdmVFbXB0eVBhdGhTZWdtZW50cyhtZW51SXRlbUJ1aWxkLnJvdXRlckxpbmsgPz8gdGhpcy5yb3V0ZVBhdGgpO1xuICAgICAgICBpZiAobWVudUl0ZW1DaGlsZHJlbkJ1aWxkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG1lbnVJdGVtQnVpbGQuaXRlbXMgPSBtZW51SXRlbUNoaWxkcmVuQnVpbGQ7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIW1lbnVJdGVtQnVpbGQuZ3VhcmRzKSB7XG4gICAgICAgICAgICBjb25zdCBndWFyZHMgPSB0aGlzLmZpbmRNZW51SXRlbUd1YXJkcygpO1xuICAgICAgICAgICAgaWYgKGd1YXJkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgbWVudUl0ZW1CdWlsZC5ndWFyZHMgPSBndWFyZHM7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gW21lbnVJdGVtQnVpbGRdO1xuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlTWVudUl0ZW0oaWNvbj86IHN0cmluZywgbGFiZWw/OiBzdHJpbmcsIHJvdXRlckxpbms/OiBBcnJheTxzdHJpbmc+KSB7XG4gICAgICAgIGNvbnN0IG1lbnVJdGVtOiBNbmdNZW51SXRlbSA9IHt9O1xuICAgICAgICBpZiAoaWNvbikge1xuICAgICAgICAgICAgbWVudUl0ZW0uaWNvbiA9IGljb247XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGxhYmVsKSB7XG4gICAgICAgICAgICBtZW51SXRlbS5sYWJlbCA9IGxhYmVsO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyb3V0ZXJMaW5rKSB7XG4gICAgICAgICAgICBtZW51SXRlbS5yb3V0ZXJMaW5rID0gcm91dGVyTGluaztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWVudUl0ZW07XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBhZGp1c3RNZW51Um91dGVyTGlua3NGcm9tQnVpbGRlcihtZW51SXRlbXM6IEFycmF5PE1uZ01lbnVJdGVtPikge1xuICAgICAgICBmb3IgKGNvbnN0IG1lbnVJdGVtIG9mIG1lbnVJdGVtcykge1xuICAgICAgICAgICAgaWYgKG1lbnVJdGVtLnJvdXRlckxpbmspIHtcbiAgICAgICAgICAgICAgICBtZW51SXRlbS5yb3V0ZXJMaW5rID0gUm91dGVVdGlsLmFwcGVuZFBhdGhUb0Jhc2VQYXRoKHRoaXMucm91dGVQYXRoLCB0eXBlb2YgbWVudUl0ZW0ucm91dGVyTGluayA9PT0gJ3N0cmluZycgPyBbbWVudUl0ZW0ucm91dGVyTGlua10gOiBtZW51SXRlbS5yb3V0ZXJMaW5rKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KG1lbnVJdGVtLml0ZW1zKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRqdXN0TWVudVJvdXRlckxpbmtzRnJvbUJ1aWxkZXIobWVudUl0ZW0uaXRlbXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmaW5kTWVudUl0ZW1HdWFyZHMoKTogQXJyYXk8YW55PiB7XG4gICAgICAgIGNvbnN0IGd1YXJkczogQXJyYXk8YW55PiA9IFtdO1xuICAgICAgICBpZiAodGhpcy5yb3V0ZS5jYW5BY3RpdmF0ZT8ubGVuZ3RoKSB7XG4gICAgICAgICAgICBndWFyZHMucHVzaCguLi50aGlzLnJvdXRlLmNhbkFjdGl2YXRlKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXJlbnQpIHtcbiAgICAgICAgICAgIC8vIENoZWNrIGZvciBwYXJlbnQgZ3VhcmRzIHRoYXQgc2hvdWxkIGJlIGluY2x1ZGVkIGluIGRlY2lzaW9uIHRvIGhpZGUgbWVudSBpdGVtIVxuICAgICAgICAgICAgLy8gU29tZSBwYXJlbnQgcm91dGVzIG1pZ2h0IGhhdmUgZ3VhcmRzLCBidXQgbm8gbWVudSBpdGVtcywgc28gdGhpcyBndWFyZHMgbXVzdCBiZSB0YWtlbiBpbnRvIGFjY291bnQgaGVyZSxcbiAgICAgICAgICAgIC8vIGJlY2F1c2UgdGhlcmUgaXMgbm8gcGFyZW50IG1lbnUgaXRlbSB0byBoaWRlLlxuICAgICAgICAgICAgdGhpcy5wYXJlbnQuZmluZE1lbnVJdGVtR3VhcmRzKCkuZm9yRWFjaChnID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZ3VhcmRzLmluZGV4T2YoZykgPCAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGd1YXJkcy5wdXNoKGcpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBndWFyZHM7XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgUm91dGVEYXRhQnVpbGRlciB7XG4gICAgcHJpdmF0ZSBkYXRhOiBNbmdSb3V0ZXJEYXRhO1xuXG4gICAgY29uc3RydWN0b3IoaW5pdD86IERhdGEpIHtcbiAgICAgICAgdGhpcy5kYXRhID0gaW5pdCA/PyB7fTtcbiAgICAgICAgaWYgKCF0aGlzLmRhdGEuYnJlYWRjcnVtYikge1xuICAgICAgICAgICAgdGhpcy5kYXRhLmJyZWFkY3J1bWIgPSBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBjcmVhdGUoZGF0YT86IERhdGEpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSb3V0ZURhdGFCdWlsZGVyKGRhdGEpO1xuICAgIH1cblxuICAgIHdpdGhCcmVhZGNydW1iKGJyZWFkY3J1bWI6IEJyZWFkY3J1bWJUeXBlKTogdGhpcyB7XG4gICAgICAgIHRoaXMuZGF0YS5icmVhZGNydW1iID0gYnJlYWRjcnVtYjtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aFBhZ2VUaXRsZShwYWdlVGl0bGU6IHN0cmluZyk6IHRoaXMge1xuICAgICAgICB0aGlzLmRhdGEucGFnZVRpdGxlID0gcGFnZVRpdGxlO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoVGFibGV2aWV3KGRlc2NyaXB0b3I6IFRhYmxldmlld0Rlc2NyaXB0b3I8YW55PiwgZGF0YVByb3ZpZGVyOiBJVGFibGV2aWV3RGF0YVByb3ZpZGVyPGFueSwgYW55PiwgYWN0aW9ucz86IEFycmF5PEFjdGlvbkRlc2NyaXB0b3I8YW55Pj4pOiB0aGlzIHtcbiAgICAgICAgdGhpcy5kYXRhLnRhYmxldmlldyA9IHtcbiAgICAgICAgICAgIGRlc2NyaXB0b3I6IGRlc2NyaXB0b3IsXG4gICAgICAgICAgICBkYXRhUHJvdmlkZXI6IGRhdGFQcm92aWRlclxuICAgICAgICB9O1xuICAgICAgICBpZiAoYWN0aW9ucykge1xuICAgICAgICAgICAgdGhpcy5kYXRhLnRhYmxldmlldy5hY3Rpb25zID0gYWN0aW9ucztcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoVG9wYmFyQ29tcG9uZW50KGNvbXBvbmVudDogVHlwZTxhbnk+KTogdGhpcyB7XG4gICAgICAgIHRoaXMuZGF0YS50b3BiYXJDb21wb25lbnQgPSBjb21wb25lbnQ7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHdpdGhCcmVhZGNydW1iQ29tcG9uZW50KGNvbXBvbmVudDogVHlwZTxhbnk+KTogdGhpcyB7XG4gICAgICAgIHRoaXMuZGF0YS5icmVhZGNydW1iQ29tcG9uZW50ID0gY29tcG9uZW50O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICB3aXRoTWVudUNvbXBvbmVudChjb21wb25lbnQ6IFR5cGU8YW55Pik6IHRoaXMge1xuICAgICAgICB0aGlzLmRhdGEubWVudUNvbXBvbmVudCA9IGNvbXBvbmVudDtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgd2l0aEZvb3RlckNvbXBvbmVudChjb21wb25lbnQ6IFR5cGU8YW55Pik6IHRoaXMge1xuICAgICAgICB0aGlzLmRhdGEuZm9vdGVyQ29tcG9uZW50ID0gY29tcG9uZW50O1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBidWlsZCgpOiBNbmdSb3V0ZXJEYXRhIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGF0YTtcbiAgICB9XG59XG4iXX0=
|