ngx-register-base 1.2.3 → 1.3.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/ng-package.json +15 -0
- package/package.json +12 -15
- package/schematics/ng-update/replace-menu-state-token/index.ts +33 -0
- package/schematics/ng-update/update-prefix/index.ts +38 -0
- package/schematics/utils/{utils.d.ts → utils.ts} +9 -2
- package/src/lib/components/checkbox-selector/checkbox-selector.component.html +91 -0
- package/src/lib/components/checkbox-selector/checkbox-selector.component.less +67 -0
- package/src/lib/components/checkbox-selector/checkbox-selector.component.ts +176 -0
- package/src/lib/components/checkbox-selector/checkbox-selector.types.ts +8 -0
- package/src/lib/components/column-settings/column-settings.component.html +160 -0
- package/src/lib/components/column-settings/column-settings.component.less +131 -0
- package/src/lib/components/column-settings/column-settings.component.ts +352 -0
- package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.html +65 -0
- package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.less +79 -0
- package/src/lib/components/column-settings/components/column-settings-template/column-settings-template.component.ts +114 -0
- package/src/lib/components/column-settings/consts/column-settings.consts.ts +9 -0
- package/src/lib/components/column-settings/types/column-settings.types.ts +26 -0
- package/src/lib/components/divider/divider.component.html +4 -0
- package/src/lib/components/divider/divider.component.less +10 -0
- package/src/lib/components/divider/divider.component.ts +12 -0
- package/src/lib/components/filter-button/filter-button.component.html +20 -0
- package/src/lib/components/filter-button/filter-button.component.less +41 -0
- package/src/lib/components/filter-button/filter-button.component.ts +18 -0
- package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.html +22 -0
- package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.less +23 -0
- package/src/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.ts +31 -0
- package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.html +49 -0
- package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.less +37 -0
- package/src/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.ts +66 -0
- package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.html +147 -0
- package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.less +45 -0
- package/src/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.ts +114 -0
- package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.html +44 -0
- package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.less +49 -0
- package/src/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.ts +167 -0
- package/src/lib/components/filters/components/filter-list/filter-list.service.ts +97 -0
- package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.html +18 -0
- package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.less +55 -0
- package/src/lib/components/filters/components/filter-list/filters-section/filters-section.component.ts +69 -0
- package/src/lib/components/filters/components/filter-list.module.ts +29 -0
- package/src/lib/components/filters/register-table-filter.component.html +53 -0
- package/src/lib/components/filters/register-table-filter.component.less +17 -0
- package/src/lib/components/filters/register-table-filter.component.ts +167 -0
- package/src/lib/components/filters/register-table-filter.module.ts +22 -0
- package/src/lib/components/inputs/inputs.module.ts +104 -0
- package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.html +49 -0
- package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.less +70 -0
- package/src/lib/components/inputs/param-calendar-year/param-calendar-year.component.ts +52 -0
- package/src/lib/components/inputs/param-custom/param-custom.component.html +1 -0
- package/src/lib/components/inputs/param-custom/param-custom.component.ts +9 -0
- package/src/lib/components/inputs/param-date/param-date.component.html +55 -0
- package/src/lib/components/inputs/param-date/param-date.component.less +67 -0
- package/src/lib/components/inputs/param-date/param-date.component.ts +77 -0
- package/src/lib/components/inputs/param-date-range/param-date-range.component.html +45 -0
- package/src/lib/components/inputs/param-date-range/param-date-range.component.less +75 -0
- package/src/lib/components/inputs/param-date-range/param-date-range.component.ts +67 -0
- package/src/lib/components/inputs/param-date-time/param-date-time.component.html +70 -0
- package/src/lib/components/inputs/param-date-time/param-date-time.component.less +72 -0
- package/src/lib/components/inputs/param-date-time/param-date-time.component.ts +101 -0
- package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.html +67 -0
- package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.less +103 -0
- package/src/lib/components/inputs/param-date-time-range/param-date-time-range.component.ts +128 -0
- package/src/lib/components/inputs/param-month/param-month.component.html +46 -0
- package/src/lib/components/inputs/param-month/param-month.component.less +72 -0
- package/src/lib/components/inputs/param-month/param-month.component.ts +55 -0
- package/src/lib/components/inputs/param-month-range/param-month-range.component.html +39 -0
- package/src/lib/components/inputs/param-month-range/param-month-range.component.less +71 -0
- package/src/lib/components/inputs/param-month-range/param-month-range.component.ts +76 -0
- package/src/lib/components/inputs/param-multi-select/param-multi-select.component.html +84 -0
- package/src/lib/components/inputs/param-multi-select/param-multi-select.component.less +108 -0
- package/src/lib/components/inputs/param-multi-select/param-multi-select.component.ts +448 -0
- package/src/lib/components/inputs/param-select/param-select.component.html +106 -0
- package/src/lib/components/inputs/param-select/param-select.component.less +26 -0
- package/src/lib/components/inputs/param-select/param-select.component.ts +318 -0
- package/src/lib/components/inputs/param-switcher/param-switcher.component.html +8 -0
- package/src/lib/components/inputs/param-switcher/param-switcher.component.less +53 -0
- package/src/lib/components/inputs/param-switcher/param-switcher.component.ts +13 -0
- package/src/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.ts +29 -0
- package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.html +19 -0
- package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.less +76 -0
- package/src/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.ts +134 -0
- package/src/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.ts +8 -0
- package/src/lib/components/inputs/param-text/param-text.component.html +59 -0
- package/src/lib/components/inputs/param-text/param-text.component.less +33 -0
- package/src/lib/components/inputs/param-text/param-text.component.ts +36 -0
- package/src/lib/components/inputs/param-textarea/param-textarea.component.html +61 -0
- package/src/lib/components/inputs/param-textarea/param-textarea.component.less +21 -0
- package/src/lib/components/inputs/param-textarea/param-textarea.component.ts +33 -0
- package/src/lib/components/inputs/param-toggle/param-toggle.component.html +40 -0
- package/src/lib/components/inputs/param-toggle/param-toggle.component.less +69 -0
- package/src/lib/components/inputs/param-toggle/param-toggle.component.ts +14 -0
- package/src/lib/components/inputs/param-tree/consts/param-tree.consts.ts +59 -0
- package/src/lib/components/inputs/param-tree/param-tree.component.html +51 -0
- package/src/lib/components/inputs/param-tree/param-tree.component.less +3 -0
- package/src/lib/components/inputs/param-tree/param-tree.component.ts +282 -0
- package/src/lib/components/inputs/param-tree/services/param-tree.service.ts +176 -0
- package/src/lib/components/inputs/param-tree/services/sync-tree-loader.service.ts +18 -0
- package/{lib/components/inputs/param-tree/tokens/param-tree.tokens.d.ts → src/lib/components/inputs/param-tree/tokens/param-tree.tokens.ts} +2 -1
- package/src/lib/components/inputs/param-tree/types/param-tree.types.ts +39 -0
- package/src/lib/components/inputs/param-tree/utils/param-tree.utils.ts +18 -0
- package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.html +78 -0
- package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.less +109 -0
- package/src/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.ts +89 -0
- package/src/lib/components/inputs/param-tree-select/param-tree-select.component.html +54 -0
- package/src/lib/components/inputs/param-tree-select/param-tree-select.component.less +56 -0
- package/src/lib/components/inputs/param-tree-select/param-tree-select.component.ts +91 -0
- package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.html +5 -0
- package/src/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.ts +13 -0
- package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.html +4 -0
- package/src/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.ts +11 -0
- package/src/lib/components/menu-constructor/sproc-menu-constructor.component.html +95 -0
- package/src/lib/components/menu-constructor/sproc-menu-constructor.component.less +183 -0
- package/src/lib/components/menu-constructor/sproc-menu-constructor.component.ts +687 -0
- package/src/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.ts +32 -0
- package/src/lib/components/menu-constructor/store/sproc-menu-constructor.consts.ts +46 -0
- package/{lib/components/menu-constructor/store/sproc-menu.tokens.d.ts → src/lib/components/menu-constructor/store/sproc-menu.tokens.ts} +4 -1
- package/src/lib/components/page-menu/README.md +60 -0
- package/src/lib/components/page-menu/schema/sproc-page-menu.consts.ts +8 -0
- package/src/lib/components/page-menu/schema/sproc-page-menu.schema.ts +35 -0
- package/src/lib/components/page-menu/schema/sproc-page-menu.tokens.ts +5 -0
- package/src/lib/components/page-menu/schema/sproc-page-menu.types.ts +42 -0
- package/src/lib/components/page-menu/sproc-page-menu.component.html +166 -0
- package/src/lib/components/page-menu/sproc-page-menu.component.less +228 -0
- package/src/lib/components/page-menu/sproc-page-menu.component.ts +337 -0
- package/src/lib/components/paginator/paginator.component.html +97 -0
- package/src/lib/components/paginator/paginator.component.less +101 -0
- package/src/lib/components/paginator/paginator.component.ts +192 -0
- package/src/lib/components/paginator/types/paginator.types.ts +16 -0
- package/src/lib/components/register-table/consts/register-table.consts.ts +3 -0
- package/src/lib/components/register-table/directives/cell-template.directive.ts +11 -0
- package/src/lib/components/register-table/directives/header-template.directive.ts +11 -0
- package/src/lib/components/register-table/model/schema.ts +62 -0
- package/src/lib/components/register-table/pipes/class-by-type.pipe.ts +28 -0
- package/src/lib/components/register-table/pipes/sticky-column.pipe.ts +11 -0
- package/src/lib/components/register-table/register-table.component.html +257 -0
- package/src/lib/components/register-table/register-table.component.less +151 -0
- package/src/lib/components/register-table/register-table.component.ts +743 -0
- package/src/lib/components/reset-settings-form/reset-settings-form.component.html +14 -0
- package/src/lib/components/reset-settings-form/reset-settings-form.component.less +26 -0
- package/src/lib/components/reset-settings-form/reset-settings-form.component.ts +15 -0
- package/src/lib/components/search-input/search-input.component.html +6 -0
- package/src/lib/components/search-input/search-input.component.less +17 -0
- package/src/lib/components/search-input/search-input.component.ts +31 -0
- package/src/lib/components/sliding-panel/sliding-panel.component.html +13 -0
- package/src/lib/components/sliding-panel/sliding-panel.component.less +112 -0
- package/src/lib/components/sliding-panel/sliding-panel.component.ts +36 -0
- package/src/lib/components/sliding-panel/sliding-panel.module.ts +11 -0
- package/src/lib/consts/date-time.consts.ts +1 -0
- package/src/lib/consts/index.ts +8 -0
- package/src/lib/consts/inputs.consts.ts +9 -0
- package/src/lib/consts/month.consts.ts +82 -0
- package/src/lib/consts/params.consts.ts +1 -0
- package/src/lib/consts/register-base.consts.ts +40 -0
- package/src/lib/core/form-group-wrapper/errors-consts.ts +6 -0
- package/src/lib/core/form-group-wrapper/form-group-wrapper.ts +109 -0
- package/src/lib/core/input-control/input-control.ts +30 -0
- package/src/lib/core/param/param-base.ts +262 -0
- package/src/lib/core/param/param-date-base.ts +30 -0
- package/src/lib/core/param/param-select-base.ts +118 -0
- package/src/lib/core/param/param-text-base.ts +23 -0
- package/{lib/core/param/param.tokens.d.ts → src/lib/core/param/param.tokens.ts} +2 -1
- package/src/lib/core/register-base/register-base.store.ts +84 -0
- package/src/lib/core/register-base/register-base.ts +854 -0
- package/src/lib/directives/date/date-time.types.ts +36 -0
- package/src/lib/directives/date/format-date.pipe.ts +28 -0
- package/src/lib/directives/number/number-only.directive.ts +36 -0
- package/src/lib/directives/sticky/sticky-relative.directive.ts +30 -0
- package/src/lib/directives/sticky/sticky-relative.service.ts +34 -0
- package/src/lib/directives/sticky/sticky.directive.ts +189 -0
- package/src/lib/services/date-time.service.ts +399 -0
- package/src/lib/services/dialog/dialog.service.ts +62 -0
- package/{lib/services/dialog/dialog.types.d.ts → src/lib/services/dialog/dialog.types.ts} +8 -4
- package/src/lib/services/dom-intersection.service.ts +23 -0
- package/src/lib/services/filter/filters-state.service.ts +83 -0
- package/src/lib/services/filter/filters-transmit.service.ts +105 -0
- package/src/lib/services/filter/filters.service.ts +21 -0
- package/src/lib/services/inputs-state.service.ts +157 -0
- package/src/lib/services/inputs.service.ts +114 -0
- package/src/lib/services/key-pressed.service.ts +40 -0
- package/src/lib/services/resize-window-observer.service.ts +37 -0
- package/src/lib/services/selected-objects-state.service.ts +159 -0
- package/src/lib/store/fast-query-store.service.ts +132 -0
- package/{lib/types/event.types.d.ts → src/lib/types/event.types.ts} +1 -1
- package/src/lib/types/hasura.types.ts +41 -0
- package/src/lib/types/inputs.types.ts +63 -0
- package/src/lib/types/params.types.ts +42 -0
- package/src/lib/types/register-base.types.ts +161 -0
- package/src/lib/types/sub-types.ts +15 -0
- package/src/lib/types/user-profile.types.ts +18 -0
- package/src/lib/utils/functions.ts +11 -0
- package/src/lib/utils/get-url-segment.ts +46 -0
- package/src/lib/utils/prizm.shared.module.ts +176 -0
- package/src/lib/utils/rxjs.ts +33 -0
- package/src/lib/utils/select-all-utils.ts +16 -0
- package/tsconfig.lib.json +16 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.schematics.json +26 -0
- package/tsconfig.spec.json +15 -0
- package/esm2022/lib/components/checkbox-selector/checkbox-selector.component.mjs +0 -129
- package/esm2022/lib/components/checkbox-selector/checkbox-selector.types.mjs +0 -8
- package/esm2022/lib/components/column-settings/column-settings.component.mjs +0 -249
- package/esm2022/lib/components/column-settings/components/column-settings-template/column-settings-template.component.mjs +0 -80
- package/esm2022/lib/components/column-settings/consts/column-settings.consts.mjs +0 -10
- package/esm2022/lib/components/column-settings/index.mjs +0 -3
- package/esm2022/lib/components/column-settings/types/column-settings.types.mjs +0 -7
- package/esm2022/lib/components/divider/divider.component.mjs +0 -16
- package/esm2022/lib/components/filter-button/filter-button.component.mjs +0 -19
- package/esm2022/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.mjs +0 -31
- package/esm2022/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.mjs +0 -57
- package/esm2022/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.mjs +0 -110
- package/esm2022/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.mjs +0 -130
- package/esm2022/lib/components/filters/components/filter-list/filter-list.service.mjs +0 -89
- package/esm2022/lib/components/filters/components/filter-list/filters-section/filters-section.component.mjs +0 -41
- package/esm2022/lib/components/filters/components/filter-list.module.mjs +0 -45
- package/esm2022/lib/components/filters/index.mjs +0 -3
- package/esm2022/lib/components/filters/register-table-filter.component.mjs +0 -155
- package/esm2022/lib/components/filters/register-table-filter.module.mjs +0 -39
- package/esm2022/lib/components/index.mjs +0 -11
- package/esm2022/lib/components/inputs/index.mjs +0 -20
- package/esm2022/lib/components/inputs/inputs.module.mjs +0 -166
- package/esm2022/lib/components/inputs/param-calendar-year/param-calendar-year.component.mjs +0 -45
- package/esm2022/lib/components/inputs/param-custom/param-custom.component.mjs +0 -12
- package/esm2022/lib/components/inputs/param-date/param-date.component.mjs +0 -76
- package/esm2022/lib/components/inputs/param-date-range/param-date-range.component.mjs +0 -61
- package/esm2022/lib/components/inputs/param-date-time/param-date-time.component.mjs +0 -86
- package/esm2022/lib/components/inputs/param-date-time-range/param-date-time-range.component.mjs +0 -96
- package/esm2022/lib/components/inputs/param-month/param-month.component.mjs +0 -50
- package/esm2022/lib/components/inputs/param-month-range/param-month-range.component.mjs +0 -62
- package/esm2022/lib/components/inputs/param-multi-select/param-multi-select.component.mjs +0 -309
- package/esm2022/lib/components/inputs/param-select/param-select.component.mjs +0 -209
- package/esm2022/lib/components/inputs/param-switcher/param-switcher.component.mjs +0 -21
- package/esm2022/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.mjs +0 -28
- package/esm2022/lib/components/inputs/param-switcher-date-time-range/index.mjs +0 -3
- package/esm2022/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.mjs +0 -105
- package/esm2022/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.mjs +0 -10
- package/esm2022/lib/components/inputs/param-text/param-text.component.mjs +0 -40
- package/esm2022/lib/components/inputs/param-textarea/param-textarea.component.mjs +0 -38
- package/esm2022/lib/components/inputs/param-toggle/param-toggle.component.mjs +0 -20
- package/esm2022/lib/components/inputs/param-tree/consts/param-tree.consts.mjs +0 -37
- package/esm2022/lib/components/inputs/param-tree/index.mjs +0 -8
- package/esm2022/lib/components/inputs/param-tree/param-tree.component.mjs +0 -207
- package/esm2022/lib/components/inputs/param-tree/services/param-tree.service.mjs +0 -116
- package/esm2022/lib/components/inputs/param-tree/services/sync-tree-loader.service.mjs +0 -20
- package/esm2022/lib/components/inputs/param-tree/tokens/param-tree.tokens.mjs +0 -3
- package/esm2022/lib/components/inputs/param-tree/types/param-tree.types.mjs +0 -2
- package/esm2022/lib/components/inputs/param-tree/utils/param-tree.utils.mjs +0 -9
- package/esm2022/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.mjs +0 -80
- package/esm2022/lib/components/inputs/param-tree-select/param-tree-select.component.mjs +0 -85
- package/esm2022/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.mjs +0 -15
- package/esm2022/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.mjs +0 -12
- package/esm2022/lib/components/menu-constructor/index.mjs +0 -5
- package/esm2022/lib/components/menu-constructor/sproc-menu-constructor.component.mjs +0 -559
- package/esm2022/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.mjs +0 -3
- package/esm2022/lib/components/menu-constructor/store/sproc-menu-constructor.consts.mjs +0 -5
- package/esm2022/lib/components/menu-constructor/store/sproc-menu.tokens.mjs +0 -3
- package/esm2022/lib/components/page-menu/index.mjs +0 -6
- package/esm2022/lib/components/page-menu/schema/sproc-page-menu.consts.mjs +0 -9
- package/esm2022/lib/components/page-menu/schema/sproc-page-menu.schema.mjs +0 -2
- package/esm2022/lib/components/page-menu/schema/sproc-page-menu.tokens.mjs +0 -4
- package/esm2022/lib/components/page-menu/schema/sproc-page-menu.types.mjs +0 -3
- package/esm2022/lib/components/page-menu/sproc-page-menu.component.mjs +0 -275
- package/esm2022/lib/components/paginator/paginator.component.mjs +0 -159
- package/esm2022/lib/components/paginator/types/paginator.types.mjs +0 -2
- package/esm2022/lib/components/register-table/consts/register-table.consts.mjs +0 -4
- package/esm2022/lib/components/register-table/directives/cell-template.directive.mjs +0 -19
- package/esm2022/lib/components/register-table/directives/header-template.directive.mjs +0 -18
- package/esm2022/lib/components/register-table/index.mjs +0 -4
- package/esm2022/lib/components/register-table/model/schema.mjs +0 -10
- package/esm2022/lib/components/register-table/pipes/class-by-type.pipe.mjs +0 -33
- package/esm2022/lib/components/register-table/pipes/sticky-column.pipe.mjs +0 -17
- package/esm2022/lib/components/register-table/register-table.component.mjs +0 -544
- package/esm2022/lib/components/reset-settings-form/reset-settings-form.component.mjs +0 -18
- package/esm2022/lib/components/search-input/search-input.component.mjs +0 -28
- package/esm2022/lib/components/sliding-panel/sliding-panel.component.mjs +0 -48
- package/esm2022/lib/components/sliding-panel/sliding-panel.module.mjs +0 -19
- package/esm2022/lib/consts/date-time.consts.mjs +0 -2
- package/esm2022/lib/consts/index.mjs +0 -4
- package/esm2022/lib/consts/inputs.consts.mjs +0 -4
- package/esm2022/lib/consts/month.consts.mjs +0 -77
- package/esm2022/lib/consts/params.consts.mjs +0 -2
- package/esm2022/lib/consts/register-base.consts.mjs +0 -26
- package/esm2022/lib/core/form-group-wrapper/errors-consts.mjs +0 -8
- package/esm2022/lib/core/form-group-wrapper/form-group-wrapper.mjs +0 -81
- package/esm2022/lib/core/form-group-wrapper/index.mjs +0 -2
- package/esm2022/lib/core/index.mjs +0 -5
- package/esm2022/lib/core/input-control/index.mjs +0 -2
- package/esm2022/lib/core/input-control/input-control.mjs +0 -11
- package/esm2022/lib/core/param/index.mjs +0 -6
- package/esm2022/lib/core/param/param-base.mjs +0 -215
- package/esm2022/lib/core/param/param-date-base.mjs +0 -26
- package/esm2022/lib/core/param/param-select-base.mjs +0 -114
- package/esm2022/lib/core/param/param-text-base.mjs +0 -25
- package/esm2022/lib/core/param/param.tokens.mjs +0 -4
- package/esm2022/lib/core/register-base/index.mjs +0 -3
- package/esm2022/lib/core/register-base/register-base.mjs +0 -575
- package/esm2022/lib/core/register-base/register-base.store.mjs +0 -43
- package/esm2022/lib/directives/date/date-time.types.mjs +0 -34
- package/esm2022/lib/directives/date/format-date.pipe.mjs +0 -33
- package/esm2022/lib/directives/index.mjs +0 -3
- package/esm2022/lib/directives/number/number-only.directive.mjs +0 -41
- package/esm2022/lib/directives/sticky/index.mjs +0 -3
- package/esm2022/lib/directives/sticky/sticky-relative.directive.mjs +0 -32
- package/esm2022/lib/directives/sticky/sticky-relative.service.mjs +0 -32
- package/esm2022/lib/directives/sticky/sticky.directive.mjs +0 -169
- package/esm2022/lib/services/date-time.service.mjs +0 -314
- package/esm2022/lib/services/dialog/dialog.service.mjs +0 -53
- package/esm2022/lib/services/dialog/dialog.types.mjs +0 -2
- package/esm2022/lib/services/dialog/index.mjs +0 -3
- package/esm2022/lib/services/dom-intersection.service.mjs +0 -22
- package/esm2022/lib/services/filter/filters-state.service.mjs +0 -65
- package/esm2022/lib/services/filter/filters-transmit.service.mjs +0 -82
- package/esm2022/lib/services/filter/filters.service.mjs +0 -23
- package/esm2022/lib/services/index.mjs +0 -8
- package/esm2022/lib/services/inputs-state.service.mjs +0 -130
- package/esm2022/lib/services/inputs.service.mjs +0 -88
- package/esm2022/lib/services/key-pressed.service.mjs +0 -37
- package/esm2022/lib/services/resize-window-observer.service.mjs +0 -33
- package/esm2022/lib/services/selected-objects-state.service.mjs +0 -123
- package/esm2022/lib/store/fast-query-store.service.mjs +0 -110
- package/esm2022/lib/store/index.mjs +0 -2
- package/esm2022/lib/types/event.types.mjs +0 -2
- package/esm2022/lib/types/hasura.types.mjs +0 -2
- package/esm2022/lib/types/index.mjs +0 -7
- package/esm2022/lib/types/inputs.types.mjs +0 -19
- package/esm2022/lib/types/params.types.mjs +0 -2
- package/esm2022/lib/types/register-base.types.mjs +0 -6
- package/esm2022/lib/types/sub-types.mjs +0 -2
- package/esm2022/lib/types/user-profile.types.mjs +0 -2
- package/esm2022/lib/utils/functions.mjs +0 -10
- package/esm2022/lib/utils/get-url-segment.mjs +0 -35
- package/esm2022/lib/utils/index.mjs +0 -5
- package/esm2022/lib/utils/prizm.shared.module.mjs +0 -284
- package/esm2022/lib/utils/rxjs.mjs +0 -28
- package/esm2022/lib/utils/select-all-utils.mjs +0 -11
- package/esm2022/ngx-register-base.mjs +0 -5
- package/esm2022/public-api.mjs +0 -9
- package/fesm2022/ngx-register-base.mjs +0 -7465
- package/fesm2022/ngx-register-base.mjs.map +0 -1
- package/index.d.ts +0 -5
- package/lib/components/checkbox-selector/checkbox-selector.component.d.ts +0 -33
- package/lib/components/checkbox-selector/checkbox-selector.types.d.ts +0 -7
- package/lib/components/column-settings/column-settings.component.d.ts +0 -80
- package/lib/components/column-settings/components/column-settings-template/column-settings-template.component.d.ts +0 -24
- package/lib/components/column-settings/consts/column-settings.consts.d.ts +0 -8
- package/lib/components/column-settings/types/column-settings.types.d.ts +0 -22
- package/lib/components/divider/divider.component.d.ts +0 -6
- package/lib/components/filter-button/filter-button.component.d.ts +0 -8
- package/lib/components/filters/components/filter-list/filter-edit/filter-edit.component.d.ts +0 -14
- package/lib/components/filters/components/filter-list/filter-list-footer/filter-list-footer.component.d.ts +0 -25
- package/lib/components/filters/components/filter-list/filter-list-header/filter-list-header.component.d.ts +0 -39
- package/lib/components/filters/components/filter-list/filter-list-saved/filter-list-saved.component.d.ts +0 -41
- package/lib/components/filters/components/filter-list/filter-list.service.d.ts +0 -20
- package/lib/components/filters/components/filter-list/filters-section/filters-section.component.d.ts +0 -15
- package/lib/components/filters/components/filter-list.module.d.ts +0 -15
- package/lib/components/filters/register-table-filter.component.d.ts +0 -40
- package/lib/components/filters/register-table-filter.module.d.ts +0 -13
- package/lib/components/inputs/inputs.module.d.ts +0 -31
- package/lib/components/inputs/param-calendar-year/param-calendar-year.component.d.ts +0 -19
- package/lib/components/inputs/param-custom/param-custom.component.d.ts +0 -6
- package/lib/components/inputs/param-date/param-date.component.d.ts +0 -20
- package/lib/components/inputs/param-date-range/param-date-range.component.d.ts +0 -26
- package/lib/components/inputs/param-date-time/param-date-time.component.d.ts +0 -25
- package/lib/components/inputs/param-date-time-range/param-date-time-range.component.d.ts +0 -28
- package/lib/components/inputs/param-month/param-month.component.d.ts +0 -18
- package/lib/components/inputs/param-month-range/param-month-range.component.d.ts +0 -21
- package/lib/components/inputs/param-multi-select/param-multi-select.component.d.ts +0 -46
- package/lib/components/inputs/param-select/param-select.component.d.ts +0 -30
- package/lib/components/inputs/param-switcher/param-switcher.component.d.ts +0 -8
- package/lib/components/inputs/param-switcher-date-time-range/consts/param-switcher-date-time-range.consts.d.ts +0 -2
- package/lib/components/inputs/param-switcher-date-time-range/param-switcher-date-time-range.component.d.ts +0 -19
- package/lib/components/inputs/param-switcher-date-time-range/types/param-switcher-date-time-range.types.d.ts +0 -8
- package/lib/components/inputs/param-text/param-text.component.d.ts +0 -10
- package/lib/components/inputs/param-textarea/param-textarea.component.d.ts +0 -10
- package/lib/components/inputs/param-toggle/param-toggle.component.d.ts +0 -9
- package/lib/components/inputs/param-tree/consts/param-tree.consts.d.ts +0 -7
- package/lib/components/inputs/param-tree/param-tree.component.d.ts +0 -41
- package/lib/components/inputs/param-tree/services/param-tree.service.d.ts +0 -37
- package/lib/components/inputs/param-tree/services/sync-tree-loader.service.d.ts +0 -10
- package/lib/components/inputs/param-tree/types/param-tree.types.d.ts +0 -32
- package/lib/components/inputs/param-tree/utils/param-tree.utils.d.ts +0 -7
- package/lib/components/inputs/param-tree-multi-select/param-tree-multi-select.component.d.ts +0 -31
- package/lib/components/inputs/param-tree-select/param-tree-select.component.d.ts +0 -30
- package/lib/components/inputs/sub-components/param-delete-content-icon/param-delete-content-btn.component.d.ts +0 -6
- package/lib/components/inputs/sub-components/param-invalid-icon/param-invalid-icon.component.d.ts +0 -5
- package/lib/components/menu-constructor/sproc-menu-constructor.component.d.ts +0 -113
- package/lib/components/menu-constructor/store/sproc-abstract-menu-constructor.store.d.ts +0 -24
- package/lib/components/menu-constructor/store/sproc-menu-constructor.consts.d.ts +0 -36
- package/lib/components/page-menu/schema/sproc-page-menu.consts.d.ts +0 -7
- package/lib/components/page-menu/schema/sproc-page-menu.schema.d.ts +0 -30
- package/lib/components/page-menu/schema/sproc-page-menu.tokens.d.ts +0 -3
- package/lib/components/page-menu/schema/sproc-page-menu.types.d.ts +0 -36
- package/lib/components/page-menu/sproc-page-menu.component.d.ts +0 -48
- package/lib/components/paginator/paginator.component.d.ts +0 -52
- package/lib/components/paginator/types/paginator.types.d.ts +0 -15
- package/lib/components/register-table/consts/register-table.consts.d.ts +0 -3
- package/lib/components/register-table/directives/cell-template.directive.d.ts +0 -9
- package/lib/components/register-table/directives/header-template.directive.d.ts +0 -9
- package/lib/components/register-table/model/schema.d.ts +0 -52
- package/lib/components/register-table/pipes/class-by-type.pipe.d.ts +0 -8
- package/lib/components/register-table/pipes/sticky-column.pipe.d.ts +0 -7
- package/lib/components/register-table/register-table.component.d.ts +0 -165
- package/lib/components/reset-settings-form/reset-settings-form.component.d.ts +0 -9
- package/lib/components/search-input/search-input.component.d.ts +0 -11
- package/lib/components/sliding-panel/sliding-panel.component.d.ts +0 -14
- package/lib/components/sliding-panel/sliding-panel.module.d.ts +0 -9
- package/lib/consts/date-time.consts.d.ts +0 -1
- package/lib/consts/index.d.ts +0 -3
- package/lib/consts/inputs.consts.d.ts +0 -4
- package/lib/consts/month.consts.d.ts +0 -49
- package/lib/consts/params.consts.d.ts +0 -1
- package/lib/consts/register-base.consts.d.ts +0 -19
- package/lib/core/form-group-wrapper/errors-consts.d.ts +0 -5
- package/lib/core/form-group-wrapper/form-group-wrapper.d.ts +0 -15
- package/lib/core/input-control/input-control.d.ts +0 -11
- package/lib/core/param/param-base.d.ts +0 -68
- package/lib/core/param/param-date-base.d.ts +0 -18
- package/lib/core/param/param-select-base.d.ts +0 -42
- package/lib/core/param/param-text-base.d.ts +0 -15
- package/lib/core/register-base/register-base.d.ts +0 -168
- package/lib/core/register-base/register-base.store.d.ts +0 -35
- package/lib/directives/date/date-time.types.d.ts +0 -32
- package/lib/directives/date/format-date.pipe.d.ts +0 -10
- package/lib/directives/number/number-only.directive.d.ts +0 -10
- package/lib/directives/sticky/sticky-relative.directive.d.ts +0 -13
- package/lib/directives/sticky/sticky-relative.service.d.ts +0 -15
- package/lib/directives/sticky/sticky.directive.d.ts +0 -27
- package/lib/services/date-time.service.d.ts +0 -80
- package/lib/services/dialog/dialog.service.d.ts +0 -22
- package/lib/services/dom-intersection.service.d.ts +0 -8
- package/lib/services/filter/filters-state.service.d.ts +0 -21
- package/lib/services/filter/filters-transmit.service.d.ts +0 -28
- package/lib/services/filter/filters.service.d.ts +0 -12
- package/lib/services/inputs-state.service.d.ts +0 -57
- package/lib/services/inputs.service.d.ts +0 -28
- package/lib/services/key-pressed.service.d.ts +0 -15
- package/lib/services/resize-window-observer.service.d.ts +0 -11
- package/lib/services/selected-objects-state.service.d.ts +0 -47
- package/lib/store/fast-query-store.service.d.ts +0 -19
- package/lib/types/hasura.types.d.ts +0 -35
- package/lib/types/inputs.types.d.ts +0 -41
- package/lib/types/params.types.d.ts +0 -27
- package/lib/types/register-base.types.d.ts +0 -123
- package/lib/types/sub-types.d.ts +0 -8
- package/lib/types/user-profile.types.d.ts +0 -17
- package/lib/utils/functions.d.ts +0 -3
- package/lib/utils/get-url-segment.d.ts +0 -7
- package/lib/utils/prizm.shared.module.d.ts +0 -14
- package/lib/utils/rxjs.d.ts +0 -10
- package/lib/utils/select-all-utils.d.ts +0 -8
- package/schematics/ng-update/replace-menu-state-token/index.d.ts +0 -2
- package/schematics/ng-update/replace-menu-state-token/index.js +0 -29
- package/schematics/ng-update/replace-menu-state-token/index.js.map +0 -1
- package/schematics/ng-update/update-prefix/index.d.ts +0 -2
- package/schematics/ng-update/update-prefix/index.js +0 -33
- package/schematics/ng-update/update-prefix/index.js.map +0 -1
- package/schematics/utils/utils.js +0 -25
- package/schematics/utils/utils.js.map +0 -1
- /package/{lib/components/column-settings/index.d.ts → src/lib/components/column-settings/index.ts} +0 -0
- /package/{lib/components/filters/index.d.ts → src/lib/components/filters/index.ts} +0 -0
- /package/{lib/components/index.d.ts → src/lib/components/index.ts} +0 -0
- /package/{lib/components/inputs/index.d.ts → src/lib/components/inputs/index.ts} +0 -0
- /package/{lib/components/inputs/param-switcher-date-time-range/index.d.ts → src/lib/components/inputs/param-switcher-date-time-range/index.ts} +0 -0
- /package/{lib/components/inputs/param-tree/index.d.ts → src/lib/components/inputs/param-tree/index.ts} +0 -0
- /package/{lib/components/menu-constructor/index.d.ts → src/lib/components/menu-constructor/index.ts} +0 -0
- /package/{lib/components/page-menu/index.d.ts → src/lib/components/page-menu/index.ts} +0 -0
- /package/{lib/components/register-table/index.d.ts → src/lib/components/register-table/index.ts} +0 -0
- /package/{lib/core/form-group-wrapper/index.d.ts → src/lib/core/form-group-wrapper/index.ts} +0 -0
- /package/{lib/core/index.d.ts → src/lib/core/index.ts} +0 -0
- /package/{lib/core/input-control/index.d.ts → src/lib/core/input-control/index.ts} +0 -0
- /package/{lib/core/param/index.d.ts → src/lib/core/param/index.ts} +0 -0
- /package/{lib/core/register-base/index.d.ts → src/lib/core/register-base/index.ts} +0 -0
- /package/{lib/directives/index.d.ts → src/lib/directives/index.ts} +0 -0
- /package/{lib/directives/sticky/index.d.ts → src/lib/directives/sticky/index.ts} +0 -0
- /package/{lib/services/dialog/index.d.ts → src/lib/services/dialog/index.ts} +0 -0
- /package/{lib/services/index.d.ts → src/lib/services/index.ts} +0 -0
- /package/{lib/store/index.d.ts → src/lib/store/index.ts} +0 -0
- /package/{lib/types/index.d.ts → src/lib/types/index.ts} +0 -0
- /package/{lib/utils/index.d.ts → src/lib/utils/index.ts} +0 -0
- /package/{public-api.d.ts → src/public-api.ts} +0 -0
|
@@ -1,559 +0,0 @@
|
|
|
1
|
-
import { Component, computed, DestroyRef, inject, output, signal } from '@angular/core';
|
|
2
|
-
import { FormsModule } from '@angular/forms';
|
|
3
|
-
import { CdkDrag, CdkDragHandle, CdkDragPreview, CdkDropList, } from '@angular/cdk/drag-drop';
|
|
4
|
-
import { AsyncPipe, NgForOf } from '@angular/common';
|
|
5
|
-
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { filter } from 'rxjs';
|
|
7
|
-
import { EMPTY_UUID, MIGRATION_HINT, NEW_ITEM_PREFIX, ROOT_TITLE, } from './store/sproc-menu-constructor.consts';
|
|
8
|
-
import { MENU_CONSTRUCTOR_STORE_TOKEN } from './store/sproc-menu.tokens';
|
|
9
|
-
import * as i0 from "@angular/core";
|
|
10
|
-
import * as i1 from "@angular/forms";
|
|
11
|
-
export class SprocMenuConstructorComponent {
|
|
12
|
-
constructor() {
|
|
13
|
-
this._store = inject(MENU_CONSTRUCTOR_STORE_TOKEN);
|
|
14
|
-
this._ref = inject(DestroyRef);
|
|
15
|
-
this.ROOT_TITLE = ROOT_TITLE;
|
|
16
|
-
this.loading$ = this._store.loading$;
|
|
17
|
-
this.originalTree = new Map([]);
|
|
18
|
-
this.MIGRATION_HINT = MIGRATION_HINT;
|
|
19
|
-
this.deletedIds = [];
|
|
20
|
-
this.errorMsgOutput = output();
|
|
21
|
-
// плоское представление иерархического меню
|
|
22
|
-
this.flatTree = signal([]);
|
|
23
|
-
// ветка элементов, которая перетаскивается
|
|
24
|
-
this.draggedBranch = signal([]);
|
|
25
|
-
// вычисляемое свойство, возвращающее только видимые (не свернутые) элементы
|
|
26
|
-
this.visibleFlatTree = computed(() => {
|
|
27
|
-
const flatTree = this.flatTree();
|
|
28
|
-
return this._getVisibleFrom(flatTree);
|
|
29
|
-
});
|
|
30
|
-
this._pendingRecalc = false;
|
|
31
|
-
}
|
|
32
|
-
ngOnInit() {
|
|
33
|
-
this._store.menuItems$
|
|
34
|
-
.pipe(filter((arr) => Array.isArray(arr) && arr.length > 0), takeUntilDestroyed(this._ref))
|
|
35
|
-
.subscribe((value) => {
|
|
36
|
-
this.flatTree.set(this._convertToFlatNode(value));
|
|
37
|
-
this.originalTree = new Map(this.flatTree().map((item) => [item.id, { ...item }]));
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Переключает состояние свернутости узла (collapse/expand)
|
|
42
|
-
* После изменения создает новый массив для триггера обновления сигнала
|
|
43
|
-
*/
|
|
44
|
-
toggleCollapse(node) {
|
|
45
|
-
node.collapsed = !node.collapsed;
|
|
46
|
-
this.flatTree.set([...this.flatTree()]);
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Начало перетаскивания: сохраняет всю ветку узла, которую тянут
|
|
50
|
-
*/
|
|
51
|
-
dragStarted(node) {
|
|
52
|
-
const branch = this._collectBranch(this.flatTree(), node);
|
|
53
|
-
this.draggedBranch.set(branch);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Завершение перетаскивания: очищает информацию о текущей ветке
|
|
57
|
-
*/
|
|
58
|
-
dragEnded() {
|
|
59
|
-
this.draggedBranch.set([]);
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Основная логика drag&drop при отпускании элемента
|
|
63
|
-
* Определяет новую позицию узла, пересчитывает глубины и связи
|
|
64
|
-
*/
|
|
65
|
-
drop(event) {
|
|
66
|
-
const before = [...this.flatTree()];
|
|
67
|
-
const visibleBefore = this._getVisibleFrom(before);
|
|
68
|
-
const prevIdx = event.previousIndex;
|
|
69
|
-
const currIdx = event.currentIndex;
|
|
70
|
-
// Получает перетаскиваемый элемент из списка видимых
|
|
71
|
-
const draggedVisible = visibleBefore[prevIdx];
|
|
72
|
-
if (!draggedVisible) {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
// Находит индекс узла в полном массиве
|
|
76
|
-
const start = before.findIndex((n) => n.id === draggedVisible.id);
|
|
77
|
-
if (start < 0) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
// Собирает всю ветку, начинающуюся с перетаскиваемого узла
|
|
81
|
-
const branch = this._collectBranch(before, before[start]);
|
|
82
|
-
const branchIds = new Set(branch.map((n) => n.id));
|
|
83
|
-
// Убирает ветку из исходного списка
|
|
84
|
-
const full = before.filter((n) => !branchIds.has(n.id));
|
|
85
|
-
// Определяет видимые элементы после удаления ветки
|
|
86
|
-
const visible = this._getVisibleFrom(full);
|
|
87
|
-
const prevVisible = visible[currIdx - 1] ?? null;
|
|
88
|
-
const nextVisible = visible[currIdx] ?? null;
|
|
89
|
-
// Индекс вставки ветки в новый список
|
|
90
|
-
const insert = nextVisible ? full.findIndex((n) => n.id === nextVisible.id) : full.length;
|
|
91
|
-
// Рассчитывает глубину вставляемой ветки в зависимости от соседей
|
|
92
|
-
let targetDepth;
|
|
93
|
-
if (prevVisible && nextVisible) {
|
|
94
|
-
targetDepth =
|
|
95
|
-
prevVisible.depth < nextVisible.depth ? prevVisible.depth + 1 : nextVisible.depth;
|
|
96
|
-
}
|
|
97
|
-
else if (prevVisible && !nextVisible) {
|
|
98
|
-
targetDepth = prevVisible.depth;
|
|
99
|
-
}
|
|
100
|
-
else if (!prevVisible && nextVisible) {
|
|
101
|
-
targetDepth = nextVisible.depth;
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
targetDepth = 0;
|
|
105
|
-
}
|
|
106
|
-
// Вставляет ветку в новое место
|
|
107
|
-
full.splice(insert, 0, ...branch);
|
|
108
|
-
// Сдвигает глубину всей ветки
|
|
109
|
-
this._applyDepthShift(branch, targetDepth - branch[0].depth);
|
|
110
|
-
// Планирует пересчет структуры дерева
|
|
111
|
-
this._scheduleRecalc(full);
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Увеличивает глубину (depth) конкретного узла, если возможно
|
|
115
|
-
*/
|
|
116
|
-
indent(node) {
|
|
117
|
-
const arr = [...this.flatTree()];
|
|
118
|
-
const index = arr.indexOf(node);
|
|
119
|
-
if (index === -1) {
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
const proposedDepth = node.depth + 1;
|
|
123
|
-
// Ищет подходящего родителя с нужной глубиной
|
|
124
|
-
const parentCandidate = [...arr]
|
|
125
|
-
.slice(0, index)
|
|
126
|
-
.reverse()
|
|
127
|
-
.find((n) => n.depth === proposedDepth - 1);
|
|
128
|
-
if (!parentCandidate) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
node.depth = proposedDepth;
|
|
132
|
-
this._scheduleRecalc(arr);
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Уменьшает глубину (depth) узла + по возможности превращает его в родителя
|
|
136
|
-
*/
|
|
137
|
-
outdent(node) {
|
|
138
|
-
const arr = [...this.flatTree()];
|
|
139
|
-
const index = arr.indexOf(node);
|
|
140
|
-
if (index === -1 || node.depth <= 0) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
node.depth = Math.max(0, node.depth - 1);
|
|
144
|
-
this._scheduleRecalc(arr);
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Увеличивает глубину всей ветки узла (вместе с потомками)
|
|
148
|
-
*/
|
|
149
|
-
indentBranch(node) {
|
|
150
|
-
const arr = [...this.flatTree()];
|
|
151
|
-
const index = arr.indexOf(node);
|
|
152
|
-
if (index === -1) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const proposedDepth = node.depth + 1;
|
|
156
|
-
const parentCandidate = [...arr]
|
|
157
|
-
.slice(0, index)
|
|
158
|
-
.reverse()
|
|
159
|
-
.find((n) => n.depth === proposedDepth - 1);
|
|
160
|
-
if (!parentCandidate) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
const branch = this._collectBranch(arr, node);
|
|
164
|
-
this._applyDepthShift(branch, 1);
|
|
165
|
-
this._scheduleRecalc(arr);
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Уменьшает глубину всей ветки узла
|
|
169
|
-
*/
|
|
170
|
-
outdentBranch(node) {
|
|
171
|
-
const arr = [...this.flatTree()];
|
|
172
|
-
const branch = this._collectBranch(arr, node);
|
|
173
|
-
this._applyDepthShift(branch, -1);
|
|
174
|
-
this._scheduleRecalc(arr);
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Проверяет, есть ли у узла дочерние элементы
|
|
178
|
-
*/
|
|
179
|
-
hasChildren(node) {
|
|
180
|
-
const arr = this.flatTree();
|
|
181
|
-
const idx = arr.indexOf(node);
|
|
182
|
-
if (idx === -1) {
|
|
183
|
-
return false;
|
|
184
|
-
}
|
|
185
|
-
for (let i = idx + 1; i < arr.length; i++) {
|
|
186
|
-
const next = arr[i];
|
|
187
|
-
if (next.depth <= node.depth) {
|
|
188
|
-
break;
|
|
189
|
-
}
|
|
190
|
-
if (next.depth === node.depth + 1) {
|
|
191
|
-
return true;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return false;
|
|
195
|
-
}
|
|
196
|
-
save() {
|
|
197
|
-
// Флаг для логгирования на время отладки
|
|
198
|
-
const logging = false;
|
|
199
|
-
const changedElements = this.flatTree().filter((newItem) => {
|
|
200
|
-
const originalItem = this.originalTree.get(newItem.id);
|
|
201
|
-
// Новый элемент
|
|
202
|
-
if (!originalItem) {
|
|
203
|
-
if (logging) {
|
|
204
|
-
console.log(`Новый элемент ${newItem.title}`);
|
|
205
|
-
}
|
|
206
|
-
return true;
|
|
207
|
-
}
|
|
208
|
-
const { order_num: originalOrderNum, id_parent: originalIdParent, title: originalTitle, allowed_roles: originalRoles, code: originalCode, route: originalRoute, icon: originalIcon, } = originalItem;
|
|
209
|
-
const { order_num: newOrderNum, id_parent: newIdParent, title: newTitle, allowed_roles: newRoles, code: newCode, route: newRoute, icon: newIcon, } = newItem;
|
|
210
|
-
const changedFields = [];
|
|
211
|
-
if (originalOrderNum !== newOrderNum) {
|
|
212
|
-
changedFields.push(`order_num: ${originalOrderNum} → ${newOrderNum}`);
|
|
213
|
-
}
|
|
214
|
-
if (originalIdParent !== newIdParent) {
|
|
215
|
-
changedFields.push(`id_parent: ${originalIdParent} → ${newIdParent}`);
|
|
216
|
-
}
|
|
217
|
-
if (originalTitle !== newTitle) {
|
|
218
|
-
changedFields.push(`title: ${originalTitle} → ${newTitle}`);
|
|
219
|
-
}
|
|
220
|
-
if (originalCode !== newCode) {
|
|
221
|
-
changedFields.push(`code: ${originalCode} → ${newCode}`);
|
|
222
|
-
}
|
|
223
|
-
if (originalRoute !== newRoute) {
|
|
224
|
-
changedFields.push(`route: ${originalRoute} → ${newRoute}`);
|
|
225
|
-
}
|
|
226
|
-
if (originalIcon !== newIcon) {
|
|
227
|
-
changedFields.push(`icon: ${originalIcon} → ${newIcon}`);
|
|
228
|
-
}
|
|
229
|
-
if (JSON.stringify(originalRoles) !== JSON.stringify(newRoles)) {
|
|
230
|
-
changedFields.push(`allowed_roles: ${originalRoles} → ${newRoles}`);
|
|
231
|
-
}
|
|
232
|
-
return changedFields.length > 0;
|
|
233
|
-
});
|
|
234
|
-
const isBlank = (s) => typeof s !== 'string' || s.trim() === '';
|
|
235
|
-
const isRouteValid = ({ route, code }) => {
|
|
236
|
-
// route считается заданным, только если это непустая строка
|
|
237
|
-
const hasRoute = route.trim() !== '';
|
|
238
|
-
return !hasRoute || route === code;
|
|
239
|
-
};
|
|
240
|
-
const invalidCodeTitles = [];
|
|
241
|
-
const invalidRouteTitles = [];
|
|
242
|
-
for (const el of changedElements) {
|
|
243
|
-
if (isBlank(el.code)) {
|
|
244
|
-
invalidCodeTitles.push(el.title ?? '(без названия)');
|
|
245
|
-
}
|
|
246
|
-
if (!isRouteValid(el)) {
|
|
247
|
-
invalidRouteTitles.push(el);
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
if (invalidCodeTitles.length > 0) {
|
|
251
|
-
this.errorMsgOutput.emit({
|
|
252
|
-
label: 'Конструктор меню',
|
|
253
|
-
appearance: 'negative',
|
|
254
|
-
// eslint-disable-next-line xss/no-mixed-html
|
|
255
|
-
content: `Все поля code должны быть заполнены. </br>
|
|
256
|
-
Исправьте следующие поля: </br>
|
|
257
|
-
${invalidCodeTitles.map((t) => `- ${t}`).join('</br>')}
|
|
258
|
-
`,
|
|
259
|
-
});
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
if (invalidRouteTitles.length > 0) {
|
|
263
|
-
this.errorMsgOutput.emit({
|
|
264
|
-
label: 'Конструктор меню',
|
|
265
|
-
appearance: 'negative',
|
|
266
|
-
// eslint-disable-next-line xss/no-mixed-html
|
|
267
|
-
content: `Все поля code должны быть равны полю route. </br>
|
|
268
|
-
Исправьте следующие поля: </br>
|
|
269
|
-
${invalidRouteTitles.map((t) => `- ${t.title} (${t.code} | ${t.route})`).join('</br>')}
|
|
270
|
-
`,
|
|
271
|
-
});
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
const elRoute = (route) => (route === '' ? null : route);
|
|
275
|
-
const normalizeElement = (el) => ({
|
|
276
|
-
title: el.title.trim(),
|
|
277
|
-
route: elRoute(el.route.trim()),
|
|
278
|
-
code: el.code,
|
|
279
|
-
icon: el.icon,
|
|
280
|
-
order_num: el.order_num,
|
|
281
|
-
allowed_roles: el.allowed_roles
|
|
282
|
-
? el.allowed_roles.split(',').map((value) => value.trim())
|
|
283
|
-
: null,
|
|
284
|
-
id_parent: el.id_parent,
|
|
285
|
-
});
|
|
286
|
-
const objectsToSave = changedElements
|
|
287
|
-
.filter(({ id }) => !id.includes(NEW_ITEM_PREFIX))
|
|
288
|
-
.map((el) => ({
|
|
289
|
-
_set: normalizeElement(el),
|
|
290
|
-
where: { id: { _eq: el.id } },
|
|
291
|
-
}));
|
|
292
|
-
const objectsToInsert = changedElements
|
|
293
|
-
.filter(({ id }) => id.includes(NEW_ITEM_PREFIX))
|
|
294
|
-
.map((element) => {
|
|
295
|
-
element.id = EMPTY_UUID;
|
|
296
|
-
return normalizeElement(element);
|
|
297
|
-
});
|
|
298
|
-
const objectsToDelete = [...this.deletedIds];
|
|
299
|
-
if (logging) {
|
|
300
|
-
console.log(`Измененные элементы`, objectsToSave);
|
|
301
|
-
console.log(`Новые элементы`, objectsToInsert);
|
|
302
|
-
console.log('Удалённые элементы:', objectsToDelete);
|
|
303
|
-
}
|
|
304
|
-
this._store.updateMenu(objectsToSave, objectsToInsert, objectsToDelete);
|
|
305
|
-
this.deletedIds = [];
|
|
306
|
-
}
|
|
307
|
-
handleFold(state) {
|
|
308
|
-
for (const element of this.flatTree()) {
|
|
309
|
-
if (element.title !== ROOT_TITLE) {
|
|
310
|
-
element.collapsed = state;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
this.flatTree.set([...this.flatTree()]);
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Удаляет один элемент из дерева.
|
|
317
|
-
* Потомки становятся дочерними элементами родителя удалённого узла.
|
|
318
|
-
*/
|
|
319
|
-
deleteItem(node) {
|
|
320
|
-
const arr = [...this.flatTree()];
|
|
321
|
-
const index = arr.indexOf(node);
|
|
322
|
-
if (index === -1) {
|
|
323
|
-
return;
|
|
324
|
-
}
|
|
325
|
-
const parentId = node.id_parent;
|
|
326
|
-
const nodeDepth = node.depth;
|
|
327
|
-
// Находим потомков, которые были напрямую под этим узлом
|
|
328
|
-
for (let i = index + 1; i < arr.length; i++) {
|
|
329
|
-
const next = arr[i];
|
|
330
|
-
if (next.depth <= nodeDepth) {
|
|
331
|
-
break;
|
|
332
|
-
}
|
|
333
|
-
if (next.depth === nodeDepth + 1) {
|
|
334
|
-
// потомок становится ребёнком родителя удалённого узла
|
|
335
|
-
next.id_parent = parentId ?? null;
|
|
336
|
-
next.depth = nodeDepth; // поднимаем на один уровень вверх
|
|
337
|
-
}
|
|
338
|
-
else if (next.depth > nodeDepth + 1) {
|
|
339
|
-
// поднимаем остальные на один уровень вверх
|
|
340
|
-
next.depth -= 1;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
// Удаляем сам элемент
|
|
344
|
-
arr.splice(index, 1);
|
|
345
|
-
// Если id не временный — добавляем в список на удаление
|
|
346
|
-
if (!node.id.includes(NEW_ITEM_PREFIX)) {
|
|
347
|
-
this.deletedIds.push(node.id);
|
|
348
|
-
}
|
|
349
|
-
this._scheduleRecalc(arr);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Добавляет новый элемент в дерево.
|
|
353
|
-
* По умолчанию он создаётся как дочерний элемент root.
|
|
354
|
-
*/
|
|
355
|
-
addNewItem() {
|
|
356
|
-
const arr = [...this.flatTree()];
|
|
357
|
-
const rootNode = arr.find((n) => n.title === this.ROOT_TITLE);
|
|
358
|
-
if (!rootNode) {
|
|
359
|
-
console.error('Root элемент не найден. Новый пункт не может быть добавлен.');
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
const newNode = {
|
|
363
|
-
id: `${NEW_ITEM_PREFIX}${crypto.randomUUID()}`,
|
|
364
|
-
id_parent: rootNode.id,
|
|
365
|
-
title: 'Новый пункт меню',
|
|
366
|
-
route: '',
|
|
367
|
-
icon: '',
|
|
368
|
-
order_num: 1,
|
|
369
|
-
allowed_roles: null,
|
|
370
|
-
collapsed: true,
|
|
371
|
-
code: '',
|
|
372
|
-
depth: rootNode.depth + 1,
|
|
373
|
-
};
|
|
374
|
-
const insertIndex = arr.findIndex((n) => n.id === rootNode.id) + 1;
|
|
375
|
-
arr.splice(insertIndex, 0, newNode);
|
|
376
|
-
this._scheduleRecalc(arr);
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Сбрасывает текущее состояние в исходное
|
|
380
|
-
*/
|
|
381
|
-
reset() {
|
|
382
|
-
const originalMenu = structuredClone(this._store.originalMenu);
|
|
383
|
-
this.flatTree.set(this._convertToFlatNode(originalMenu));
|
|
384
|
-
this.deletedIds = [];
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Проверяет, находится ли элемент в текущей перетаскиваемой ветке
|
|
388
|
-
*/
|
|
389
|
-
isDragged(node) {
|
|
390
|
-
return this.draggedBranch().some((n) => n.id === node.id);
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Собирает всю ветку элементов начиная с указанного узла (включая потомков)
|
|
394
|
-
*/
|
|
395
|
-
_collectBranch(arr, root) {
|
|
396
|
-
const start = arr.indexOf(root);
|
|
397
|
-
if (start < 0) {
|
|
398
|
-
return [];
|
|
399
|
-
}
|
|
400
|
-
const branch = [{ ...root }];
|
|
401
|
-
for (let i = start + 1; i < arr.length; i++) {
|
|
402
|
-
const n = arr[i];
|
|
403
|
-
if (n.depth > root.depth) {
|
|
404
|
-
branch.push(n);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
break;
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
return branch;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Сдвигает глубину всех элементов ветки на указанную разницу
|
|
414
|
-
* Не допускает отрицательных глубин
|
|
415
|
-
*/
|
|
416
|
-
_applyDepthShift(branch, diff) {
|
|
417
|
-
if (diff === 0) {
|
|
418
|
-
return;
|
|
419
|
-
}
|
|
420
|
-
for (const n of branch) {
|
|
421
|
-
n.depth = Math.max(0, n.depth + diff);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
/**
|
|
425
|
-
* Преобразует иерархический JSON в плоский массив FlatNode[]
|
|
426
|
-
* Сохраняет порядок элементов и их вложенность
|
|
427
|
-
*/
|
|
428
|
-
_convertToFlatNode(data) {
|
|
429
|
-
// Глубокая копия, чтобы не портить оригинал
|
|
430
|
-
const cloned = structuredClone(data);
|
|
431
|
-
const map = new Map();
|
|
432
|
-
const roots = [];
|
|
433
|
-
for (const item of cloned) {
|
|
434
|
-
map.set(item.id, item);
|
|
435
|
-
}
|
|
436
|
-
for (const item of cloned) {
|
|
437
|
-
if (item.id_parent && map.has(item.id_parent)) {
|
|
438
|
-
const parent = map.get(item.id_parent);
|
|
439
|
-
if (!parent.children) {
|
|
440
|
-
parent.children = [];
|
|
441
|
-
}
|
|
442
|
-
parent.children.push(item);
|
|
443
|
-
}
|
|
444
|
-
else {
|
|
445
|
-
roots.push(item);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
const flat = [];
|
|
449
|
-
const walk = (node, depth) => {
|
|
450
|
-
flat.push({
|
|
451
|
-
id: node.id,
|
|
452
|
-
id_parent: node.id_parent,
|
|
453
|
-
title: node.title ?? '',
|
|
454
|
-
route: node.route ?? '',
|
|
455
|
-
icon: node.icon ?? '',
|
|
456
|
-
order_num: node.order_num ?? 0,
|
|
457
|
-
allowed_roles: node.allowed_roles?.join(',') ?? null,
|
|
458
|
-
collapsed: node.title !== ROOT_TITLE,
|
|
459
|
-
code: node.code ?? '',
|
|
460
|
-
depth,
|
|
461
|
-
});
|
|
462
|
-
if (node.children?.length) {
|
|
463
|
-
const sortedChildren = [...node.children].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
|
|
464
|
-
for (const child of sortedChildren) {
|
|
465
|
-
walk(child, depth + 1);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
};
|
|
469
|
-
const sortedRoots = [...roots].sort((a, b) => (a.order_num ?? 0) - (b.order_num ?? 0));
|
|
470
|
-
for (const root of sortedRoots) {
|
|
471
|
-
walk(root, 0);
|
|
472
|
-
}
|
|
473
|
-
return flat;
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* Возвращает список видимых элементов на основе флагов collapsed
|
|
477
|
-
* Использует стек для отслеживания свернутости на каждом уровне
|
|
478
|
-
*/
|
|
479
|
-
_getVisibleFrom(arr) {
|
|
480
|
-
const source = typeof arr === 'function' ? arr() : arr;
|
|
481
|
-
const out = [];
|
|
482
|
-
const collapsedStack = [];
|
|
483
|
-
for (const n of source) {
|
|
484
|
-
while (collapsedStack.length > n.depth) {
|
|
485
|
-
collapsedStack.pop();
|
|
486
|
-
}
|
|
487
|
-
if (!collapsedStack.includes(true)) {
|
|
488
|
-
out.push(n);
|
|
489
|
-
collapsedStack[n.depth] = !!n.collapsed;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
return out;
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Пересчитывает order_num и id_parent у всех элементов массива
|
|
496
|
-
* После перемещений поддерживает корректную структуру дерева
|
|
497
|
-
* order_num назначается относительно родителя (1..N)
|
|
498
|
-
*/
|
|
499
|
-
_recalculateTree(arr) {
|
|
500
|
-
const parents = [];
|
|
501
|
-
const childCounters = new Map();
|
|
502
|
-
for (const node of arr) {
|
|
503
|
-
while (parents.length > 0 && parents[parents.length - 1].depth >= node.depth) {
|
|
504
|
-
parents.pop();
|
|
505
|
-
}
|
|
506
|
-
const parent = parents.length > 0 ? parents[parents.length - 1] : null;
|
|
507
|
-
node.id_parent = parent ? parent.id : null;
|
|
508
|
-
// вычисляем порядковый номер среди братьев
|
|
509
|
-
if (node.title !== ROOT_TITLE) {
|
|
510
|
-
const parentId = node.id_parent ?? null;
|
|
511
|
-
const currentCount = childCounters.get(parentId) ?? 1;
|
|
512
|
-
node.order_num = currentCount;
|
|
513
|
-
childCounters.set(parentId, currentCount + 1);
|
|
514
|
-
}
|
|
515
|
-
parents.push(node);
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
/**
|
|
519
|
-
* Асинхронно планирует пересчет дерева через requestAnimationFrame
|
|
520
|
-
* Это предотвращает множественные лишние пересчеты при частых изменениях
|
|
521
|
-
*/
|
|
522
|
-
_scheduleRecalc(arr) {
|
|
523
|
-
if (this._pendingRecalc) {
|
|
524
|
-
return;
|
|
525
|
-
}
|
|
526
|
-
this._pendingRecalc = true;
|
|
527
|
-
requestAnimationFrame(() => {
|
|
528
|
-
this._recalculateTree([...arr]);
|
|
529
|
-
const current = this.flatTree();
|
|
530
|
-
if (!this._arraysEqual(current, arr)) {
|
|
531
|
-
this.flatTree.set([...arr]);
|
|
532
|
-
}
|
|
533
|
-
this._pendingRecalc = false;
|
|
534
|
-
});
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Проверяет равенство двух массивов FlatNode по ключевым свойствам
|
|
538
|
-
*/
|
|
539
|
-
_arraysEqual(a, b) {
|
|
540
|
-
if (a.length !== b.length) {
|
|
541
|
-
return false;
|
|
542
|
-
}
|
|
543
|
-
for (const [i, element] of a.entries()) {
|
|
544
|
-
if (element.id !== b[i].id ||
|
|
545
|
-
element.depth !== b[i].depth ||
|
|
546
|
-
element.order_num !== b[i].order_num) {
|
|
547
|
-
return false;
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
return true;
|
|
551
|
-
}
|
|
552
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
553
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SprocMenuConstructorComponent, isStandalone: true, selector: "sproc-menu-constructor", outputs: { errorMsgOutput: "errorMsgOutput" }, ngImport: i0, template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"], dependencies: [{ kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "pipe", type: AsyncPipe, name: "async" }] }); }
|
|
554
|
-
}
|
|
555
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SprocMenuConstructorComponent, decorators: [{
|
|
556
|
-
type: Component,
|
|
557
|
-
args: [{ standalone: true, selector: 'sproc-menu-constructor', imports: [CdkDrag, CdkDropList, NgForOf, FormsModule, CdkDragPreview, CdkDragHandle, AsyncPipe], template: "<div class=\"menu-constructor\">\n <div class=\"pane editor\">\n <div class=\"pane-header\">\n <h2>\u0420\u0435\u0434\u0430\u043A\u0442\u043E\u0440 \u043C\u0435\u043D\u044E</h2>\n <div class=\"buttons\">\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"addNewItem()\">\n +\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn secondary\" (click)=\"reset()\">\n \u0421\u0431\u0440\u043E\u0441\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"save()\">\n \u0421\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(false)\">\n \u0420\u0430\u0441\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n <button [disabled]=\"$any(loading$ | async)\" class=\"btn primary\" (click)=\"handleFold(true)\">\n \u0421\u043A\u0440\u044B\u0442\u044C \u0432\u0441\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B\n </button>\n </div>\n </div>\n\n <div\n class=\"list-wrapper\"\n cdkDropList\n [cdkDropListData]=\"visibleFlatTree()\"\n (cdkDropListDropped)=\"drop($event)\"\n [cdkDropListLockAxis]=\"'y'\"\n >\n @for (node of visibleFlatTree(); track node.id + '-' + node.order_num) {\n <div\n class=\"node\"\n [style.marginLeft.px]=\"node.depth * 24\"\n [class.dragged]=\"isDragged(node)\"\n cdkDrag\n (cdkDragStarted)=\"dragStarted(node)\"\n (cdkDragEnded)=\"dragEnded()\"\n >\n <div class=\"node-bar\" cdkDragHandle>\n @if (hasChildren(node)) {\n <button\n class=\"collapse-btn\"\n (click)=\"toggleCollapse(node); $event.stopPropagation()\"\n [title]=\"node.collapsed ? '\u0420\u0430\u0437\u0432\u0435\u0440\u043D\u0443\u0442\u044C' : '\u0421\u0432\u0435\u0440\u043D\u0443\u0442\u044C'\"\n >\n {{ node.collapsed ? '\u25B6' : '\u25BC' }}\n </button>\n }\n\n @if (node.title === ROOT_TITLE) {\n <span class=\"root-title\">\u041A\u043E\u0440\u043D\u0435\u0432\u043E\u0439 \u044D\u043B\u0435\u043C\u0435\u043D\u0442</span>\n } @else {\n <div class=\"left-control\">\n <span class=\"grip\">\u22EE\u22EE</span>\n <input class=\"inp title\" [(ngModel)]=\"node.title\" placeholder=\"\u041D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\" />\n <input\n class=\"inp code\"\n [required]=\"true\"\n [(ngModel)]=\"node.code\"\n placeholder=\"code\"\n />\n <input class=\"inp route\" [(ngModel)]=\"node.route\" placeholder=\"route\" />\n <input class=\"inp icon\" [(ngModel)]=\"node.icon\" placeholder=\"icon\" />\n <input class=\"inp roles\" [(ngModel)]=\"node.allowed_roles\" placeholder=\"\u0420\u043E\u043B\u0438\" />\n </div>\n\n <div class=\"depth-controls\">\n <button class=\"btn small\" (click)=\"outdent(node)\">\u2190</button>\n <button class=\"btn small\" (click)=\"indent(node)\">\u2192</button>\n @if (hasChildren(node)) {\n <button class=\"btn small\" (click)=\"outdentBranch(node)\">\u21D0</button>\n <button class=\"btn small\" (click)=\"indentBranch(node)\">\u21D2</button>\n }\n <button class=\"btn small\" (click)=\"deleteItem(node)\">\u0423\u0434\u0430\u043B\u0438\u0442\u044C</button>\n </div>\n }\n </div>\n\n <ng-template cdkDragPreview>\n <div class=\"drag-branch-preview\">\n <div\n class=\"preview-bar\"\n *ngFor=\"let n of draggedBranch()\"\n [style.marginLeft.px]=\"(n.depth - node.depth) * 20\"\n >\n {{ n.title }}\n </div>\n </div>\n </ng-template>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".menu-constructor{display:flex;flex-direction:column;gap:16px;padding:16px;height:calc(100vh - var(--header-height))}.pane{border:1px solid #e2e8f0;border-radius:12px;padding:12px;background:#fff;display:flex;flex-direction:column}.pane.editor{height:100%}.hidden{display:none}.root-title{width:100%}.collapse-btn{background:none;border:none;cursor:pointer;font-size:12px;color:#334155;margin-right:4px;transition:transform .2s ease}.collapse-btn:hover{color:#1e3a8a}.pane-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.pane-header h2{margin:0;font-size:16px}.pane-header .buttons{display:flex;gap:6px}.btn{padding:6px 10px;border-radius:6px;border:1px solid #94a3b8;background:#f8fafc;cursor:pointer;font-size:12px;line-height:1}.btn.primary{border-color:#3b82f6;background:#e0f2fe}.btn.secondary{border-color:#b5b5b5;background:#d1d1d1}.btn.small{padding:2px 6px;margin-left:2px}.btn:hover{background:#e2e8f0}.list-wrapper{flex:1;overflow:auto;min-height:200px}.left-control{gap:6px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.node{border:1px dashed #cbd5e1;border-radius:8px;margin:6px 0;background:#fafafa;padding:4px}.node-bar{display:flex;flex-direction:row;justify-content:space-between;gap:6px;align-items:center;background:#f1f5f9;padding:4px 6px;border-radius:6px}.grip{cursor:grab;text-align:center;color:#475569}.inp{border:1px solid #cbd5e1;width:100%;border-radius:6px;padding:3px 6px;font-size:12px}.depth-controls{display:flex;gap:2px}.node.dragged{background:#e0f2fe;border-color:#3b82f6;opacity:.85}.drag-branch-preview{background:#fff;border:1px solid #94a3b8;box-shadow:0 6px 18px #00000026;border-radius:8px;padding:6px;min-width:160px}.preview-bar{background:#f8fafc;border-left:3px solid #3b82f6;border-radius:4px;margin:3px 0;padding:4px 8px;font-size:12px}.drag-branch-placeholder{padding:6px 0}.placeholder-row{height:32px;margin:3px 0;background:repeating-linear-gradient(-45deg,#e2e8f0,#e2e8f0 6px,#f1f5f9 6px 12px);border-radius:4px}\n"] }]
|
|
558
|
-
}] });
|
|
559
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtcmVnaXN0ZXItYmFzZS9zcmMvbGliL2NvbXBvbmVudHMvbWVudS1jb25zdHJ1Y3Rvci9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1yZWdpc3Rlci1iYXNlL3NyYy9saWIvY29tcG9uZW50cy9tZW51LWNvbnN0cnVjdG9yL3Nwcm9jLW1lbnUtY29uc3RydWN0b3IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hHLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsT0FBTyxFQUVQLGFBQWEsRUFDYixjQUFjLEVBQ2QsV0FBVyxHQUNaLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTlCLE9BQU8sRUFDTCxVQUFVLEVBSVYsY0FBYyxFQUNkLGVBQWUsRUFDZixVQUFVLEdBQ1gsTUFBTSx1Q0FBdUMsQ0FBQztBQUUvQyxPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQzs7O0FBU3pFLE1BQU0sT0FBTyw2QkFBNkI7SUFQMUM7UUFRVSxXQUFNLEdBQUcsTUFBTSxDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDOUMsU0FBSSxHQUFH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Q0FBQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIGNvbXB1dGVkLCBEZXN0cm95UmVmLCBpbmplY3QsIE9uSW5pdCwgb3V0cHV0LCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgQ2RrRHJhZyxcbiAgQ2RrRHJhZ0Ryb3AsXG4gIENka0RyYWdIYW5kbGUsXG4gIENka0RyYWdQcmV2aWV3LFxuICBDZGtEcm9wTGlzdCxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBBc3luY1BpcGUsIE5nRm9yT2YgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTcHJvY0Fic3RyYWN0TWVudUNvbnN0cnVjdG9yU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Nwcm9jLWFic3RyYWN0LW1lbnUtY29uc3RydWN0b3Iuc3RvcmUnO1xuaW1wb3J0IHtcbiAgRU1QVFlfVVVJRCxcbiAgRmxhdE5vZGUsXG4gIElDbHNNZW51SXRlbUlucHV0LFxuICBJTWVudUNvbnN0cnVjdG9yRXJyb3IsXG4gIE1JR1JBVElPTl9ISU5ULFxuICBORVdfSVRFTV9QUkVGSVgsXG4gIFJPT1RfVElUTEUsXG59IGZyb20gJy4vc3RvcmUvc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb25zdHMnO1xuaW1wb3J0IHsgSUNsc01lbnVJdGVtIH0gZnJvbSAnLi4vcGFnZS1tZW51JztcbmltcG9ydCB7IE1FTlVfQ09OU1RSVUNUT1JfU1RPUkVfVE9LRU4gfSBmcm9tICcuL3N0b3JlL3Nwcm9jLW1lbnUudG9rZW5zJztcblxuQENvbXBvbmVudCh7XG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIHNlbGVjdG9yOiAnc3Byb2MtbWVudS1jb25zdHJ1Y3RvcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9zcHJvYy1tZW51LWNvbnN0cnVjdG9yLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vc3Byb2MtbWVudS1jb25zdHJ1Y3Rvci5jb21wb25lbnQubGVzcyddLFxuICBpbXBvcnRzOiBbQ2RrRHJhZywgQ2RrRHJvcExpc3QsIE5nRm9yT2YsIEZvcm1zTW9kdWxlLCBDZGtEcmFnUHJldmlldywgQ2RrRHJhZ0hhbmRsZSwgQXN5bmNQaXBlXSxcbn0pXG5leHBvcnQgY2xhc3MgU3Byb2NNZW51Q29uc3RydWN0b3JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIF9zdG9yZSA9IGluamVjdChNRU5VX0NPTlNUUlVDVE9SX1NUT1JFX1RPS0VOKTtcbiAgcHJpdmF0ZSBfcmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHByb3RlY3RlZCBST09UX1RJVExFID0gUk9PVF9USVRMRTtcbiAgcHJvdGVjdGVkIGxvYWRpbmckID0gdGhpcy5fc3RvcmUubG9hZGluZyQ7XG4gIHByb3RlY3RlZCBvcmlnaW5hbFRyZWU6IE1hcDxzdHJpbmcsIEZsYXROb2RlPiA9IG5ldyBNYXAoW10pO1xuICBwcm90ZWN0ZWQgTUlHUkFUSU9OX0hJTlQgPSBNSUdSQVRJT05fSElOVDtcbiAgcHJpdmF0ZSBkZWxldGVkSWRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIHB1YmxpYyBlcnJvck1zZ091dHB1dCA9IG91dHB1dDxJTWVudUNvbnN0cnVjdG9yRXJyb3I+KCk7XG5cbiAgLy8g0L/Qu9C+0YHQutC+0LUg0L/RgNC10LTRgdGC0LDQstC70LXQvdC40LUg0LjQtdGA0LDRgNGF0LjRh9C10YHQutC+0LPQviDQvNC10L3RjlxuICBwcm90ZWN0ZWQgZmxhdFRyZWUgPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0LXRgtC60LAg0Y3Qu9C10LzQtdC90YLQvtCyLCDQutC+0YLQvtGA0LDRjyDQv9C10YDQtdGC0LDRgdC60LjQstCw0LXRgtGB0Y9cbiAgcHJvdGVjdGVkIGRyYWdnZWRCcmFuY2ggPSBzaWduYWw8RmxhdE5vZGVbXT4oW10pO1xuXG4gIC8vINCy0YvRh9C40YHQu9GP0LXQvNC+0LUg0YHQstC+0LnRgdGC0LLQviwg0LLQvtC30LLRgNCw0YnQsNGO0YnQtdC1INGC0L7Qu9GM0LrQviDQstC40LTQuNC80YvQtSAo0L3QtSDRgdCy0LXRgNC90YPRgtGL0LUpINGN0LvQtdC80LXQvdGC0YtcbiAgcHJvdGVjdGVkIHZpc2libGVGbGF0VHJlZSA9IGNvbXB1dGVkPEZsYXROb2RlW10+KCgpID0+IHtcbiAgICBjb25zdCBmbGF0VHJlZSA9IHRoaXMuZmxhdFRyZWUoKTtcbiAgICByZXR1cm4gdGhpcy5fZ2V0VmlzaWJsZUZyb20oZmxhdFRyZWUpO1xuICB9KTtcblxuICBwcml2YXRlIF9wZW5kaW5nUmVjYWxjID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5fc3RvcmUubWVudUl0ZW1zJFxuICAgICAgLnBpcGUoXG4gICAgICAgIGZpbHRlcigoYXJyKSA9PiBBcnJheS5pc0FycmF5KGFycikgJiYgYXJyLmxlbmd0aCA+IDApLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fcmVmKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgICAgdGhpcy5mbGF0VHJlZS5zZXQodGhpcy5fY29udmVydFRvRmxhdE5vZGUodmFsdWUpKTtcbiAgICAgICAgdGhpcy5vcmlnaW5hbFRyZWUgPSBuZXcgTWFwKHRoaXMuZmxhdFRyZWUoKS5tYXAoKGl0ZW0pID0+IFtpdGVtLmlkLCB7IC4uLml0ZW0gfV0pKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqINCf0LXRgNC10LrQu9GO0YfQsNC10YIg0YHQvtGB0YLQvtGP0L3QuNC1INGB0LLQtdGA0L3Rg9GC0L7RgdGC0Lgg0YPQt9C70LAgKGNvbGxhcHNlL2V4cGFuZClcbiAgICog0J/QvtGB0LvQtSDQuNC30LzQtdC90LXQvdC40Y8g0YHQvtC30LTQsNC10YIg0L3QvtCy0YvQuSDQvNCw0YHRgdC40LIg0LTQu9GPINGC0YDQuNCz0LPQtdGA0LAg0L7QsdC90L7QstC70LXQvdC40Y8g0YHQuNCz0L3QsNC70LBcbiAgICovXG4gIHByb3RlY3RlZCB0b2dnbGVDb2xsYXBzZShub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIG5vZGUuY29sbGFwc2VkID0gIW5vZGUuY29sbGFwc2VkO1xuICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi50aGlzLmZsYXRUcmVlKCldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQndCw0YfQsNC70L4g0L/QtdGA0LXRgtCw0YHQutC40LLQsNC90LjRjzog0YHQvtGF0YDQsNC90Y/QtdGCINCy0YHRjiDQstC10YLQutGDINGD0LfQu9CwLCDQutC+0YLQvtGA0YPRjiDRgtGP0L3Rg9GCXG4gICAqL1xuICBwcm90ZWN0ZWQgZHJhZ1N0YXJ0ZWQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKHRoaXMuZmxhdFRyZWUoKSwgbm9kZSk7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChicmFuY2gpO1xuICB9XG5cbiAgLyoqXG4gICAqINCX0LDQstC10YDRiNC10L3QuNC1INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQvdC40Y86INC+0YfQuNGJ0LDQtdGCINC40L3RhNC+0YDQvNCw0YbQuNGOINC+INGC0LXQutGD0YnQtdC5INCy0LXRgtC60LVcbiAgICovXG4gIHByb3RlY3RlZCBkcmFnRW5kZWQoKTogdm9pZCB7XG4gICAgdGhpcy5kcmFnZ2VkQnJhbmNoLnNldChbXSk7XG4gIH1cblxuICAvKipcbiAgICog0J7RgdC90L7QstC90LDRjyDQu9C+0LPQuNC60LAgZHJhZyZkcm9wINC/0YDQuCDQvtGC0L/Rg9GB0LrQsNC90LjQuCDRjdC70LXQvNC10L3RgtCwXG4gICAqINCe0L/RgNC10LTQtdC70Y/QtdGCINC90L7QstGD0Y4g0L/QvtC30LjRhtC40Y4g0YPQt9C70LAsINC/0LXRgNC10YHRh9C40YLRi9Cy0LDQtdGCINCz0LvRg9Cx0LjQvdGLINC4INGB0LLRj9C30LhcbiAgICovXG4gIHByb3RlY3RlZCBkcm9wKGV2ZW50OiBDZGtEcmFnRHJvcDxGbGF0Tm9kZVtdPik6IHZvaWQge1xuICAgIGNvbnN0IGJlZm9yZSA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IHZpc2libGVCZWZvcmUgPSB0aGlzLl9nZXRWaXNpYmxlRnJvbShiZWZvcmUpO1xuICAgIGNvbnN0IHByZXZJZHggPSBldmVudC5wcmV2aW91c0luZGV4O1xuICAgIGNvbnN0IGN1cnJJZHggPSBldmVudC5jdXJyZW50SW5kZXg7XG5cbiAgICAvLyDQn9C+0LvRg9GH0LDQtdGCINC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80YvQuSDRjdC70LXQvNC10L3RgiDQuNC3INGB0L/QuNGB0LrQsCDQstC40LTQuNC80YvRhVxuICAgIGNvbnN0IGRyYWdnZWRWaXNpYmxlID0gdmlzaWJsZUJlZm9yZVtwcmV2SWR4XTtcbiAgICBpZiAoIWRyYWdnZWRWaXNpYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8g0J3QsNGF0L7QtNC40YIg0LjQvdC00LXQutGBINGD0LfQu9CwINCyINC/0L7Qu9C90L7QvCDQvNCw0YHRgdC40LLQtVxuICAgIGNvbnN0IHN0YXJ0ID0gYmVmb3JlLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gZHJhZ2dlZFZpc2libGUuaWQpO1xuICAgIGlmIChzdGFydCA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyDQodC+0LHQuNGA0LDQtdGCINCy0YHRjiDQstC10YLQutGDLCDQvdCw0YfQuNC90LDRjtGJ0YPRjtGB0Y8g0YEg0L/QtdGA0LXRgtCw0YHQutC40LLQsNC10LzQvtCz0L4g0YPQt9C70LBcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGJlZm9yZSwgYmVmb3JlW3N0YXJ0XSk7XG4gICAgY29uc3QgYnJhbmNoSWRzID0gbmV3IFNldChicmFuY2gubWFwKChuKSA9PiBuLmlkKSk7XG5cbiAgICAvLyDQo9Cx0LjRgNCw0LXRgiDQstC10YLQutGDINC40Lcg0LjRgdGF0L7QtNC90L7Qs9C+INGB0L/QuNGB0LrQsFxuICAgIGNvbnN0IGZ1bGwgPSBiZWZvcmUuZmlsdGVyKChuKSA9PiAhYnJhbmNoSWRzLmhhcyhuLmlkKSk7XG5cbiAgICAvLyDQntC/0YDQtdC00LXQu9GP0LXRgiDQstC40LTQuNC80YvQtSDRjdC70LXQvNC10L3RgtGLINC/0L7RgdC70LUg0YPQtNCw0LvQtdC90LjRjyDQstC10YLQutC4XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMuX2dldFZpc2libGVGcm9tKGZ1bGwpO1xuICAgIGNvbnN0IHByZXZWaXNpYmxlID0gdmlzaWJsZVtjdXJySWR4IC0gMV0gPz8gbnVsbDtcbiAgICBjb25zdCBuZXh0VmlzaWJsZSA9IHZpc2libGVbY3VycklkeF0gPz8gbnVsbDtcblxuICAgIC8vINCY0L3QtNC10LrRgSDQstGB0YLQsNCy0LrQuCDQstC10YLQutC4INCyINC90L7QstGL0Lkg0YHQv9C40YHQvtC6XG4gICAgY29uc3QgaW5zZXJ0ID0gbmV4dFZpc2libGUgPyBmdWxsLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gbmV4dFZpc2libGUuaWQpIDogZnVsbC5sZW5ndGg7XG5cbiAgICAvLyDQoNCw0YHRgdGH0LjRgtGL0LLQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdGC0LDQstC70Y/QtdC80L7QuSDQstC10YLQutC4INCyINC30LDQstC40YHQuNC80L7RgdGC0Lgg0L7RgiDRgdC+0YHQtdC00LXQuVxuICAgIGxldCB0YXJnZXREZXB0aDtcbiAgICBpZiAocHJldlZpc2libGUgJiYgbmV4dFZpc2libGUpIHtcbiAgICAgIHRhcmdldERlcHRoID1cbiAgICAgICAgcHJldlZpc2libGUuZGVwdGggPCBuZXh0VmlzaWJsZS5kZXB0aCA/IHByZXZWaXNpYmxlLmRlcHRoICsgMSA6IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAocHJldlZpc2libGUgJiYgIW5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IHByZXZWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSBpZiAoIXByZXZWaXNpYmxlICYmIG5leHRWaXNpYmxlKSB7XG4gICAgICB0YXJnZXREZXB0aCA9IG5leHRWaXNpYmxlLmRlcHRoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXREZXB0aCA9IDA7XG4gICAgfVxuXG4gICAgLy8g0JLRgdGC0LDQstC70Y/QtdGCINCy0LXRgtC60YMg0LIg0L3QvtCy0L7QtSDQvNC10YHRgtC+XG4gICAgZnVsbC5zcGxpY2UoaW5zZXJ0LCAwLCAuLi5icmFuY2gpO1xuICAgIC8vINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuFxuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIHRhcmdldERlcHRoIC0gYnJhbmNoWzBdLmRlcHRoKTtcblxuICAgIC8vINCf0LvQsNC90LjRgNGD0LXRgiDQv9C10YDQtdGB0YfQtdGCINGB0YLRgNGD0LrRgtGD0YDRiyDQtNC10YDQtdCy0LBcbiAgICB0aGlzLl9zY2hlZHVsZVJlY2FsYyhmdWxsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDIChkZXB0aCkg0LrQvtC90LrRgNC10YLQvdC+0LPQviDRg9C30LvQsCwg0LXRgdC70Lgg0LLQvtC30LzQvtC20L3QvlxuICAgKi9cbiAgcHJvdGVjdGVkIGluZGVudChub2RlOiBGbGF0Tm9kZSk6IHZvaWQge1xuICAgIGNvbnN0IGFyciA9IFsuLi50aGlzLmZsYXRUcmVlKCldO1xuICAgIGNvbnN0IGluZGV4ID0gYXJyLmluZGV4T2Yobm9kZSk7XG4gICAgaWYgKGluZGV4ID09PSAtMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICAvLyDQmNGJ0LXRgiDQv9C+0LTRhdC+0LTRj9GJ0LXQs9C+INGA0L7QtNC40YLQtdC70Y8g0YEg0L3Rg9C20L3QvtC5INCz0LvRg9Cx0LjQvdC+0LlcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbm9kZS5kZXB0aCA9IHByb3Bvc2VkRGVwdGg7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMgKGRlcHRoKSDRg9C30LvQsCArINC/0L4g0LLQvtC30LzQvtC20L3QvtGB0YLQuCDQv9GA0LXQstGA0LDRidCw0LXRgiDQtdCz0L4g0LIg0YDQvtC00LjRgtC10LvRj1xuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnQobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEgfHwgbm9kZS5kZXB0aCA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5vZGUuZGVwdGggPSBNYXRoLm1heCgwLCBub2RlLmRlcHRoIC0gMSk7XG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9Cy0LXQu9C40YfQuNCy0LDQtdGCINCz0LvRg9Cx0LjQvdGDINCy0YHQtdC5INCy0LXRgtC60Lgg0YPQt9C70LAgKNCy0LzQtdGB0YLQtSDRgSDQv9C+0YLQvtC80LrQsNC80LgpXG4gICAqL1xuICBwcm90ZWN0ZWQgaW5kZW50QnJhbmNoKG5vZGU6IEZsYXROb2RlKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG4gICAgY29uc3QgaW5kZXggPSBhcnIuaW5kZXhPZihub2RlKTtcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHByb3Bvc2VkRGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICBjb25zdCBwYXJlbnRDYW5kaWRhdGUgPSBbLi4uYXJyXVxuICAgICAgLnNsaWNlKDAsIGluZGV4KVxuICAgICAgLnJldmVyc2UoKVxuICAgICAgLmZpbmQoKG4pID0+IG4uZGVwdGggPT09IHByb3Bvc2VkRGVwdGggLSAxKTtcblxuICAgIGlmICghcGFyZW50Q2FuZGlkYXRlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgYnJhbmNoID0gdGhpcy5fY29sbGVjdEJyYW5jaChhcnIsIG5vZGUpO1xuICAgIHRoaXMuX2FwcGx5RGVwdGhTaGlmdChicmFuY2gsIDEpO1xuXG4gICAgdGhpcy5fc2NoZWR1bGVSZWNhbGMoYXJyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQo9C80LXQvdGM0YjQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10Lkg0LLQtdGC0LrQuCDRg9C30LvQsFxuICAgKi9cbiAgcHJvdGVjdGVkIG91dGRlbnRCcmFuY2gobm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBicmFuY2ggPSB0aGlzLl9jb2xsZWN0QnJhbmNoKGFyciwgbm9kZSk7XG4gICAgdGhpcy5fYXBwbHlEZXB0aFNoaWZ0KGJyYW5jaCwgLTEpO1xuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0J/RgNC+0LLQtdGA0Y/QtdGCLCDQtdGB0YLRjCDQu9C4INGDINGD0LfQu9CwINC00L7Rh9C10YDQvdC40LUg0Y3Qu9C10LzQtdC90YLRi1xuICAgKi9cbiAgcHJvdGVjdGVkIGhhc0NoaWxkcmVuKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYXJyID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgIGNvbnN0IGlkeCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpZHggPT09IC0xKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSBpZHggKyAxOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBuZXh0ID0gYXJyW2ldO1xuICAgICAgaWYgKG5leHQuZGVwdGggPD0gbm9kZS5kZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlLmRlcHRoICsgMSkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgcHJvdGVjdGVkIHNhdmUoKTogdm9pZCB7XG4gICAgLy8g0KTQu9Cw0LMg0LTQu9GPINC70L7Qs9Cz0LjRgNC+0LLQsNC90LjRjyDQvdCwINCy0YDQtdC80Y8g0L7RgtC70LDQtNC60LhcbiAgICBjb25zdCBsb2dnaW5nID0gZmFsc2U7XG5cbiAgICBjb25zdCBjaGFuZ2VkRWxlbWVudHMgPSB0aGlzLmZsYXRUcmVlKCkuZmlsdGVyKChuZXdJdGVtKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW5hbEl0ZW0gPSB0aGlzLm9yaWdpbmFsVHJlZS5nZXQobmV3SXRlbS5pZCk7XG5cbiAgICAgIC8vINCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YJcbiAgICAgIGlmICghb3JpZ2luYWxJdGVtKSB7XG4gICAgICAgIGlmIChsb2dnaW5nKSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYNCd0L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIgJHtuZXdJdGVtLnRpdGxlfWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHtcbiAgICAgICAgb3JkZXJfbnVtOiBvcmlnaW5hbE9yZGVyTnVtLFxuICAgICAgICBpZF9wYXJlbnQ6IG9yaWdpbmFsSWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBvcmlnaW5hbFRpdGxlLFxuICAgICAgICBhbGxvd2VkX3JvbGVzOiBvcmlnaW5hbFJvbGVzLFxuICAgICAgICBjb2RlOiBvcmlnaW5hbENvZGUsXG4gICAgICAgIHJvdXRlOiBvcmlnaW5hbFJvdXRlLFxuICAgICAgICBpY29uOiBvcmlnaW5hbEljb24sXG4gICAgICB9ID0gb3JpZ2luYWxJdGVtO1xuXG4gICAgICBjb25zdCB7XG4gICAgICAgIG9yZGVyX251bTogbmV3T3JkZXJOdW0sXG4gICAgICAgIGlkX3BhcmVudDogbmV3SWRQYXJlbnQsXG4gICAgICAgIHRpdGxlOiBuZXdUaXRsZSxcbiAgICAgICAgYWxsb3dlZF9yb2xlczogbmV3Um9sZXMsXG4gICAgICAgIGNvZGU6IG5ld0NvZGUsXG4gICAgICAgIHJvdXRlOiBuZXdSb3V0ZSxcbiAgICAgICAgaWNvbjogbmV3SWNvbixcbiAgICAgIH0gPSBuZXdJdGVtO1xuXG4gICAgICBjb25zdCBjaGFuZ2VkRmllbGRzOiBzdHJpbmdbXSA9IFtdO1xuXG4gICAgICBpZiAob3JpZ2luYWxPcmRlck51bSAhPT0gbmV3T3JkZXJOdW0pIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBvcmRlcl9udW06ICR7b3JpZ2luYWxPcmRlck51bX0g4oaSICR7bmV3T3JkZXJOdW19YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxJZFBhcmVudCAhPT0gbmV3SWRQYXJlbnQpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBpZF9wYXJlbnQ6ICR7b3JpZ2luYWxJZFBhcmVudH0g4oaSICR7bmV3SWRQYXJlbnR9YCk7XG4gICAgICB9XG4gICAgICBpZiAob3JpZ2luYWxUaXRsZSAhPT0gbmV3VGl0bGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGB0aXRsZTogJHtvcmlnaW5hbFRpdGxlfSDihpIgJHtuZXdUaXRsZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbENvZGUgIT09IG5ld0NvZGUpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBjb2RlOiAke29yaWdpbmFsQ29kZX0g4oaSICR7bmV3Q29kZX1gKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmlnaW5hbFJvdXRlICE9PSBuZXdSb3V0ZSkge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYHJvdXRlOiAke29yaWdpbmFsUm91dGV9IOKGkiAke25ld1JvdXRlfWApO1xuICAgICAgfVxuICAgICAgaWYgKG9yaWdpbmFsSWNvbiAhPT0gbmV3SWNvbikge1xuICAgICAgICBjaGFuZ2VkRmllbGRzLnB1c2goYGljb246ICR7b3JpZ2luYWxJY29ufSDihpIgJHtuZXdJY29ufWApO1xuICAgICAgfVxuICAgICAgaWYgKEpTT04uc3RyaW5naWZ5KG9yaWdpbmFsUm9sZXMpICE9PSBKU09OLnN0cmluZ2lmeShuZXdSb2xlcykpIHtcbiAgICAgICAgY2hhbmdlZEZpZWxkcy5wdXNoKGBhbGxvd2VkX3JvbGVzOiAke29yaWdpbmFsUm9sZXN9IOKGkiAke25ld1JvbGVzfWApO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2hhbmdlZEZpZWxkcy5sZW5ndGggPiAwO1xuICAgIH0pO1xuXG4gICAgY29uc3QgaXNCbGFuayA9IChzOiB1bmtub3duKTogYm9vbGVhbiA9PiB0eXBlb2YgcyAhPT0gJ3N0cmluZycgfHwgcy50cmltKCkgPT09ICcnO1xuXG4gICAgY29uc3QgaXNSb3V0ZVZhbGlkID0gKHsgcm91dGUsIGNvZGUgfTogRmxhdE5vZGUpOiBib29sZWFuID0+IHtcbiAgICAgIC8vIHJvdXRlINGB0YfQuNGC0LDQtdGC0YHRjyDQt9Cw0LTQsNC90L3Ri9C8LCDRgtC+0LvRjNC60L4g0LXRgdC70Lgg0Y3RgtC+INC90LXQv9GD0YHRgtCw0Y8g0YHRgtGA0L7QutCwXG4gICAgICBjb25zdCBoYXNSb3V0ZSA9IHJvdXRlLnRyaW0oKSAhPT0gJyc7XG5cbiAgICAgIHJldHVybiAhaGFzUm91dGUgfHwgcm91dGUgPT09IGNvZGU7XG4gICAgfTtcblxuICAgIGNvbnN0IGludmFsaWRDb2RlVGl0bGVzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGNvbnN0IGludmFsaWRSb3V0ZVRpdGxlczogRmxhdE5vZGVbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBlbCBvZiBjaGFuZ2VkRWxlbWVudHMpIHtcbiAgICAgIGlmIChpc0JsYW5rKGVsLmNvZGUpKSB7XG4gICAgICAgIGludmFsaWRDb2RlVGl0bGVzLnB1c2goZWwudGl0bGUgPz8gJyjQsdC10Lcg0L3QsNC30LLQsNC90LjRjyknKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1JvdXRlVmFsaWQoZWwpKSB7XG4gICAgICAgIGludmFsaWRSb3V0ZVRpdGxlcy5wdXNoKGVsKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaW52YWxpZENvZGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0LfQsNC/0L7Qu9C90LXQvdGLLiA8L2JyPlxuICAgICAgICDQmNGB0L/RgNCw0LLRjNGC0LUg0YHQu9C10LTRg9GO0YnQuNC1INC/0L7Qu9GPOiA8L2JyPlxuICAgICAgICAke2ludmFsaWRDb2RlVGl0bGVzLm1hcCgodCkgPT4gYC0gJHt0fWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpbnZhbGlkUm91dGVUaXRsZXMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5lcnJvck1zZ091dHB1dC5lbWl0KHtcbiAgICAgICAgbGFiZWw6ICfQmtC+0L3RgdGC0YDRg9C60YLQvtGAINC80LXQvdGOJyxcbiAgICAgICAgYXBwZWFyYW5jZTogJ25lZ2F0aXZlJyxcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHhzcy9uby1taXhlZC1odG1sXG4gICAgICAgIGNvbnRlbnQ6IGDQktGB0LUg0L/QvtC70Y8gY29kZSDQtNC+0LvQttC90Ysg0LHRi9GC0Ywg0YDQsNCy0L3RiyDQv9C+0LvRjiByb3V0ZS4gPC9icj5cbiAgICAgICAg0JjRgdC/0YDQsNCy0YzRgtC1INGB0LvQtdC00YPRjtGJ0LjQtSDQv9C+0LvRjzogPC9icj5cbiAgICAgICAgJHtpbnZhbGlkUm91dGVUaXRsZXMubWFwKCh0KSA9PiBgLSAke3QudGl0bGV9ICgke3QuY29kZX0gfCAke3Qucm91dGV9KWApLmpvaW4oJzwvYnI+Jyl9XG4gICAgICAgIGAsXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGVsUm91dGUgPSAocm91dGU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwgPT4gKHJvdXRlID09PSAnJyA/IG51bGwgOiByb3V0ZSk7XG5cbiAgICBjb25zdCBub3JtYWxpemVFbGVtZW50ID0gKGVsOiBGbGF0Tm9kZSk6IElDbHNNZW51SXRlbUlucHV0ID0+ICh7XG4gICAgICB0aXRsZTogZWwudGl0bGUudHJpbSgpLFxuICAgICAgcm91dGU6IGVsUm91dGUoZWwucm91dGUudHJpbSgpKSxcbiAgICAgIGNvZGU6IGVsLmNvZGUsXG4gICAgICBpY29uOiBlbC5pY29uLFxuICAgICAgb3JkZXJfbnVtOiBlbC5vcmRlcl9udW0sXG4gICAgICBhbGxvd2VkX3JvbGVzOiBlbC5hbGxvd2VkX3JvbGVzXG4gICAgICAgID8gZWwuYWxsb3dlZF9yb2xlcy5zcGxpdCgnLCcpLm1hcCgodmFsdWUpID0+IHZhbHVlLnRyaW0oKSlcbiAgICAgICAgOiBudWxsLFxuICAgICAgaWRfcGFyZW50OiBlbC5pZF9wYXJlbnQsXG4gICAgfSk7XG5cbiAgICBjb25zdCBvYmplY3RzVG9TYXZlID0gY2hhbmdlZEVsZW1lbnRzXG4gICAgICAuZmlsdGVyKCh7IGlkIH0pID0+ICFpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWwpID0+ICh7XG4gICAgICAgIF9zZXQ6IG5vcm1hbGl6ZUVsZW1lbnQoZWwpLFxuICAgICAgICB3aGVyZTogeyBpZDogeyBfZXE6IGVsLmlkIH0gfSxcbiAgICAgIH0pKTtcblxuICAgIGNvbnN0IG9iamVjdHNUb0luc2VydCA9IGNoYW5nZWRFbGVtZW50c1xuICAgICAgLmZpbHRlcigoeyBpZCB9KSA9PiBpZC5pbmNsdWRlcyhORVdfSVRFTV9QUkVGSVgpKVxuICAgICAgLm1hcCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBlbGVtZW50LmlkID0gRU1QVFlfVVVJRDtcblxuICAgICAgICByZXR1cm4gbm9ybWFsaXplRWxlbWVudChlbGVtZW50KTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgb2JqZWN0c1RvRGVsZXRlID0gWy4uLnRoaXMuZGVsZXRlZElkc107XG5cbiAgICBpZiAobG9nZ2luZykge1xuICAgICAgY29uc29sZS5sb2coYNCY0LfQvNC10L3QtdC90L3Ri9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9TYXZlKTtcbiAgICAgIGNvbnNvbGUubG9nKGDQndC+0LLRi9C1INGN0LvQtdC80LXQvdGC0YtgLCBvYmplY3RzVG9JbnNlcnQpO1xuICAgICAgY29uc29sZS5sb2coJ9Cj0LTQsNC70ZHQvdC90YvQtSDRjdC70LXQvNC10L3RgtGLOicsIG9iamVjdHNUb0RlbGV0ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fc3RvcmUudXBkYXRlTWVudShvYmplY3RzVG9TYXZlLCBvYmplY3RzVG9JbnNlcnQsIG9iamVjdHNUb0RlbGV0ZSk7XG5cbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBoYW5kbGVGb2xkKHN0YXRlOiBib29sZWFuKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBlbGVtZW50IG9mIHRoaXMuZmxhdFRyZWUoKSkge1xuICAgICAgaWYgKGVsZW1lbnQudGl0bGUgIT09IFJPT1RfVElUTEUpIHtcbiAgICAgICAgZWxlbWVudC5jb2xsYXBzZWQgPSBzdGF0ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmZsYXRUcmVlLnNldChbLi4udGhpcy5mbGF0VHJlZSgpXSk7XG4gIH1cblxuICAvKipcbiAgICog0KPQtNCw0LvRj9C10YIg0L7QtNC40L0g0Y3Qu9C10LzQtdC90YIg0LjQtyDQtNC10YDQtdCy0LAuXG4gICAqINCf0L7RgtC+0LzQutC4INGB0YLQsNC90L7QstGP0YLRgdGPINC00L7Rh9C10YDQvdC40LzQuCDRjdC70LXQvNC10L3RgtCw0LzQuCDRgNC+0LTQuNGC0LXQu9GPINGD0LTQsNC70ZHQvdC90L7Qs9C+INGD0LfQu9CwLlxuICAgKi9cbiAgcHJvdGVjdGVkIGRlbGV0ZUl0ZW0obm9kZTogRmxhdE5vZGUpOiB2b2lkIHtcbiAgICBjb25zdCBhcnIgPSBbLi4udGhpcy5mbGF0VHJlZSgpXTtcbiAgICBjb25zdCBpbmRleCA9IGFyci5pbmRleE9mKG5vZGUpO1xuICAgIGlmIChpbmRleCA9PT0gLTEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBwYXJlbnRJZCA9IG5vZGUuaWRfcGFyZW50O1xuICAgIGNvbnN0IG5vZGVEZXB0aCA9IG5vZGUuZGVwdGg7XG5cbiAgICAvLyDQndCw0YXQvtC00LjQvCDQv9C+0YLQvtC80LrQvtCyLCDQutC+0YLQvtGA0YvQtSDQsdGL0LvQuCDQvdCw0L/RgNGP0LzRg9GOINC/0L7QtCDRjdGC0LjQvCDRg9C30LvQvtC8XG4gICAgZm9yIChsZXQgaSA9IGluZGV4ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbmV4dCA9IGFycltpXTtcbiAgICAgIGlmIChuZXh0LmRlcHRoIDw9IG5vZGVEZXB0aCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChuZXh0LmRlcHRoID09PSBub2RlRGVwdGggKyAxKSB7XG4gICAgICAgIC8vINC/0L7RgtC+0LzQvtC6INGB0YLQsNC90L7QstC40YLRgdGPINGA0LXQsdGR0L3QutC+0Lwg0YDQvtC00LjRgtC10LvRjyDRg9C00LDQu9GR0L3QvdC+0LPQviDRg9C30LvQsFxuICAgICAgICBuZXh0LmlkX3BhcmVudCA9IHBhcmVudElkID8/IG51bGw7XG4gICAgICAgIG5leHQuZGVwdGggPSBub2RlRGVwdGg7IC8vINC/0L7QtNC90LjQvNCw0LXQvCDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgIH0gZWxzZSBpZiAobmV4dC5kZXB0aCA+IG5vZGVEZXB0aCArIDEpIHtcbiAgICAgICAgLy8g0L/QvtC00L3QuNC80LDQtdC8INC+0YHRgtCw0LvRjNC90YvQtSDQvdCwINC+0LTQuNC9INGD0YDQvtCy0LXQvdGMINCy0LLQtdGA0YVcbiAgICAgICAgbmV4dC5kZXB0aCAtPSAxO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vINCj0LTQsNC70Y/QtdC8INGB0LDQvCDRjdC70LXQvNC10L3RglxuICAgIGFyci5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgLy8g0JXRgdC70LggaWQg0L3QtSDQstGA0LXQvNC10L3QvdGL0Lkg4oCUINC00L7QsdCw0LLQu9GP0LXQvCDQsiDRgdC/0LjRgdC+0Log0L3QsCDRg9C00LDQu9C10L3QuNC1XG4gICAgaWYgKCFub2RlLmlkLmluY2x1ZGVzKE5FV19JVEVNX1BSRUZJWCkpIHtcbiAgICAgIHRoaXMuZGVsZXRlZElkcy5wdXNoKG5vZGUuaWQpO1xuICAgIH1cblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0JTQvtCx0LDQstC70Y/QtdGCINC90L7QstGL0Lkg0Y3Qu9C10LzQtdC90YIg0LIg0LTQtdGA0LXQstC+LlxuICAgKiDQn9C+INGD0LzQvtC70YfQsNC90LjRjiDQvtC9INGB0L7Qt9C00LDRkdGC0YHRjyDQutCw0Log0LTQvtGH0LXRgNC90LjQuSDRjdC70LXQvNC10L3RgiByb290LlxuICAgKi9cbiAgcHJvdGVjdGVkIGFkZE5ld0l0ZW0oKTogdm9pZCB7XG4gICAgY29uc3QgYXJyID0gWy4uLnRoaXMuZmxhdFRyZWUoKV07XG5cbiAgICBjb25zdCByb290Tm9kZSA9IGFyci5maW5kKChuKSA9PiBuLnRpdGxlID09PSB0aGlzLlJPT1RfVElUTEUpO1xuXG4gICAgaWYgKCFyb290Tm9kZSkge1xuICAgICAgY29uc29sZS5lcnJvcignUm9vdCDRjdC70LXQvNC10L3RgiDQvdC1INC90LDQudC00LXQvS4g0J3QvtCy0YvQuSDQv9GD0L3QutGCINC90LUg0LzQvtC20LXRgiDQsdGL0YLRjCDQtNC+0LHQsNCy0LvQtdC9LicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld05vZGU6IEZsYXROb2RlID0ge1xuICAgICAgaWQ6IGAke05FV19JVEVNX1BSRUZJWH0ke2NyeXB0by5yYW5kb21VVUlEKCl9YCxcbiAgICAgIGlkX3BhcmVudDogcm9vdE5vZGUuaWQsXG4gICAgICB0aXRsZTogJ9Cd0L7QstGL0Lkg0L/Rg9C90LrRgiDQvNC10L3RjicsXG4gICAgICByb3V0ZTogJycsXG4gICAgICBpY29uOiAnJyxcbiAgICAgIG9yZGVyX251bTogMSxcbiAgICAgIGFsbG93ZWRfcm9sZXM6IG51bGwsXG4gICAgICBjb2xsYXBzZWQ6IHRydWUsXG4gICAgICBjb2RlOiAnJyxcbiAgICAgIGRlcHRoOiByb290Tm9kZS5kZXB0aCArIDEsXG4gICAgfTtcblxuICAgIGNvbnN0IGluc2VydEluZGV4ID0gYXJyLmZpbmRJbmRleCgobikgPT4gbi5pZCA9PT0gcm9vdE5vZGUuaWQpICsgMTtcbiAgICBhcnIuc3BsaWNlKGluc2VydEluZGV4LCAwLCBuZXdOb2RlKTtcblxuICAgIHRoaXMuX3NjaGVkdWxlUmVjYWxjKGFycik7XG4gIH1cblxuICAvKipcbiAgICog0KHQsdGA0LDRgdGL0LLQsNC10YIg0YLQtdC60YPRidC10LUg0YHQvtGB0YLQvtGP0L3QuNC1INCyINC40YHRhdC+0LTQvdC+0LVcbiAgICovXG4gIHByb3RlY3RlZCByZXNldCgpOiB2b2lkIHtcbiAgICBjb25zdCBvcmlnaW5hbE1lbnUgPSBzdHJ1Y3R1cmVkQ2xvbmUodGhpcy5fc3RvcmUub3JpZ2luYWxNZW51KTtcbiAgICB0aGlzLmZsYXRUcmVlLnNldCh0aGlzLl9jb252ZXJ0VG9GbGF0Tm9kZShvcmlnaW5hbE1lbnUpKTtcbiAgICB0aGlzLmRlbGV0ZWRJZHMgPSBbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIsINC90LDRhdC+0LTQuNGC0YHRjyDQu9C4INGN0LvQtdC80LXQvdGCINCyINGC0LXQutGD0YnQtdC5INC/0LXRgNC10YLQsNGB0LrQuNCy0LDQtdC80L7QuSDQstC10YLQutC1XG4gICAqL1xuICBwcm90ZWN0ZWQgaXNEcmFnZ2VkKG5vZGU6IEZsYXROb2RlKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZHJhZ2dlZEJyYW5jaCgpLnNvbWUoKG4pID0+IG4uaWQgPT09IG5vZGUuaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0L7QsdC40YDQsNC10YIg0LLRgdGOINCy0LXRgtC60YMg0Y3Qu9C10LzQtdC90YLQvtCyINC90LDRh9C40L3QsNGPINGBINGD0LrQsNC30LDQvdC90L7Qs9C+INGD0LfQu9CwICjQstC60LvRjtGH0LDRjyDQv9C+0YLQvtC80LrQvtCyKVxuICAgKi9cbiAgcHJpdmF0ZSBfY29sbGVjdEJyYW5jaChhcnI6IEZsYXROb2RlW10sIHJvb3Q6IEZsYXROb2RlKTogRmxhdE5vZGVbXSB7XG4gICAgY29uc3Qgc3RhcnQgPSBhcnIuaW5kZXhPZihyb290KTtcbiAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IGJyYW5jaDogRmxhdE5vZGVbXSA9IFt7IC4uLnJvb3QgfV07XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0ICsgMTsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgbiA9IGFycltpXTtcbiAgICAgIGlmIChuLmRlcHRoID4gcm9vdC5kZXB0aCkge1xuICAgICAgICBicmFuY2gucHVzaChuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYnJhbmNoO1xuICB9XG5cbiAgLyoqXG4gICAqINCh0LTQstC40LPQsNC10YIg0LPQu9GD0LHQuNC90YMg0LLRgdC10YUg0Y3Qu9C10LzQtdC90YLQvtCyINCy0LXRgtC60Lgg0L3QsCDRg9C60LDQt9Cw0L3QvdGD0Y4g0YDQsNC30L3QuNGG0YNcbiAgICog0J3QtSDQtNC+0L/Rg9GB0LrQsNC10YIg0L7RgtGA0LjRhtCw0YLQtdC70YzQvdGL0YUg0LPQu9GD0LHQuNC9XG4gICAqL1xuICBwcml2YXRlIF9hcHBseURlcHRoU2hpZnQoYnJhbmNoOiBGbGF0Tm9kZVtdLCBkaWZmOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoZGlmZiA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG4gb2YgYnJhbmNoKSB7XG4gICAgICBuLmRlcHRoID0gTWF0aC5tYXgoMCwgbi5kZXB0aCArIGRpZmYpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0LXQvtCx0YDQsNC30YPQtdGCINC40LXRgNCw0YDRhdC40YfQtdGB0LrQuNC5IEpTT04g0LIg0L/Qu9C+0YHQutC40Lkg0LzQsNGB0YHQuNCyIEZsYXROb2RlW11cbiAgICog0KHQvtGF0YDQsNC90Y/QtdGCINC/0L7RgNGP0LTQvtC6INGN0LvQtdC80LXQvdGC0L7QsiDQuCDQuNGFINCy0LvQvtC20LXQvdC90L7RgdGC0YxcbiAgICovXG4gIHByaXZhdGUgX2NvbnZlcnRUb0ZsYXROb2RlKGRhdGE6IElDbHNNZW51SXRlbVtdKTogRmxhdE5vZGVbXSB7XG4gICAgLy8g0JPQu9GD0LHQvtC60LDRjyDQutC+0L/QuNGPLCDRh9GC0L7QsdGLINC90LUg0L/QvtGA0YLQuNGC0Ywg0L7RgNC40LPQuNC90LDQu1xuICAgIGNvbnN0IGNsb25lZCA9IHN0cnVjdHVyZWRDbG9uZShkYXRhKTtcblxuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBJQ2xzTWVudUl0ZW0+KCk7XG4gICAgY29uc3Qgcm9vdHM6IElDbHNNZW51SXRlbVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgY2xvbmVkKSB7XG4gICAgICBtYXAuc2V0KGl0ZW0uaWQsIGl0ZW0pO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgaXRlbSBvZiBjbG9uZWQpIHtcbiAgICAgIGlmIChpdGVtLmlkX3BhcmVudCAmJiBtYXAuaGFzKGl0ZW0uaWRfcGFyZW50KSkge1xuICAgICAgICBjb25zdCBwYXJlbnQgPSBtYXAuZ2V0KGl0ZW0uaWRfcGFyZW50KSE7XG4gICAgICAgIGlmICghcGFyZW50LmNoaWxkcmVuKSB7XG4gICAgICAgICAgcGFyZW50LmNoaWxkcmVuID0gW107XG4gICAgICAgIH1cbiAgICAgICAgcGFyZW50LmNoaWxkcmVuLnB1c2goaXRlbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByb290cy5wdXNoKGl0ZW0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGZsYXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCB3YWxrID0gKG5vZGU6IElDbHNNZW51SXRlbSwgZGVwdGg6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgZmxhdC5wdXNoKHtcbiAgICAgICAgaWQ6IG5vZGUuaWQsXG4gICAgICAgIGlkX3BhcmVudDogbm9kZS5pZF9wYXJlbnQsXG4gICAgICAgIHRpdGxlOiBub2RlLnRpdGxlID8/ICcnLFxuICAgICAgICByb3V0ZTogbm9kZS5yb3V0ZSA/PyAnJyxcbiAgICAgICAgaWNvbjogbm9kZS5pY29uID8/ICcnLFxuICAgICAgICBvcmRlcl9udW06IG5vZGUub3JkZXJfbnVtID8/IDAsXG4gICAgICAgIGFsbG93ZWRfcm9sZXM6IG5vZGUuYWxsb3dlZF9yb2xlcz8uam9pbignLCcpID8/IG51bGwsXG4gICAgICAgIGNvbGxhcHNlZDogbm9kZS50aXRsZSAhPT0gUk9PVF9USVRMRSxcbiAgICAgICAgY29kZTogbm9kZS5jb2RlID8/ICcnLFxuICAgICAgICBkZXB0aCxcbiAgICAgIH0pO1xuXG4gICAgICBpZiAobm9kZS5jaGlsZHJlbj8ubGVuZ3RoKSB7XG4gICAgICAgIGNvbnN0IHNvcnRlZENoaWxkcmVuID0gWy4uLm5vZGUuY2hpbGRyZW5dLnNvcnQoXG4gICAgICAgICAgKGEsIGIpID0+IChhLm9yZGVyX251bSA/PyAwKSAtIChiLm9yZGVyX251bSA/PyAwKVxuICAgICAgICApO1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIHNvcnRlZENoaWxkcmVuKSB7XG4gICAgICAgICAgd2FsayhjaGlsZCwgZGVwdGggKyAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBjb25zdCBzb3J0ZWRSb290cyA9IFsuLi5yb290c10uc29ydCgoYSwgYikgPT4gKGEub3JkZXJfbnVtID8/IDApIC0gKGIub3JkZXJfbnVtID8/IDApKTtcbiAgICBmb3IgKGNvbnN0IHJvb3Qgb2Ygc29ydGVkUm9vdHMpIHtcbiAgICAgIHdhbGsocm9vdCwgMCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZsYXQ7XG4gIH1cblxuICAvKipcbiAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0YHQv9C40YHQvtC6INCy0LjQtNC40LzRi9GFINGN0LvQtdC80LXQvdGC0L7QsiDQvdCwINC+0YHQvdC+0LLQtSDRhNC70LDQs9C+0LIgY29sbGFwc2VkXG4gICAqINCY0YHQv9C+0LvRjNC30YPQtdGCINGB0YLQtdC6INC00LvRjyDQvtGC0YHQu9C10LbQuNCy0LDQvdC40Y8g0YHQstC10YDQvdGD0YLQvtGB0YLQuCDQvdCwINC60LDQttC00L7QvCDRg9GA0L7QstC90LVcbiAgICovXG4gIHByaXZhdGUgX2dldFZpc2libGVGcm9tKGFycjogRmxhdE5vZGVbXSB8ICgoKSA9PiBGbGF0Tm9kZVtdKSk6IEZsYXROb2RlW10ge1xuICAgIGNvbnN0IHNvdXJjZSA9IHR5cGVvZiBhcnIgPT09ICdmdW5jdGlvbicgPyBhcnIoKSA6IGFycjtcbiAgICBjb25zdCBvdXQ6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjb2xsYXBzZWRTdGFjazogYm9vbGVhbltdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG4gb2Ygc291cmNlKSB7XG4gICAgICB3aGlsZSAoY29sbGFwc2VkU3RhY2subGVuZ3RoID4gbi5kZXB0aCkge1xuICAgICAgICBjb2xsYXBzZWRTdGFjay5wb3AoKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb2xsYXBzZWRTdGFjay5pbmNsdWRlcyh0cnVlKSkge1xuICAgICAgICBvdXQucHVzaChuKTtcbiAgICAgICAgY29sbGFwc2VkU3RhY2tbbi5kZXB0aF0gPSAhIW4uY29sbGFwc2VkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvdXQ7XG4gIH1cblxuICAvKipcbiAgICog0J/QtdGA0LXRgdGH0LjRgtGL0LLQsNC10YIgb3JkZXJfbnVtINC4IGlkX3BhcmVudCDRgyDQstGB0LXRhSDRjdC70LXQvNC10L3RgtC+0LIg0LzQsNGB0YHQuNCy0LBcbiAgICog0J/QvtGB0LvQtSDQv9C10YDQtdC80LXRidC10L3QuNC5INC/0L7QtNC00LXRgNC20LjQstCw0LXRgiDQutC+0YDRgNC10LrRgtC90YPRjiDRgdGC0YDRg9C60YLRg9GA0YMg0LTQtdGA0LXQstCwXG4gICAqIG9yZGVyX251bSDQvdCw0LfQvdCw0YfQsNC10YLRgdGPINC+0YLQvdC+0YHQuNGC0LXQu9GM0L3QviDRgNC+0LTQuNGC0LXQu9GPICgxLi5OKVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVjYWxjdWxhdGVUcmVlKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudHM6IEZsYXROb2RlW10gPSBbXTtcbiAgICBjb25zdCBjaGlsZENvdW50ZXJzID0gbmV3IE1hcDxzdHJpbmcgfCBudWxsLCBudW1iZXI+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG5vZGUgb2YgYXJyKSB7XG4gICAgICB3aGlsZSAocGFyZW50cy5sZW5ndGggPiAwICYmIHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXS5kZXB0aCA+PSBub2RlLmRlcHRoKSB7XG4gICAgICAgIHBhcmVudHMucG9wKCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBhcmVudCA9IHBhcmVudHMubGVuZ3RoID4gMCA/IHBhcmVudHNbcGFyZW50cy5sZW5ndGggLSAxXSA6IG51bGw7XG4gICAgICBub2RlLmlkX3BhcmVudCA9IHBhcmVudCA/IHBhcmVudC5pZCA6IG51bGw7XG5cbiAgICAgIC8vINCy0YvRh9C40YHQu9GP0LXQvCDQv9C+0YDRj9C00LrQvtCy0YvQuSDQvdC+0LzQtdGAINGB0YDQtdC00Lgg0LHRgNCw0YLRjNC10LJcbiAgICAgIGlmIChub2RlLnRpdGxlICE9PSBST09UX1RJVExFKSB7XG4gICAgICAgIGNvbnN0IHBhcmVudElkID0gbm9kZS5pZF9wYXJlbnQgPz8gbnVsbDtcbiAgICAgICAgY29uc3QgY3VycmVudENvdW50ID0gY2hpbGRDb3VudGVycy5nZXQocGFyZW50SWQpID8/IDE7XG4gICAgICAgIG5vZGUub3JkZXJfbnVtID0gY3VycmVudENvdW50O1xuICAgICAgICBjaGlsZENvdW50ZXJzLnNldChwYXJlbnRJZCwgY3VycmVudENvdW50ICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHBhcmVudHMucHVzaChub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICog0JDRgdC40L3RhdGA0L7QvdC90L4g0L/Qu9Cw0L3QuNGA0YPQtdGCINC/0LXRgNC10YHRh9C10YIg0LTQtdGA0LXQstCwINGH0LXRgNC10LcgcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG4gICAqINCt0YLQviDQv9GA0LXQtNC+0YLQstGA0LDRidCw0LXRgiDQvNC90L7QttC10YHRgtCy0LXQvdC90YvQtSDQu9C40YjQvdC40LUg0L/QtdGA0LXRgdGH0LXRgtGLINC/0YDQuCDRh9Cw0YHRgtGL0YUg0LjQt9C80LXQvdC10L3QuNGP0YVcbiAgICovXG4gIHByaXZhdGUgX3NjaGVkdWxlUmVjYWxjKGFycjogRmxhdE5vZGVbXSk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9wZW5kaW5nUmVjYWxjKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcGVuZGluZ1JlY2FsYyA9IHRydWU7XG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIHRoaXMuX3JlY2FsY3VsYXRlVHJlZShbLi4uYXJyXSk7XG4gICAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5mbGF0VHJlZSgpO1xuICAgICAgaWYgKCF0aGlzLl9hcnJheXNFcXVhbChjdXJyZW50LCBhcnIpKSB7XG4gICAgICAgIHRoaXMuZmxhdFRyZWUuc2V0KFsuLi5hcnJdKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX3BlbmRpbmdSZWNhbGMgPSBmYWxzZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiDQn9GA0L7QstC10YDRj9C10YIg0YDQsNCy0LXQvdGB0YLQstC+INC00LLRg9GFINC80LDRgdGB0LjQstC+0LIgRmxhdE5vZGUg0L/QviDQutC70Y7Rh9C10LLRi9C8INGB0LLQvtC50YHRgtCy0LDQvFxuICAgKi9cbiAgcHJpdmF0ZSBfYXJyYXlzRXF1YWwoYTogRmxhdE5vZGVbXSwgYjogRmxhdE5vZGVbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChhLmxlbmd0aCAhPT0gYi5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgZm9yIChjb25zdCBbaSwgZWxlbWVudF0gb2YgYS5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChcbiAgICAgICAgZWxlbWVudC5pZCAhPT0gYltpXS5pZCB8fFxuICAgICAgICBlbGVtZW50LmRlcHRoICE9PSBiW2ldLmRlcHRoIHx8XG4gICAgICAgIGVsZW1lbnQub3JkZXJfbnVtICE9PSBiW2ldLm9yZGVyX251bVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cIm1lbnUtY29uc3RydWN0b3JcIj5cbiAgPGRpdiBjbGFzcz1cInBhbmUgZWRpdG9yXCI+XG4gICAgPGRpdiBjbGFzcz1cInBhbmUtaGVhZGVyXCI+XG4gICAgICA8aDI+0KDQtdC00LDQutGC0L7RgCDQvNC10L3RjjwvaDI+XG4gICAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uc1wiPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gc2Vjb25kYXJ5XCIgKGNsaWNrKT1cImFkZE5ld0l0ZW0oKVwiPlxuICAgICAgICAgICtcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBzZWNvbmRhcnlcIiAoY2xpY2spPVwicmVzZXQoKVwiPlxuICAgICAgICAgINCh0LHRgNC+0YHQuNGC0YxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gW2Rpc2FibGVkXT1cIiRhbnkobG9hZGluZyQgfCBhc3luYylcIiBjbGFzcz1cImJ0biBwcmltYXJ5XCIgKGNsaWNrKT1cInNhdmUoKVwiPlxuICAgICAgICAgINCh0L7RhdGA0LDQvdC40YLRjFxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiBbZGlzYWJsZWRdPVwiJGFueShsb2FkaW5nJCB8IGFzeW5jKVwiIGNsYXNzPVwiYnRuIHByaW1hcnlcIiAoY2xpY2spPVwiaGFuZGxlRm9sZChmYWxzZSlcIj5cbiAgICAgICAgICDQoNCw0YHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uIFtkaXNhYmxlZF09XCIkYW55KGxvYWRpbmckIHwgYXN5bmMpXCIgY2xhc3M9XCJidG4gcHJpbWFyeVwiIChjbGljayk9XCJoYW5kbGVGb2xkKHRydWUpXCI+XG4gICAgICAgICAg0KHQutGA0YvRgtGMINCy0YHQtSDRjdC70LXQvNC10L3RgtGLXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImxpc3Qtd3JhcHBlclwiXG4gICAgICBjZGtEcm9wTGlzdFxuICAgICAgW2Nka0Ryb3BMaXN0RGF0YV09XCJ2aXNpYmxlRmxhdFRyZWUoKVwiXG4gICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cImRyb3AoJGV2ZW50KVwiXG4gICAgICBbY2RrRHJvcExpc3RMb2NrQXhpc109XCIneSdcIlxuICAgID5cbiAgICAgIEBmb3IgKG5vZGUgb2YgdmlzaWJsZUZsYXRUcmVlKCk7IHRyYWNrIG5vZGUuaWQgKyAnLScgKyBub2RlLm9yZGVyX251bSkge1xuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJub2RlXCJcbiAgICAgICAgICBbc3R5bGUubWFyZ2luTGVmdC5weF09XCJub2RlLmRlcHRoICogMjRcIlxuICAgICAgICAgIFtjbGFzcy5kcmFnZ2VkXT1cImlzRHJhZ2dlZChub2RlKVwiXG4gICAgICAgICAgY2RrRHJhZ1xuICAgICAgICAgIChjZGtEcmFnU3RhcnRlZCk9XCJkcmFnU3RhcnRlZChub2RlKVwiXG4gICAgICAgICAgKGNka0RyYWdFbmRlZCk9XCJkcmFnRW5kZWQoKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibm9kZS1iYXJcIiBjZGtEcmFnSGFuZGxlPlxuICAgICAgICAgICAgQGlmIChoYXNDaGlsZHJlbihub2RlKSkge1xuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjb2xsYXBzZS1idG5cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVDb2xsYXBzZShub2RlKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgICAgICBbdGl0bGVdPVwibm9kZS5jb2xsYXBzZWQgPyAn0KDQsNC30LLQtdGA0L3Rg9GC0YwnIDogJ9Ch0LLQtdGA0L3Rg9GC0YwnXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG5vZGUuY29sbGFwc2VkID8gJ+KWticgOiAn4pa8JyB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChub2RlLnRpdGxlID09PSBST09UX1RJVExFKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicm9vdC10aXRsZVwiPtCa0L7RgNC90LXQstC+0Lkg0Y3Qu9C10LzQtdC90YI8L3NwYW4+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImxlZnQtY29udHJvbFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpcFwiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXQgY2xhc3M9XCJpbnAgdGl0bGVcIiBbKG5nTW9kZWwpXT1cIm5vZGUudGl0bGVcIiBwbGFjZWhvbGRlcj1cItCd0LDQt9Cy0LDQvdC40LVcIiAvPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJpbnAgY29kZVwiXG4gICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5vZGUuY29kZVwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cImNvZGVcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvdXRlXCIgWyhuZ01vZGVsKV09XCJub2RlLnJvdXRlXCIgcGxhY2Vob2xkZXI9XCJyb3V0ZVwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIGljb25cIiBbKG5nTW9kZWwpXT1cIm5vZGUuaWNvblwiIHBsYWNlaG9sZGVyPVwiaWNvblwiIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wIHJvbGVzXCIgWyhuZ01vZGVsKV09XCJub2RlLmFsbG93ZWRfcm9sZXNcIiBwbGFjZWhvbGRlcj1cItCg0L7Qu9C4XCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlcHRoLWNvbnRyb2xzXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJvdXRkZW50KG5vZGUpXCI+4oaQPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBzbWFsbFwiIChjbGljayk9XCJpbmRlbnQobm9kZSlcIj7ihpI8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICBAaWYgKGhhc0NoaWxkcmVuKG5vZGUpKSB7XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIHNtYWxsXCIgKGNsaWNrKT1cIm91dGRlbnRCcmFuY2gobm9kZSlcIj7ih5A8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiaW5kZW50QnJhbmNoKG5vZGUpXCI+4oeSPC9idXR0b24+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gc21hbGxcIiAoY2xpY2spPVwiZGVsZXRlSXRlbShub2RlKVwiPtCj0LTQsNC70LjRgtGMPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPG5nLXRlbXBsYXRlIGNka0RyYWdQcmV2aWV3PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRyYWctYnJhbmNoLXByZXZpZXdcIj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzPVwicHJldmlldy1iYXJcIlxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBuIG9mIGRyYWdnZWRCcmFuY2goKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1hcmdpbkxlZnQucHhdPVwiKG4uZGVwdGggLSBub2RlLmRlcHRoKSAqIDIwXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IG4udGl0bGUgfX1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
|