@seniorsistemas/data-seniorx-core 2.3.0 → 3.0.0
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/core/constants/autocomplete.const.d.ts +4 -0
- package/core/constants/context-selector.const.d.ts +1 -0
- package/core/constants/gantt.const.d.ts +7 -0
- package/core/constants/hyperlink.const.d.ts +1 -0
- package/core/constants/inline-edit.const.d.ts +4 -0
- package/core/constants/kanban.const.d.ts +2 -0
- package/core/constants/pin-code-field.const.d.ts +5 -0
- package/core/constants/rating-scale.const.d.ts +1 -0
- package/core/constants/spotlight.const.d.ts +8 -0
- package/core/constants/star-rating.const.d.ts +4 -0
- package/core/constants/stepper.const.d.ts +1 -0
- package/core/constants/tiered-menu.const.d.ts +3 -0
- package/core/types/autocomplete.type.d.ts +9 -0
- package/core/types/chat.type.d.ts +12 -0
- package/core/types/checkbox-list.type.d.ts +12 -0
- package/core/types/gantt.type.d.ts +22 -0
- package/core/types/grid-menu.type.d.ts +13 -0
- package/core/types/hyperlink.type.d.ts +1 -0
- package/core/types/image-cropper.type.d.ts +20 -0
- package/core/types/inline-edit.type.d.ts +26 -0
- package/core/types/kanban.type.d.ts +36 -0
- package/core/types/panel.type.d.ts +16 -0
- package/core/types/profile-picture-picker.type.d.ts +9 -0
- package/core/types/rating-scale.type.d.ts +5 -0
- package/core/types/select-button.type.d.ts +1 -0
- package/core/types/spotlight.type.d.ts +34 -0
- package/core/types/star-rating.type.d.ts +1 -0
- package/core/types/stepper.type.d.ts +20 -0
- package/core/types/table-column.type.d.ts +3 -1
- package/core/types/table-options.type.d.ts +8 -2
- package/core/types/table.type.d.ts +1 -1
- package/core/types/tiered-menu.type.d.ts +16 -0
- package/core/types/tree.type.d.ts +25 -0
- package/core/types/workspace-switch.type.d.ts +6 -0
- package/core/utils/body-scroll.util.d.ts +2 -0
- package/core/utils/roving-focus.util.d.ts +2 -0
- package/core/utils/selection.util.d.ts +3 -0
- package/core/utils/tree.util.d.ts +4 -0
- package/esm2022/core/constants/autocomplete.const.mjs +5 -0
- package/esm2022/core/constants/context-selector.const.mjs +2 -0
- package/esm2022/core/constants/gantt.const.mjs +7 -0
- package/esm2022/core/constants/hyperlink.const.mjs +2 -1
- package/esm2022/core/constants/inline-edit.const.mjs +5 -0
- package/esm2022/core/constants/kanban.const.mjs +3 -0
- package/esm2022/core/constants/pin-code-field.const.mjs +6 -0
- package/esm2022/core/constants/rating-scale.const.mjs +2 -0
- package/esm2022/core/constants/spotlight.const.mjs +9 -0
- package/esm2022/core/constants/star-rating.const.mjs +5 -0
- package/esm2022/core/constants/stepper.const.mjs +2 -0
- package/esm2022/core/constants/table.const.mjs +2 -2
- package/esm2022/core/constants/tiered-menu.const.mjs +4 -0
- package/esm2022/core/types/autocomplete.type.mjs +2 -0
- package/esm2022/core/types/chat.type.mjs +2 -0
- package/esm2022/core/types/checkbox-list.type.mjs +2 -0
- package/esm2022/core/types/gantt.type.mjs +2 -0
- package/esm2022/core/types/grid-menu.type.mjs +2 -0
- package/esm2022/core/types/hyperlink.type.mjs +1 -1
- package/esm2022/core/types/image-cropper.type.mjs +2 -0
- package/esm2022/core/types/inline-edit.type.mjs +2 -0
- package/esm2022/core/types/kanban.type.mjs +2 -0
- package/esm2022/core/types/panel.type.mjs +9 -0
- package/esm2022/core/types/profile-picture-picker.type.mjs +2 -0
- package/esm2022/core/types/rating-scale.type.mjs +2 -0
- package/esm2022/core/types/select-button.type.mjs +1 -1
- package/esm2022/core/types/spotlight.type.mjs +2 -0
- package/esm2022/core/types/star-rating.type.mjs +2 -0
- package/esm2022/core/types/stepper.type.mjs +7 -0
- package/esm2022/core/types/table-column.type.mjs +1 -1
- package/esm2022/core/types/table-options.type.mjs +1 -1
- package/esm2022/core/types/table.type.mjs +1 -1
- package/esm2022/core/types/tiered-menu.type.mjs +2 -0
- package/esm2022/core/types/tree.type.mjs +2 -0
- package/esm2022/core/types/workspace-switch.type.mjs +2 -0
- package/esm2022/core/utils/body-scroll.util.mjs +19 -0
- package/esm2022/core/utils/combobox.util.mjs +3 -2
- package/esm2022/core/utils/roving-focus.util.mjs +20 -0
- package/esm2022/core/utils/selection.util.mjs +13 -0
- package/esm2022/core/utils/string.util.mjs +8 -3
- package/esm2022/core/utils/tree.util.mjs +23 -0
- package/esm2022/features/accordion/accordion.component.mjs +2 -2
- package/esm2022/features/accordion/{accordion-item.component.mjs → components/accordion-item/accordion-item.component.mjs} +7 -7
- package/esm2022/features/autocomplete/autocomplete.component.mjs +501 -0
- package/esm2022/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.mjs +30 -0
- package/esm2022/features/breadcrumb/breadcrumb.component.mjs +2 -2
- package/esm2022/features/card-list/card/card.component.mjs +63 -99
- package/esm2022/features/chat/chat.component.mjs +126 -0
- package/esm2022/features/checkbox-list/checkbox-list.component.mjs +125 -0
- package/esm2022/features/combobox/combobox.component.mjs +20 -8
- package/esm2022/features/context-selector/context-selector.component.mjs +198 -0
- package/esm2022/features/filters/filters.component.mjs +1 -1
- package/esm2022/features/gantt/components/gantt-side-table/gantt-side-table.component.mjs +17 -0
- package/esm2022/features/gantt/gantt-date.utils.mjs +97 -0
- package/esm2022/features/gantt/gantt.component.mjs +89 -0
- package/esm2022/features/gantt/gantt.engine.mjs +662 -0
- package/esm2022/features/grid-menu/grid-menu.component.mjs +104 -0
- package/esm2022/features/hyperlink/hyperlink.component.mjs +7 -4
- package/esm2022/features/icon-picker/icon-picker.component.mjs +3 -3
- package/esm2022/features/image-cropper/image-cropper.component.mjs +218 -0
- package/esm2022/features/image-cropper/services/image-cropper.service.mjs +50 -0
- package/esm2022/features/infinite-scroll/infinite-scroll.directive.mjs +89 -0
- package/esm2022/features/info-sign/info-sign.component.mjs +3 -3
- package/esm2022/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.mjs +38 -0
- package/esm2022/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.mjs +29 -0
- package/esm2022/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.mjs +29 -0
- package/esm2022/features/inline-edit/components/inline-edit-item/inline-edit-item.component.mjs +131 -0
- package/esm2022/features/inline-edit/fields/inline-edit-field.mjs +17 -0
- package/esm2022/features/inline-edit/fields/inline-edit-number-field.mjs +15 -0
- package/esm2022/features/inline-edit/fields/inline-edit-text-field.mjs +11 -0
- package/esm2022/features/inline-edit/fields/inline-edit-textarea-field.mjs +15 -0
- package/esm2022/features/inline-edit/inline-edit.component.mjs +27 -0
- package/esm2022/features/interactive-content/interactive-content.directive.mjs +140 -0
- package/esm2022/features/kanban/components/kanban-column/kanban-column.component.mjs +88 -0
- package/esm2022/features/kanban/components/kanban-item/kanban-item.component.mjs +72 -0
- package/esm2022/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.mjs +19 -0
- package/esm2022/features/kanban/directives/kanban-template.directive.mjs +22 -0
- package/esm2022/features/kanban/kanban.component.mjs +198 -0
- package/esm2022/features/kanban/services/kanban-event.service.mjs +27 -0
- package/esm2022/features/loading-state/loading-state.component.mjs +3 -62
- package/esm2022/features/mouse-events/directives/double-click.directive.mjs +34 -0
- package/esm2022/features/mouse-events/directives/long-press.directive.mjs +61 -0
- package/esm2022/features/paginator/paginator.component.mjs +8 -3
- package/esm2022/features/panel/panel.component.mjs +43 -11
- package/esm2022/features/pin-code-field/pin-code-field.component.mjs +234 -0
- package/esm2022/features/profile-picture-picker/profile-picture-picker.component.mjs +330 -0
- package/esm2022/features/rating-scale/rating-scale.component.mjs +86 -0
- package/esm2022/features/row-card-list/row-card/row-card.component.mjs +3 -3
- package/esm2022/features/scaffold/scaffold.component.mjs +4 -6
- package/esm2022/features/select-button/select-button.component.mjs +7 -4
- package/esm2022/features/speech-recognition/services/speech-recognition.service.mjs +148 -0
- package/esm2022/features/speech-recognition/services/text-to-speech.service.mjs +88 -0
- package/esm2022/features/speech-recognition/speech-recognition.component.mjs +243 -0
- package/esm2022/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.mjs +521 -0
- package/esm2022/features/spotlight/directives/spotlight-step.directive.mjs +38 -0
- package/esm2022/features/spotlight/services/spotlight-tour.service.mjs +179 -0
- package/esm2022/features/spotlight/spotlight.component.mjs +160 -0
- package/esm2022/features/star-rating/star-rating.component.mjs +95 -0
- package/esm2022/features/stepper/stepper.component.mjs +86 -0
- package/esm2022/features/switch/switch.component.mjs +12 -8
- package/esm2022/features/tab/{tab-item.component.mjs → components/tab-item/tab-item.component.mjs} +1 -1
- package/esm2022/features/tab/tab.component.mjs +4 -4
- package/esm2022/features/table/components/table-cell-content.component.mjs +14 -5
- package/esm2022/features/table/table.component.mjs +220 -29
- package/esm2022/features/table/utils/table-data.util.mjs +71 -8
- package/esm2022/features/table/utils/table-layout.util.mjs +21 -1
- package/esm2022/features/tiered-menu/components/tiered-menu/tiered-menu.component.mjs +367 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.mjs +11 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.mjs +97 -0
- package/esm2022/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.mjs +181 -0
- package/esm2022/features/tiered-menu/directives/tiered-menu.directive.mjs +246 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.event.service.mjs +16 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.global.service.mjs +12 -0
- package/esm2022/features/tiered-menu/services/tiered-menu.service.mjs +49 -0
- package/esm2022/features/tree/components/tree-node-item/tree-node-item.component.mjs +169 -0
- package/esm2022/features/tree/tree.component.mjs +211 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.mjs +41 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.mjs +38 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.mjs +29 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.mjs +29 -0
- package/esm2022/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.mjs +35 -0
- package/esm2022/features/visual-sql-editor/services/visual-sql-editor-flow.service.mjs +106 -0
- package/esm2022/features/visual-sql-editor/services/visual-sql-editor-state.service.mjs +230 -0
- package/esm2022/features/visual-sql-editor/types/visual-sql-editor.types.mjs +2 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.mjs +72 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-sql.util.mjs +281 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor-text.util.mjs +37 -0
- package/esm2022/features/visual-sql-editor/utils/visual-sql-editor.constants.mjs +89 -0
- package/esm2022/features/visual-sql-editor/visual-sql-editor.component.mjs +172 -630
- package/esm2022/locales/en.json +351 -3
- package/esm2022/locales/es-CO.json +351 -3
- package/esm2022/locales/pt.json +351 -3
- package/esm2022/providers/features.provider.mjs +40 -4
- package/esm2022/public-api.mjs +56 -3
- package/features/accordion/accordion.component.d.ts +1 -1
- package/features/accordion/{accordion-item.component.d.ts → components/accordion-item/accordion-item.component.d.ts} +1 -1
- package/features/autocomplete/autocomplete.component.d.ts +102 -0
- package/features/autocomplete/components/autocomplete-chip/autocomplete-chip.component.d.ts +11 -0
- package/features/card-list/card/card.component.d.ts +14 -34
- package/features/chat/chat.component.d.ts +31 -0
- package/features/checkbox-list/checkbox-list.component.d.ts +26 -0
- package/features/combobox/combobox.component.d.ts +2 -1
- package/features/context-selector/context-selector.component.d.ts +37 -0
- package/features/gantt/components/gantt-side-table/gantt-side-table.component.d.ts +8 -0
- package/features/gantt/gantt-date.utils.d.ts +36 -0
- package/features/gantt/gantt.component.d.ts +24 -0
- package/features/gantt/gantt.engine.d.ts +52 -0
- package/features/grid-menu/grid-menu.component.d.ts +29 -0
- package/features/hyperlink/hyperlink.component.d.ts +2 -1
- package/features/image-cropper/image-cropper.component.d.ts +43 -0
- package/features/image-cropper/services/image-cropper.service.d.ts +13 -0
- package/features/infinite-scroll/infinite-scroll.directive.d.ts +25 -0
- package/features/inline-edit/components/fields/inline-edit-number/inline-edit-number.component.d.ts +13 -0
- package/features/inline-edit/components/fields/inline-edit-text/inline-edit-text.component.d.ts +13 -0
- package/features/inline-edit/components/fields/inline-edit-textarea/inline-edit-textarea.component.d.ts +13 -0
- package/features/inline-edit/components/inline-edit-item/inline-edit-item.component.d.ts +37 -0
- package/features/inline-edit/fields/inline-edit-field.d.ts +12 -0
- package/features/inline-edit/fields/inline-edit-number-field.d.ts +9 -0
- package/features/inline-edit/fields/inline-edit-text-field.d.ts +7 -0
- package/features/inline-edit/fields/inline-edit-textarea-field.d.ts +9 -0
- package/features/inline-edit/inline-edit.component.d.ts +13 -0
- package/features/interactive-content/interactive-content.directive.d.ts +31 -0
- package/features/kanban/components/kanban-column/kanban-column.component.d.ts +22 -0
- package/features/kanban/components/kanban-item/kanban-item.component.d.ts +23 -0
- package/features/kanban/components/kanban-item-dragging/kanban-item-dragging.component.d.ts +8 -0
- package/features/kanban/directives/kanban-template.directive.d.ts +10 -0
- package/features/kanban/kanban.component.d.ts +32 -0
- package/features/kanban/services/kanban-event.service.d.ts +15 -0
- package/features/loading-state/loading-state.component.d.ts +0 -2
- package/features/mouse-events/directives/double-click.directive.d.ts +11 -0
- package/features/mouse-events/directives/long-press.directive.d.ts +14 -0
- package/features/panel/panel.component.d.ts +12 -3
- package/features/pin-code-field/pin-code-field.component.d.ts +44 -0
- package/features/profile-picture-picker/profile-picture-picker.component.d.ts +77 -0
- package/features/rating-scale/rating-scale.component.d.ts +24 -0
- package/features/select-button/select-button.component.d.ts +2 -1
- package/features/speech-recognition/services/speech-recognition.service.d.ts +29 -0
- package/features/speech-recognition/services/text-to-speech.service.d.ts +24 -0
- package/features/speech-recognition/speech-recognition.component.d.ts +50 -0
- package/features/spotlight/components/spotlight-overlay/spotlight-overlay.component.d.ts +59 -0
- package/features/spotlight/directives/spotlight-step.directive.d.ts +13 -0
- package/features/spotlight/services/spotlight-tour.service.d.ts +46 -0
- package/features/spotlight/spotlight.component.d.ts +59 -0
- package/features/star-rating/star-rating.component.d.ts +26 -0
- package/features/stepper/stepper.component.d.ts +23 -0
- package/features/switch/switch.component.d.ts +2 -1
- package/features/tab/tab.component.d.ts +1 -1
- package/features/table/components/table-cell-content.component.d.ts +4 -3
- package/features/table/table.component.d.ts +40 -5
- package/features/table/utils/table-data.util.d.ts +1 -0
- package/features/table/utils/table-layout.util.d.ts +1 -0
- package/features/tiered-menu/components/tiered-menu/tiered-menu.component.d.ts +49 -0
- package/features/tiered-menu/components/tiered-menu-divider/tiered-menu-divider.component.d.ts +5 -0
- package/features/tiered-menu/components/tiered-menu-item/tiered-menu-item.component.d.ts +19 -0
- package/features/tiered-menu/components/tiered-menu-nested/tiered-menu-nested.component.d.ts +26 -0
- package/features/tiered-menu/directives/tiered-menu.directive.d.ts +44 -0
- package/features/tiered-menu/services/tiered-menu.event.service.d.ts +13 -0
- package/features/tiered-menu/services/tiered-menu.global.service.d.ts +7 -0
- package/features/tiered-menu/services/tiered-menu.service.d.ts +14 -0
- package/features/tree/components/tree-node-item/tree-node-item.component.d.ts +37 -0
- package/features/tree/tree.component.d.ts +37 -0
- package/features/visual-sql-editor/components/visual-sql-editor-field-modal/visual-sql-editor-field-modal.component.d.ts +18 -0
- package/features/visual-sql-editor/components/visual-sql-editor-filter-modal/visual-sql-editor-filter-modal.component.d.ts +17 -0
- package/features/visual-sql-editor/components/visual-sql-editor-join-modal/visual-sql-editor-join-modal.component.d.ts +13 -0
- package/features/visual-sql-editor/components/visual-sql-editor-sort-modal/visual-sql-editor-sort-modal.component.d.ts +13 -0
- package/features/visual-sql-editor/components/visual-sql-editor-source-modal/visual-sql-editor-source-modal.component.d.ts +15 -0
- package/features/visual-sql-editor/services/visual-sql-editor-flow.service.d.ts +26 -0
- package/features/visual-sql-editor/services/visual-sql-editor-state.service.d.ts +72 -0
- package/features/visual-sql-editor/types/visual-sql-editor.types.d.ts +182 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-sanitize.util.d.ts +14 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-sql.util.d.ts +81 -0
- package/features/visual-sql-editor/utils/visual-sql-editor-text.util.d.ts +15 -0
- package/features/visual-sql-editor/utils/visual-sql-editor.constants.d.ts +36 -0
- package/features/visual-sql-editor/visual-sql-editor.component.d.ts +37 -199
- package/fesm2022/seniorsistemas-data-seniorx-core.mjs +14883 -6353
- package/fesm2022/seniorsistemas-data-seniorx-core.mjs.map +1 -1
- package/package.json +8 -8
- package/public-api.d.ts +72 -2
- package/src/locales/en.json +353 -15
- package/src/locales/es-CO.json +352 -14
- package/src/locales/pt.json +352 -14
- package/styles/sdc-global-variables.scss +1 -1
- package/styles.css +1 -1
- /package/features/tab/{tab-item.component.d.ts → components/tab-item/tab-item.component.d.ts} +0 -0
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
import { GANTT_BAR_HEIGHT, GANTT_DEFAULT_BAR_COLOR, GANTT_HEADER_HEIGHT, GANTT_ROW_HEIGHT, } from '../../core/constants/gantt.const';
|
|
2
|
+
import { addDays, addHours, diffDays, diffHours, formatDayMonth, formatHourLabel, formatMonthLabel, formatWeekLabel, isWeekend, isSameDay, startOfDay, startOfHour, startOfMonth, startOfWeek, } from './gantt-date.utils';
|
|
3
|
+
// ---------------------------------------------------------------------------
|
|
4
|
+
// Public types & Constants
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
const RX_VALUE = 3;
|
|
7
|
+
const DATE_RANGE_SAFETY_LIMIT = 5000;
|
|
8
|
+
const DAYS_IN_WEEK = 7;
|
|
9
|
+
const HEADER_LABEL_VERTICAL_OFFSET = 5;
|
|
10
|
+
const HANDLE_WIDTH = 6;
|
|
11
|
+
const TASK_LABEL_HORIZONTAL_PADDING = 6;
|
|
12
|
+
const DRAG_MIN_HANDLE_FACTOR = 2;
|
|
13
|
+
const POPUP_AUTO_REMOVE_DELAY_MS = 3000;
|
|
14
|
+
const MONTHS_IN_YEAR = 12;
|
|
15
|
+
const BAR_SELECTOR = '.sdc-gantt-bar';
|
|
16
|
+
var DragMode;
|
|
17
|
+
(function (DragMode) {
|
|
18
|
+
DragMode[DragMode["Move"] = 0] = "Move";
|
|
19
|
+
DragMode[DragMode["ResizeLeft"] = 1] = "ResizeLeft";
|
|
20
|
+
DragMode[DragMode["ResizeRight"] = 2] = "ResizeRight";
|
|
21
|
+
})(DragMode || (DragMode = {}));
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// GanttEngine – pure TypeScript class, no Angular decorators
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
26
|
+
export class GanttEngine {
|
|
27
|
+
svg;
|
|
28
|
+
tasks;
|
|
29
|
+
options;
|
|
30
|
+
// Layout constants – kept in sync with SCSS tokens
|
|
31
|
+
HEADER_HEIGHT = GANTT_HEADER_HEIGHT;
|
|
32
|
+
ROW_HEIGHT = GANTT_ROW_HEIGHT;
|
|
33
|
+
BAR_HEIGHT = GANTT_BAR_HEIGHT;
|
|
34
|
+
PADDING = 12;
|
|
35
|
+
COLUMN_WIDTHS = {
|
|
36
|
+
hour: 50,
|
|
37
|
+
day: 50,
|
|
38
|
+
week: 140,
|
|
39
|
+
month: 120,
|
|
40
|
+
};
|
|
41
|
+
// Popup element managed by the engine
|
|
42
|
+
popup = null;
|
|
43
|
+
// Active drag state
|
|
44
|
+
drag = null;
|
|
45
|
+
// Bound global handlers (kept so we can remove them on destroy)
|
|
46
|
+
boundMouseMove;
|
|
47
|
+
boundMouseUp;
|
|
48
|
+
constructor(svg, tasks, options) {
|
|
49
|
+
this.svg = svg;
|
|
50
|
+
this.tasks = tasks;
|
|
51
|
+
this.options = options;
|
|
52
|
+
this.boundMouseMove = this.onMouseMove.bind(this);
|
|
53
|
+
this.boundMouseUp = this.onMouseUp.bind(this);
|
|
54
|
+
document.addEventListener('mousemove', this.boundMouseMove);
|
|
55
|
+
document.addEventListener('mouseup', this.boundMouseUp);
|
|
56
|
+
this.render();
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// Public API
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
refresh(tasks) {
|
|
62
|
+
this.tasks = tasks;
|
|
63
|
+
this.render();
|
|
64
|
+
}
|
|
65
|
+
updateOptions(options) {
|
|
66
|
+
this.options = { ...this.options, ...options };
|
|
67
|
+
this.render();
|
|
68
|
+
}
|
|
69
|
+
changeViewMode(mode) {
|
|
70
|
+
this.updateOptions({ viewMode: mode });
|
|
71
|
+
}
|
|
72
|
+
destroy() {
|
|
73
|
+
document.removeEventListener('mousemove', this.boundMouseMove);
|
|
74
|
+
document.removeEventListener('mouseup', this.boundMouseUp);
|
|
75
|
+
this.removePopup();
|
|
76
|
+
this.clearSvg();
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Render pipeline
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
render() {
|
|
82
|
+
this.clearSvg();
|
|
83
|
+
this.removePopup();
|
|
84
|
+
this.drag = null;
|
|
85
|
+
if (this.tasks.length === 0) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const { dates } = this.computeDateRange();
|
|
89
|
+
const colW = this.COLUMN_WIDTHS[this.options.viewMode];
|
|
90
|
+
const totalWidth = dates.length * colW;
|
|
91
|
+
const totalHeight = this.HEADER_HEIGHT + this.tasks.length * this.ROW_HEIGHT;
|
|
92
|
+
this.svg.setAttribute('width', String(totalWidth));
|
|
93
|
+
this.svg.setAttribute('height', String(totalHeight));
|
|
94
|
+
this.svg.setAttribute('viewBox', `0 0 ${totalWidth} ${totalHeight}`);
|
|
95
|
+
this.drawGrid(dates, colW, totalWidth, totalHeight);
|
|
96
|
+
this.drawBars(dates[0], colW);
|
|
97
|
+
}
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// Date range computation
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
computeDateRange() {
|
|
102
|
+
const mode = this.options.viewMode;
|
|
103
|
+
let minDate = this.tasks[0].start;
|
|
104
|
+
let maxDate = this.tasks[0].end;
|
|
105
|
+
for (const task of this.tasks) {
|
|
106
|
+
if (task.start < minDate) {
|
|
107
|
+
minDate = task.start;
|
|
108
|
+
}
|
|
109
|
+
if (task.end > maxDate) {
|
|
110
|
+
maxDate = task.end;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Add margin
|
|
114
|
+
const marginedMax = addDays(maxDate, 1);
|
|
115
|
+
const start = this.slotStart(minDate, mode);
|
|
116
|
+
const end = this.slotStart(addDays(marginedMax, 1), mode);
|
|
117
|
+
const dates = [];
|
|
118
|
+
let cursor = new Date(start);
|
|
119
|
+
// Safety limit to avoid infinite loops
|
|
120
|
+
let safety = 0;
|
|
121
|
+
while (cursor < end && safety < DATE_RANGE_SAFETY_LIMIT) {
|
|
122
|
+
dates.push(new Date(cursor));
|
|
123
|
+
cursor = this.nextSlot(cursor, mode);
|
|
124
|
+
safety++;
|
|
125
|
+
}
|
|
126
|
+
return { start, end, dates };
|
|
127
|
+
}
|
|
128
|
+
slotStart(date, mode) {
|
|
129
|
+
switch (mode) {
|
|
130
|
+
case 'hour':
|
|
131
|
+
return startOfHour(date);
|
|
132
|
+
case 'day':
|
|
133
|
+
return startOfDay(date);
|
|
134
|
+
case 'week':
|
|
135
|
+
return startOfWeek(date);
|
|
136
|
+
case 'month':
|
|
137
|
+
return startOfMonth(date);
|
|
138
|
+
default:
|
|
139
|
+
return startOfDay(date);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
nextSlot(date, mode) {
|
|
143
|
+
switch (mode) {
|
|
144
|
+
case 'hour':
|
|
145
|
+
return addHours(date, 1);
|
|
146
|
+
case 'day':
|
|
147
|
+
return addDays(date, 1);
|
|
148
|
+
case 'week':
|
|
149
|
+
return addDays(date, DAYS_IN_WEEK);
|
|
150
|
+
case 'month': {
|
|
151
|
+
const d = new Date(date);
|
|
152
|
+
d.setMonth(d.getMonth() + 1);
|
|
153
|
+
return d;
|
|
154
|
+
}
|
|
155
|
+
default:
|
|
156
|
+
return addDays(date, 1);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
// ---------------------------------------------------------------------------
|
|
160
|
+
// Grid drawing
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
drawGrid(dates, colW, totalWidth, totalHeight) {
|
|
163
|
+
const mode = this.options.viewMode;
|
|
164
|
+
// Row backgrounds
|
|
165
|
+
for (let i = 0; i < this.tasks.length; i++) {
|
|
166
|
+
const y = this.HEADER_HEIGHT + i * this.ROW_HEIGHT;
|
|
167
|
+
const bg = this.createSvgElement('rect');
|
|
168
|
+
bg.setAttribute('x', '0');
|
|
169
|
+
bg.setAttribute('y', String(y));
|
|
170
|
+
bg.setAttribute('width', String(totalWidth));
|
|
171
|
+
bg.setAttribute('height', String(this.ROW_HEIGHT));
|
|
172
|
+
bg.setAttribute('class', `sdc-gantt-row-bg ${i % 2 === 0 ? 'sdc-gantt-row-bg--even' : 'sdc-gantt-row-bg--odd'}`);
|
|
173
|
+
this.svg.appendChild(bg);
|
|
174
|
+
}
|
|
175
|
+
// Column slots – backgrounds + separators + labels
|
|
176
|
+
const today = startOfDay(new Date());
|
|
177
|
+
for (let i = 0; i < dates.length; i++) {
|
|
178
|
+
const x = i * colW;
|
|
179
|
+
const date = dates[i];
|
|
180
|
+
// Weekend highlight (day/hour modes)
|
|
181
|
+
if ((mode === 'day' || mode === 'hour') && isWeekend(date)) {
|
|
182
|
+
const wkRect = this.createSvgElement('rect');
|
|
183
|
+
wkRect.setAttribute('x', String(x));
|
|
184
|
+
wkRect.setAttribute('y', String(this.HEADER_HEIGHT));
|
|
185
|
+
wkRect.setAttribute('width', String(colW));
|
|
186
|
+
wkRect.setAttribute('height', String(this.tasks.length * this.ROW_HEIGHT));
|
|
187
|
+
wkRect.setAttribute('class', 'sdc-gantt-weekend');
|
|
188
|
+
this.svg.appendChild(wkRect);
|
|
189
|
+
}
|
|
190
|
+
// Today highlight
|
|
191
|
+
if (mode === 'day' && isSameDay(date, today)) {
|
|
192
|
+
const todayRect = this.createSvgElement('rect');
|
|
193
|
+
todayRect.setAttribute('x', String(x));
|
|
194
|
+
todayRect.setAttribute('y', '0');
|
|
195
|
+
todayRect.setAttribute('width', String(colW));
|
|
196
|
+
todayRect.setAttribute('height', String(totalHeight));
|
|
197
|
+
todayRect.setAttribute('class', 'sdc-gantt-today');
|
|
198
|
+
this.svg.appendChild(todayRect);
|
|
199
|
+
}
|
|
200
|
+
// Vertical grid line
|
|
201
|
+
const line = this.createSvgElement('line');
|
|
202
|
+
line.setAttribute('x1', String(x));
|
|
203
|
+
line.setAttribute('y1', String(this.HEADER_HEIGHT));
|
|
204
|
+
line.setAttribute('x2', String(x));
|
|
205
|
+
line.setAttribute('y2', String(totalHeight));
|
|
206
|
+
line.setAttribute('class', 'sdc-gantt-grid-line');
|
|
207
|
+
this.svg.appendChild(line);
|
|
208
|
+
// Header background
|
|
209
|
+
const hdrRect = this.createSvgElement('rect');
|
|
210
|
+
hdrRect.setAttribute('x', String(x));
|
|
211
|
+
hdrRect.setAttribute('y', '0');
|
|
212
|
+
hdrRect.setAttribute('width', String(colW));
|
|
213
|
+
hdrRect.setAttribute('height', String(this.HEADER_HEIGHT));
|
|
214
|
+
hdrRect.setAttribute('class', 'sdc-gantt-header-cell');
|
|
215
|
+
this.svg.appendChild(hdrRect);
|
|
216
|
+
// Header label
|
|
217
|
+
const label = this.createSvgElement('text');
|
|
218
|
+
label.setAttribute('x', String(x + colW / 2));
|
|
219
|
+
label.setAttribute('y', String(this.HEADER_HEIGHT / 2 + HEADER_LABEL_VERTICAL_OFFSET));
|
|
220
|
+
label.setAttribute('text-anchor', 'middle');
|
|
221
|
+
label.setAttribute('class', 'sdc-gantt-header-label');
|
|
222
|
+
label.textContent = this.formatColumnLabel(date, mode);
|
|
223
|
+
this.svg.appendChild(label);
|
|
224
|
+
}
|
|
225
|
+
// Bottom header border line
|
|
226
|
+
const hdrBorder = this.createSvgElement('line');
|
|
227
|
+
hdrBorder.setAttribute('x1', '0');
|
|
228
|
+
hdrBorder.setAttribute('y1', String(this.HEADER_HEIGHT));
|
|
229
|
+
hdrBorder.setAttribute('x2', String(totalWidth));
|
|
230
|
+
hdrBorder.setAttribute('y2', String(this.HEADER_HEIGHT));
|
|
231
|
+
hdrBorder.setAttribute('class', 'sdc-gantt-header-border');
|
|
232
|
+
this.svg.appendChild(hdrBorder);
|
|
233
|
+
// Horizontal row separators
|
|
234
|
+
for (let i = 1; i <= this.tasks.length; i++) {
|
|
235
|
+
const y = this.HEADER_HEIGHT + i * this.ROW_HEIGHT;
|
|
236
|
+
const hLine = this.createSvgElement('line');
|
|
237
|
+
hLine.setAttribute('x1', '0');
|
|
238
|
+
hLine.setAttribute('y1', String(y));
|
|
239
|
+
hLine.setAttribute('x2', String(totalWidth));
|
|
240
|
+
hLine.setAttribute('y2', String(y));
|
|
241
|
+
hLine.setAttribute('class', 'sdc-gantt-grid-line sdc-gantt-grid-line--horizontal');
|
|
242
|
+
this.svg.appendChild(hLine);
|
|
243
|
+
}
|
|
244
|
+
// Right border line
|
|
245
|
+
const rightLine = this.createSvgElement('line');
|
|
246
|
+
rightLine.setAttribute('x1', String(totalWidth));
|
|
247
|
+
rightLine.setAttribute('y1', '0');
|
|
248
|
+
rightLine.setAttribute('x2', String(totalWidth));
|
|
249
|
+
rightLine.setAttribute('y2', String(totalHeight));
|
|
250
|
+
rightLine.setAttribute('class', 'sdc-gantt-grid-line');
|
|
251
|
+
this.svg.appendChild(rightLine);
|
|
252
|
+
}
|
|
253
|
+
formatColumnLabel(date, mode) {
|
|
254
|
+
switch (mode) {
|
|
255
|
+
case 'hour':
|
|
256
|
+
return formatHourLabel(date);
|
|
257
|
+
case 'day':
|
|
258
|
+
return formatDayMonth(date);
|
|
259
|
+
case 'week':
|
|
260
|
+
return formatWeekLabel(date);
|
|
261
|
+
case 'month':
|
|
262
|
+
return formatMonthLabel(date);
|
|
263
|
+
default:
|
|
264
|
+
return formatDayMonth(date);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
// ---------------------------------------------------------------------------
|
|
268
|
+
// Bar drawing
|
|
269
|
+
// ---------------------------------------------------------------------------
|
|
270
|
+
drawBars(rangeStart, colW) {
|
|
271
|
+
for (let i = 0; i < this.tasks.length; i++) {
|
|
272
|
+
this.drawBarElement(this.tasks[i], i, rangeStart, colW);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
drawBarElement(task, rowIndex, rangeStart, colW) {
|
|
276
|
+
const barX = this.computeBarX(task.start, rangeStart, colW);
|
|
277
|
+
const barW = Math.max(this.computeBarWidth(task, colW), 4);
|
|
278
|
+
const barY = this.HEADER_HEIGHT + rowIndex * this.ROW_HEIGHT + (this.ROW_HEIGHT - this.BAR_HEIGHT) / 2;
|
|
279
|
+
const color = task.color ?? GANTT_DEFAULT_BAR_COLOR;
|
|
280
|
+
const group = this.createSvgElement('g');
|
|
281
|
+
group.setAttribute('class', `sdc-gantt-bar-group${task.customClass ? ' ' + task.customClass : ''}`);
|
|
282
|
+
group.setAttribute('data-task-id', task.id);
|
|
283
|
+
group.style.cursor = this.options.allowMovement ? 'grab' : 'pointer';
|
|
284
|
+
// Main bar rectangle
|
|
285
|
+
const rect = this.createSvgElement('rect');
|
|
286
|
+
rect.setAttribute('x', String(barX));
|
|
287
|
+
rect.setAttribute('y', String(barY));
|
|
288
|
+
rect.setAttribute('width', String(barW));
|
|
289
|
+
rect.setAttribute('height', String(this.BAR_HEIGHT));
|
|
290
|
+
rect.setAttribute('rx', String(RX_VALUE));
|
|
291
|
+
rect.setAttribute('ry', String(RX_VALUE));
|
|
292
|
+
rect.setAttribute('fill', color);
|
|
293
|
+
rect.setAttribute('class', 'sdc-gantt-bar');
|
|
294
|
+
group.appendChild(rect);
|
|
295
|
+
// Task name inside bar
|
|
296
|
+
if (task.showTaskName) {
|
|
297
|
+
const textEl = this.createSvgElement('text');
|
|
298
|
+
textEl.setAttribute('x', String(barX + TASK_LABEL_HORIZONTAL_PADDING));
|
|
299
|
+
textEl.setAttribute('y', String(barY + this.BAR_HEIGHT / 2 + 4));
|
|
300
|
+
textEl.setAttribute('class', 'sdc-gantt-bar-label');
|
|
301
|
+
textEl.setAttribute('clip-path', `url(#clip-${task.id})`);
|
|
302
|
+
textEl.textContent = task.name;
|
|
303
|
+
group.appendChild(textEl);
|
|
304
|
+
// Clip path so text stays inside the bar
|
|
305
|
+
const defs = this.createSvgElement('defs');
|
|
306
|
+
const clip = this.createSvgElement('clipPath');
|
|
307
|
+
clip.setAttribute('id', `clip-${task.id}`);
|
|
308
|
+
const clipRect = this.createSvgElement('rect');
|
|
309
|
+
clipRect.setAttribute('x', String(barX + 2));
|
|
310
|
+
clipRect.setAttribute('y', String(barY));
|
|
311
|
+
clipRect.setAttribute('width', String(Math.max(barW - 4, 0)));
|
|
312
|
+
clipRect.setAttribute('height', String(this.BAR_HEIGHT));
|
|
313
|
+
clip.appendChild(clipRect);
|
|
314
|
+
defs.appendChild(clip);
|
|
315
|
+
this.svg.insertBefore(defs, this.svg.firstChild);
|
|
316
|
+
}
|
|
317
|
+
// Resize handles (only when movement is allowed)
|
|
318
|
+
if (this.options.allowMovement) {
|
|
319
|
+
const leftHandle = this.createSvgElement('rect');
|
|
320
|
+
leftHandle.setAttribute('x', String(barX));
|
|
321
|
+
leftHandle.setAttribute('y', String(barY));
|
|
322
|
+
leftHandle.setAttribute('width', String(HANDLE_WIDTH));
|
|
323
|
+
leftHandle.setAttribute('height', String(this.BAR_HEIGHT));
|
|
324
|
+
leftHandle.setAttribute('rx', String(RX_VALUE));
|
|
325
|
+
leftHandle.setAttribute('fill', 'rgba(0,0,0,0.2)');
|
|
326
|
+
leftHandle.setAttribute('class', 'sdc-gantt-bar-handle sdc-gantt-bar-handle--left');
|
|
327
|
+
leftHandle.style.cursor = 'ew-resize';
|
|
328
|
+
leftHandle.addEventListener('mousedown', (e) => {
|
|
329
|
+
e.stopPropagation();
|
|
330
|
+
this.startDrag(e, task, group, DragMode.ResizeLeft, {
|
|
331
|
+
rangeStart,
|
|
332
|
+
colW,
|
|
333
|
+
rowIndex,
|
|
334
|
+
clientX: e.clientX,
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
group.appendChild(leftHandle);
|
|
338
|
+
const rightHandle = this.createSvgElement('rect');
|
|
339
|
+
rightHandle.setAttribute('x', String(barX + barW - HANDLE_WIDTH));
|
|
340
|
+
rightHandle.setAttribute('y', String(barY));
|
|
341
|
+
rightHandle.setAttribute('width', String(HANDLE_WIDTH));
|
|
342
|
+
rightHandle.setAttribute('height', String(this.BAR_HEIGHT));
|
|
343
|
+
rightHandle.setAttribute('rx', String(RX_VALUE));
|
|
344
|
+
rightHandle.setAttribute('fill', 'rgba(0,0,0,0.2)');
|
|
345
|
+
rightHandle.setAttribute('class', 'sdc-gantt-bar-handle sdc-gantt-bar-handle--right');
|
|
346
|
+
rightHandle.style.cursor = 'ew-resize';
|
|
347
|
+
rightHandle.addEventListener('mousedown', (e) => {
|
|
348
|
+
e.stopPropagation();
|
|
349
|
+
this.startDrag(e, task, group, DragMode.ResizeRight, {
|
|
350
|
+
rangeStart,
|
|
351
|
+
colW,
|
|
352
|
+
rowIndex,
|
|
353
|
+
clientX: e.clientX,
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
group.appendChild(rightHandle);
|
|
357
|
+
}
|
|
358
|
+
// Click / drag on main bar
|
|
359
|
+
rect.addEventListener('mousedown', (e) => {
|
|
360
|
+
if (this.options.allowMovement) {
|
|
361
|
+
this.startDrag(e, task, group, DragMode.Move, {
|
|
362
|
+
rangeStart,
|
|
363
|
+
colW,
|
|
364
|
+
rowIndex,
|
|
365
|
+
clientX: e.clientX,
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
rect.addEventListener('click', (e) => {
|
|
370
|
+
// Only fire click if not dragging
|
|
371
|
+
if (this.drag) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
if (this.options.hasPopup) {
|
|
375
|
+
this.showPopup(task, e.clientX, e.clientY);
|
|
376
|
+
}
|
|
377
|
+
this.options.onTaskClick?.(task);
|
|
378
|
+
});
|
|
379
|
+
this.svg.appendChild(group);
|
|
380
|
+
}
|
|
381
|
+
// ---------------------------------------------------------------------------
|
|
382
|
+
// Drag-and-drop
|
|
383
|
+
// ---------------------------------------------------------------------------
|
|
384
|
+
startDrag(e, task, barGroup, mode, seed) {
|
|
385
|
+
e.preventDefault();
|
|
386
|
+
const bar = barGroup.querySelector(BAR_SELECTOR);
|
|
387
|
+
if (!bar) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
this.drag = this.createDragState(task, barGroup, bar, mode, seed);
|
|
391
|
+
this.updateBarVisualForDrag(bar, barGroup);
|
|
392
|
+
}
|
|
393
|
+
createDragState(task, barGroup, bar, mode, seed) {
|
|
394
|
+
const startX = seed.clientX;
|
|
395
|
+
const columnWidth = seed.colW;
|
|
396
|
+
const dragRangeStart = seed.rangeStart;
|
|
397
|
+
const dragRowIndex = seed.rowIndex;
|
|
398
|
+
return {
|
|
399
|
+
startX,
|
|
400
|
+
task,
|
|
401
|
+
barGroup,
|
|
402
|
+
mode,
|
|
403
|
+
originalX: parseFloat(bar.getAttribute('x') ?? '0'),
|
|
404
|
+
originalWidth: parseFloat(bar.getAttribute('width') ?? '0'),
|
|
405
|
+
colW: columnWidth,
|
|
406
|
+
rangeStart: dragRangeStart,
|
|
407
|
+
rowIndex: dragRowIndex,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
updateBarVisualForDrag(bar, barGroup) {
|
|
411
|
+
barGroup.style.cursor = 'grabbing';
|
|
412
|
+
bar.setAttribute('stroke', 'var(--sdc-gantt-bar-selected-stroke, #212533)');
|
|
413
|
+
bar.setAttribute('stroke-width', '2');
|
|
414
|
+
}
|
|
415
|
+
onMouseMove(e) {
|
|
416
|
+
const drag = this.drag;
|
|
417
|
+
if (!drag) {
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const dx = e.clientX - drag.startX;
|
|
421
|
+
const bar = drag.barGroup.querySelector(BAR_SELECTOR);
|
|
422
|
+
if (!bar) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
const { mode, originalX, originalWidth } = drag;
|
|
426
|
+
if (mode === DragMode.Move) {
|
|
427
|
+
this.handleDragMove(drag, originalX, originalWidth, bar, dx);
|
|
428
|
+
}
|
|
429
|
+
else if (mode === DragMode.ResizeRight) {
|
|
430
|
+
this.handleDragResizeRight(drag, originalX, originalWidth, bar, dx);
|
|
431
|
+
}
|
|
432
|
+
else if (mode === DragMode.ResizeLeft) {
|
|
433
|
+
this.handleDragResizeLeft(drag, originalX, originalWidth, bar, dx);
|
|
434
|
+
}
|
|
435
|
+
else {
|
|
436
|
+
// Drag mode is exhaustive by type, this guards future changes.
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
handleDragMove(drag, originalX, originalWidth, bar, dx) {
|
|
440
|
+
const newX = Math.max(0, originalX + dx);
|
|
441
|
+
bar.setAttribute('x', String(newX));
|
|
442
|
+
const leftHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--left');
|
|
443
|
+
const rightHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--right');
|
|
444
|
+
if (leftHandle) {
|
|
445
|
+
leftHandle.setAttribute('x', String(newX));
|
|
446
|
+
}
|
|
447
|
+
if (rightHandle) {
|
|
448
|
+
rightHandle.setAttribute('x', String(newX + originalWidth - HANDLE_WIDTH));
|
|
449
|
+
}
|
|
450
|
+
const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
|
|
451
|
+
if (clipRect) {
|
|
452
|
+
clipRect.setAttribute('x', String(newX + 2));
|
|
453
|
+
}
|
|
454
|
+
const label = drag.barGroup.querySelector('.sdc-gantt-bar-label');
|
|
455
|
+
if (label) {
|
|
456
|
+
label.setAttribute('x', String(newX + TASK_LABEL_HORIZONTAL_PADDING));
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
handleDragResizeRight(drag, originalX, originalWidth, bar, dx) {
|
|
460
|
+
const newWidth = Math.max(drag.colW / DRAG_MIN_HANDLE_FACTOR, originalWidth + dx);
|
|
461
|
+
bar.setAttribute('width', String(newWidth));
|
|
462
|
+
const rightHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--right');
|
|
463
|
+
if (rightHandle) {
|
|
464
|
+
rightHandle.setAttribute('x', String(originalX + newWidth - HANDLE_WIDTH));
|
|
465
|
+
}
|
|
466
|
+
const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
|
|
467
|
+
if (clipRect) {
|
|
468
|
+
clipRect.setAttribute('width', String(Math.max(newWidth - 4, 0)));
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
handleDragResizeLeft(drag, originalX, originalWidth, bar, dx) {
|
|
472
|
+
const newWidth = Math.max(drag.colW / DRAG_MIN_HANDLE_FACTOR, originalWidth - dx);
|
|
473
|
+
const newX = originalX + (originalWidth - newWidth);
|
|
474
|
+
bar.setAttribute('x', String(newX));
|
|
475
|
+
bar.setAttribute('width', String(newWidth));
|
|
476
|
+
const leftHandle = drag.barGroup.querySelector('.sdc-gantt-bar-handle--left');
|
|
477
|
+
if (leftHandle) {
|
|
478
|
+
leftHandle.setAttribute('x', String(newX));
|
|
479
|
+
}
|
|
480
|
+
const clipRect = this.svg.querySelector(`#clip-${drag.task.id} rect`);
|
|
481
|
+
if (clipRect) {
|
|
482
|
+
clipRect.setAttribute('x', String(newX + 2));
|
|
483
|
+
clipRect.setAttribute('width', String(Math.max(newWidth - 4, 0)));
|
|
484
|
+
}
|
|
485
|
+
const label = drag.barGroup.querySelector('.sdc-gantt-bar-label');
|
|
486
|
+
if (label) {
|
|
487
|
+
label.setAttribute('x', String(newX + TASK_LABEL_HORIZONTAL_PADDING));
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
onMouseUp(e) {
|
|
491
|
+
if (!this.drag) {
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const { task, barGroup, rangeStart, colW, mode } = this.drag;
|
|
495
|
+
const bar = barGroup.querySelector(BAR_SELECTOR);
|
|
496
|
+
if (!bar) {
|
|
497
|
+
this.drag = null;
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const finalX = parseFloat(bar.getAttribute('x') ?? '0');
|
|
501
|
+
const finalW = parseFloat(bar.getAttribute('width') ?? '0');
|
|
502
|
+
const dx = e.clientX - this.drag.startX;
|
|
503
|
+
this.emitDateChangeIfSignificantMovement(task, finalX, finalW, dx, rangeStart, colW, mode);
|
|
504
|
+
// Reset visual states
|
|
505
|
+
bar.removeAttribute('stroke');
|
|
506
|
+
bar.removeAttribute('stroke-width');
|
|
507
|
+
barGroup.style.cursor = 'grab';
|
|
508
|
+
this.drag = null;
|
|
509
|
+
}
|
|
510
|
+
emitDateChangeIfSignificantMovement(task, finalX, finalW, dx, rangeStart, colW, mode) {
|
|
511
|
+
// Only emit if there was meaningful movement
|
|
512
|
+
if (Math.abs(dx) > 2 && this.options.onDateChange) {
|
|
513
|
+
const { newStart, newEnd } = this.calculateNewDates(task, finalX, finalW, rangeStart, colW, mode);
|
|
514
|
+
this.options.onDateChange(task, newStart, newEnd);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
calculateNewDates(task, finalX, finalW, rangeStart, colW, mode) {
|
|
518
|
+
const durationMs = task.end.getTime() - task.start.getTime();
|
|
519
|
+
let newStart;
|
|
520
|
+
let newEnd;
|
|
521
|
+
if (mode === DragMode.Move) {
|
|
522
|
+
newStart = this.xToDate(finalX, rangeStart, colW);
|
|
523
|
+
newEnd = new Date(newStart.getTime() + durationMs);
|
|
524
|
+
}
|
|
525
|
+
else if (mode === DragMode.ResizeRight) {
|
|
526
|
+
newStart = task.start;
|
|
527
|
+
newEnd = this.xToDate(finalX + finalW, rangeStart, colW);
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
// resize-left
|
|
531
|
+
newStart = this.xToDate(finalX, rangeStart, colW);
|
|
532
|
+
newEnd = task.end;
|
|
533
|
+
}
|
|
534
|
+
return { newStart, newEnd };
|
|
535
|
+
}
|
|
536
|
+
// ---------------------------------------------------------------------------
|
|
537
|
+
// Popup
|
|
538
|
+
// ---------------------------------------------------------------------------
|
|
539
|
+
showPopup(task, clientX, clientY) {
|
|
540
|
+
this.removePopup();
|
|
541
|
+
const div = document.createElement('div');
|
|
542
|
+
div.className = 'sdc-gantt-popup';
|
|
543
|
+
div.style.cssText = `
|
|
544
|
+
position: fixed;
|
|
545
|
+
z-index: 9999;
|
|
546
|
+
background: #fff;
|
|
547
|
+
border: 1px solid #ccc;
|
|
548
|
+
border-radius: 4px;
|
|
549
|
+
padding: 8px 12px;
|
|
550
|
+
box-shadow: 0 2px 8px rgba(0,0,0,.2);
|
|
551
|
+
font-size: 13px;
|
|
552
|
+
pointer-events: none;
|
|
553
|
+
white-space: nowrap;
|
|
554
|
+
`;
|
|
555
|
+
const formatOpts = { day: '2-digit', month: 'short', year: 'numeric' };
|
|
556
|
+
const start = task.start.toLocaleDateString('pt-BR', formatOpts);
|
|
557
|
+
const end = task.end.toLocaleDateString('pt-BR', formatOpts);
|
|
558
|
+
const title = document.createElement('strong');
|
|
559
|
+
title.style.display = 'block';
|
|
560
|
+
title.style.marginBottom = '4px';
|
|
561
|
+
title.textContent = task.name;
|
|
562
|
+
const startLabel = document.createElement('span');
|
|
563
|
+
startLabel.textContent = `Inicio: ${start}`;
|
|
564
|
+
const lineBreak = document.createElement('br');
|
|
565
|
+
const endLabel = document.createElement('span');
|
|
566
|
+
endLabel.textContent = `Fim: ${end}`;
|
|
567
|
+
div.replaceChildren(title, startLabel, lineBreak, endLabel); /*
|
|
568
|
+
<strong style="display:block;margin-bottom:4px;">${task.name}</strong>
|
|
569
|
+
<span>Início: ${start}</span><br>
|
|
570
|
+
<span>Fim: ${end}</span>
|
|
571
|
+
*/
|
|
572
|
+
div.style.left = `${clientX + this.PADDING}px`;
|
|
573
|
+
div.style.top = `${clientY - 10}px`;
|
|
574
|
+
document.body.appendChild(div);
|
|
575
|
+
this.popup = div;
|
|
576
|
+
// Auto-remove after 3 s
|
|
577
|
+
setTimeout(() => this.removePopup(), POPUP_AUTO_REMOVE_DELAY_MS);
|
|
578
|
+
// Remove on next click anywhere
|
|
579
|
+
const removeOnClick = () => {
|
|
580
|
+
this.removePopup();
|
|
581
|
+
document.removeEventListener('click', removeOnClick, true);
|
|
582
|
+
};
|
|
583
|
+
document.addEventListener('click', removeOnClick, true);
|
|
584
|
+
}
|
|
585
|
+
removePopup() {
|
|
586
|
+
if (this.popup?.parentNode) {
|
|
587
|
+
this.popup.parentNode.removeChild(this.popup);
|
|
588
|
+
}
|
|
589
|
+
this.popup = null;
|
|
590
|
+
}
|
|
591
|
+
// ---------------------------------------------------------------------------
|
|
592
|
+
// Position / dimension helpers
|
|
593
|
+
// ---------------------------------------------------------------------------
|
|
594
|
+
computeBarX(taskStart, rangeStart, colW) {
|
|
595
|
+
const mode = this.options.viewMode;
|
|
596
|
+
switch (mode) {
|
|
597
|
+
case 'hour':
|
|
598
|
+
return diffHours(rangeStart, taskStart) * colW;
|
|
599
|
+
case 'day':
|
|
600
|
+
return diffDays(rangeStart, taskStart) * colW;
|
|
601
|
+
case 'week':
|
|
602
|
+
return (diffDays(rangeStart, taskStart) / DAYS_IN_WEEK) * colW;
|
|
603
|
+
case 'month': {
|
|
604
|
+
const monthDiff = (taskStart.getFullYear() - rangeStart.getFullYear()) * MONTHS_IN_YEAR +
|
|
605
|
+
(taskStart.getMonth() - rangeStart.getMonth());
|
|
606
|
+
const dayFraction = (taskStart.getDate() - 1) / new Date(taskStart.getFullYear(), taskStart.getMonth() + 1, 0).getDate();
|
|
607
|
+
return (monthDiff + dayFraction) * colW;
|
|
608
|
+
}
|
|
609
|
+
default:
|
|
610
|
+
return diffDays(rangeStart, taskStart) * colW;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
computeBarWidth(task, colW) {
|
|
614
|
+
const mode = this.options.viewMode;
|
|
615
|
+
switch (mode) {
|
|
616
|
+
case 'hour':
|
|
617
|
+
return diffHours(task.start, task.end) * colW;
|
|
618
|
+
case 'day':
|
|
619
|
+
return diffDays(task.start, task.end) * colW;
|
|
620
|
+
case 'week':
|
|
621
|
+
return (diffDays(task.start, task.end) / DAYS_IN_WEEK) * colW;
|
|
622
|
+
case 'month': {
|
|
623
|
+
const daysInRange = diffDays(task.start, task.end);
|
|
624
|
+
const daysInMonth = new Date(task.start.getFullYear(), task.start.getMonth() + 1, 0).getDate();
|
|
625
|
+
return (daysInRange / daysInMonth) * colW;
|
|
626
|
+
}
|
|
627
|
+
default:
|
|
628
|
+
return diffDays(task.start, task.end) * colW;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
xToDate(x, rangeStart, colW) {
|
|
632
|
+
const mode = this.options.viewMode;
|
|
633
|
+
const slots = x / colW;
|
|
634
|
+
switch (mode) {
|
|
635
|
+
case 'hour':
|
|
636
|
+
return addHours(rangeStart, Math.round(slots));
|
|
637
|
+
case 'day':
|
|
638
|
+
return addDays(rangeStart, Math.round(slots));
|
|
639
|
+
case 'week':
|
|
640
|
+
return addDays(rangeStart, Math.round(slots * DAYS_IN_WEEK));
|
|
641
|
+
case 'month': {
|
|
642
|
+
const d = new Date(rangeStart);
|
|
643
|
+
d.setMonth(d.getMonth() + Math.floor(slots));
|
|
644
|
+
return d;
|
|
645
|
+
}
|
|
646
|
+
default:
|
|
647
|
+
return addDays(rangeStart, Math.round(slots));
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// ---------------------------------------------------------------------------
|
|
651
|
+
// SVG helpers
|
|
652
|
+
// ---------------------------------------------------------------------------
|
|
653
|
+
clearSvg() {
|
|
654
|
+
while (this.svg.firstChild) {
|
|
655
|
+
this.svg.removeChild(this.svg.firstChild);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
createSvgElement(tag) {
|
|
659
|
+
return document.createElementNS(SVG_NS, tag);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FudHQuZW5naW5lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vbGliL3NyYy9mZWF0dXJlcy9nYW50dC9nYW50dC5lbmdpbmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLGdCQUFnQixFQUNoQix1QkFBdUIsRUFDdkIsbUJBQW1CLEVBQ25CLGdCQUFnQixHQUNqQixNQUFNLGtDQUFrQyxDQUFDO0FBRTFDLE9BQU8sRUFDTCxPQUFPLEVBQ1AsUUFBUSxFQUNSLFFBQVEsRUFDUixTQUFTLEVBQ1QsY0FBYyxFQUNkLGVBQWUsRUFDZixnQkFBZ0IsRUFDaEIsZUFBZSxFQUNmLFNBQVMsRUFDVCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFdBQVcsRUFDWCxZQUFZLEVBQ1osV0FBVyxHQUNaLE1BQU0sb0JBQW9CLENBQUM7QUFFNUIsOEVBQThFO0FBQzlFLDJCQUEyQjtBQUMzQiw4RUFBOEU7QUFFOUUsTUFBTSxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ25CLE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDO0FBQ3JDLE1BQU0sWUFBWSxHQUFHLENBQUMsQ0FBQztBQUN2QixNQUFNLDRCQUE0QixHQUFHLENBQUMsQ0FBQztBQUN2QyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7QUFDdkIsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFDeEMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7QUFDakMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLENBQUM7QUFDeEMsTUFBTSxjQUFjLEdBQUcsRUFBRSxDQUFDO0FBQzFCLE1BQU0sWUFBWSxHQUFHLGdCQUFnQixDQUFDO0FBRXRDLElBQUssUUFJSjtBQUpELFdBQUssUUFBUTtJQUNYLHVDQUFJLENBQUE7SUFDSixtREFBVSxDQUFBO0lBQ1YscURBQVcsQ0FBQTtBQUNiLENBQUMsRUFKSSxRQUFRLEtBQVIsUUFBUSxRQUlaO0FBNkJELDhFQUE4RTtBQUM5RSw2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QUFDLENBQUM7UUFDNUMsQ0FBQztJQUNILENBQUM7SUFFTyxnQkFBZ0IsQ0FBdUMsR0FBTTtRQUNuRSxPQUFPLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQy9DLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEdBTlRUX0JBUl9IRUlHSFQsXG4gIEdBTlRUX0RFRkFVTFRfQkFSX0NPTE9SLFxuICBHQU5UVF9IRUFERVJfSEVJR0hULFxuICBHQU5UVF9ST1dfSEVJR0hULFxufSBmcm9tICcuLi8uLi9jb3JlL2NvbnN0YW50cy9nYW50dC5jb25zdCc7XG5pbXBvcnQgdHlwZSB7IEdhbnR0VGFzaywgR2FudHRWaWV3TW9kZSB9IGZyb20gJy4uLy4uL2NvcmUvdHlwZXMvZ2FudHQudHlwZSc7XG5pbXBvcnQge1xuICBhZGREYXlzLFxuICBhZGRIb3VycyxcbiAgZGlmZkRheXMsXG4gIGRpZmZIb3VycyxcbiAgZm9ybWF0RGF5TW9udGgsXG4gIGZvcm1hdEhvdXJMYWJlbCxcbiAgZm9ybWF0TW9udGhMYWJlbCxcbiAgZm9ybWF0V2Vla0xhYmVsLFxuICBpc1dlZWtlbmQsXG4gIGlzU2FtZURheSxcbiAgc3RhcnRPZkRheSxcbiAgc3RhcnRPZkhvdXIsXG4gIHN0YXJ0T2ZNb250aCxcbiAgc3RhcnRPZldlZWssXG59IGZyb20gJy4vZ2FudHQtZGF0ZS51dGlscyc7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gUHVibGljIHR5cGVzICYgQ29uc3RhbnRzXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgUlhfVkFMVUUgPSAzO1xuY29uc3QgREFURV9SQU5HRV9TQUZFVFlfTElNSVQgPSA1MDAwO1xuY29uc3QgREFZU19JTl9XRUVLID0gNztcbmNvbnN0IEhFQURFUl9MQUJFTF9WRVJUSUNBTF9PRkZTRVQgPSA1O1xuY29uc3QgSEFORExFX1dJRFRIID0gNjtcbmNvbnN0IFRBU0tfTEFCRUxfSE9SSVpPTlRBTF9QQURESU5HID0gNjtcbmNvbnN0IERSQUdfTUlOX0hBTkRMRV9GQUNUT1IgPSAyO1xuY29uc3QgUE9QVVBfQVVUT19SRU1PVkVfREVMQVlfTVMgPSAzMDAwO1xuY29uc3QgTU9OVEhTX0lOX1lFQVIgPSAxMjtcbmNvbnN0IEJBUl9TRUxFQ1RPUiA9ICcuc2RjLWdhbnR0LWJhcic7XG5cbmVudW0gRHJhZ01vZGUge1xuICBNb3ZlLFxuICBSZXNpemVMZWZ0LFxuICBSZXNpemVSaWdodCxcbn1cblxuZXhwb3J0IGludGVyZmFjZSBHYW50dEVuZ2luZU9wdGlvbnMge1xuICB2aWV3TW9kZTogR2FudHRWaWV3TW9kZTtcbiAgYWxsb3dNb3ZlbWVudDogYm9vbGVhbjtcbiAgaGFzUG9wdXA6IGJvb2xlYW47XG4gIG9uVGFza0NsaWNrPzogKHRhc2s6IEdhbnR0VGFzaykgPT4gdm9pZDtcbiAgb25EYXRlQ2hhbmdlPzogKHRhc2s6IEdhbnR0VGFzaywgc3RhcnQ6IERhdGUsIGVuZDogRGF0ZSkgPT4gdm9pZDtcbn1cblxuaW50ZXJmYWNlIERyYWdTdGF0ZSB7XG4gIHRhc2s6IEdhbnR0VGFzaztcbiAgYmFyR3JvdXA6IFNWR0dFbGVtZW50O1xuICBzdGFydFg6IG51bWJlcjtcbiAgb3JpZ2luYWxYOiBudW1iZXI7XG4gIG9yaWdpbmFsV2lkdGg6IG51bWJlcjtcbiAgY29sVzogbnVtYmVyO1xuICByYW5nZVN0YXJ0OiBEYXRlO1xuICByb3dJbmRleDogbnVtYmVyO1xuICBtb2RlOiBEcmFnTW9kZTtcbn1cblxuaW50ZXJmYWNlIERyYWdTdGF0ZVNlZWQge1xuICBjbGllbnRYOiBudW1iZXI7XG4gIHJhbmdlU3RhcnQ6IERhdGU7XG4gIGNvbFc6IG51bWJlcjtcbiAgcm93SW5kZXg6IG51bWJlcjtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBHYW50dEVuZ2luZSDigJMgcHVyZSBUeXBlU2NyaXB0IGNsYXNzLCBubyBBbmd1bGFyIGRlY29yYXRvcnNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBTVkdfTlMgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xuXG5leHBvcnQgY2xhc3MgR2FudHRFbmdpbmUge1xuICBwcml2YXRlIHJlYWRvbmx5IHN2ZzogU1ZHRWxlbWVudDtcbiAgcHJpdmF0ZSB0YXNrczogR2FudHRUYXNrW107XG4gIHByaXZhdGUgb3B0aW9uczogR2FudHRFbmdpbmVPcHRpb25zO1xuXG4gIC8vIExheW91dCBjb25zdGFudHMg4oCTIGtlcHQgaW4gc3luYyB3aXRoIFNDU1MgdG9rZW5zXG4gIHByaXZhdGUgcmVhZG9ubHkgSEVBREVSX0hFSUdIVCA9IEdBTlRUX0hFQURFUl9IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgUk9XX0hFSUdIVCA9IEdBTlRUX1JPV19IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgQkFSX0hFSUdIVCA9IEdBTlRUX0JBUl9IRUlHSFQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgUEFERElORyA9IDEyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgQ09MVU1OX1dJRFRIUzogUmVjb3JkPEdhbnR0Vmlld01vZGUsIG51bWJlcj4gPSB7XG4gICAgaG91cjogNTAsXG4gICAgZGF5OiA1MCxcbiAgICB3ZWVrOiAxNDAsXG4gICAgbW9udGg6IDEyMCxcbiAgfTtcblxuICAvLyBQb3B1cCBlbGVtZW50IG1hbmFnZWQgYnkgdGhlIGVuZ2luZVxuICBwcml2YXRlIHBvcHVwOiBIVE1MRGl2RWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8vIEFjdGl2ZSBkcmFnIHN0YXRlXG4gIHByaXZhdGUgZHJhZzogRHJhZ1N0YXRlIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gQm91bmQgZ2xvYmFsIGhhbmRsZXJzIChrZXB0IHNvIHdlIGNhbiByZW1vdmUgdGhlbSBvbiBkZXN0cm95KVxuICBwcml2YXRlIHJlYWRvbmx5IGJvdW5kTW91c2VNb3ZlOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSBib3VuZE1vdXNlVXA6IChlOiBNb3VzZUV2ZW50KSA9PiB2b2lkO1xuXG4gIGNvbnN0cnVjdG9yKHN2ZzogU1ZHRWxlbWVudCwgdGFza3M6IEdhbnR0VGFza1tdLCBvcHRpb25zOiBHYW50dEVuZ2luZU9wdGlvbnMpIHtcbiAgICB0aGlzLnN2ZyA9IHN2ZztcbiAgICB0aGlzLnRhc2tzID0gdGFza3M7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgIHRoaXMuYm91bmRNb3VzZU1vdmUgPSB0aGlzLm9uTW91c2VNb3ZlLmJpbmQodGhpcyk7XG4gICAgdGhpcy5ib3VuZE1vdXNlVXAgPSB0aGlzLm9uTW91c2VVcC5iaW5kKHRoaXMpO1xuXG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE1vdXNlTW92ZSk7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUHVibGljIEFQSVxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwdWJsaWMgcmVmcmVzaCh0YXNrczogR2FudHRUYXNrW10pOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tzID0gdGFza3M7XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVPcHRpb25zKG9wdGlvbnM6IFBhcnRpYWw8R2FudHRFbmdpbmVPcHRpb25zPik6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zLCAuLi5vcHRpb25zIH07XG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBjaGFuZ2VWaWV3TW9kZShtb2RlOiBHYW50dFZpZXdNb2RlKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVPcHRpb25zKHsgdmlld01vZGU6IG1vZGUgfSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5ib3VuZE1vdXNlVXApO1xuICAgIHRoaXMucmVtb3ZlUG9wdXAoKTtcbiAgICB0aGlzLmNsZWFyU3ZnKCk7XG4gIH1cblxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgLy8gUmVuZGVyIHBpcGVsaW5lXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgcmVuZGVyKCk6IHZvaWQge1xuICAgIHRoaXMuY2xlYXJTdmcoKTtcbiAgICB0aGlzLnJlbW92ZVBvcHVwKCk7XG4gICAgdGhpcy5kcmFnID0gbnVsbDtcblxuICAgIGlmICh0aGlzLnRhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgZGF0ZXMgfSA9IHRoaXMuY29tcHV0ZURhdGVSYW5nZSgpO1xuICAgIGNvbnN0IGNvbFcgPSB0aGlzLkNPTFVNTl9XSURUSFNbdGhpcy5vcHRpb25zLnZpZXdNb2RlXTtcbiAgICBjb25zdCB0b3RhbFdpZHRoID0gZGF0ZXMubGVuZ3RoICogY29sVztcbiAgICBjb25zdCB0b3RhbEhlaWdodCA9IHRoaXMuSEVBREVSX0hFSUdIVCArIHRoaXMudGFza3MubGVuZ3RoICogdGhpcy5ST1dfSEVJR0hUO1xuXG4gICAgdGhpcy5zdmcuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgdGhpcy5zdmcuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICB0aGlzLnN2Zy5zZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnLCBgMCAwICR7dG90YWxXaWR0aH0gJHt0b3RhbEhlaWdodH1gKTtcblxuICAgIHRoaXMuZHJhd0dyaWQoZGF0ZXMsIGNvbFcsIHRvdGFsV2lkdGgsIHRvdGFsSGVpZ2h0KTtcbiAgICB0aGlzLmRyYXdCYXJzKGRhdGVzWzBdLCBjb2xXKTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBEYXRlIHJhbmdlIGNvbXB1dGF0aW9uXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY29tcHV0ZURhdGVSYW5nZSgpOiB7IHN0YXJ0OiBEYXRlOyBlbmQ6IERhdGU7IGRhdGVzOiBEYXRlW10gfSB7XG4gICAgY29uc3QgbW9kZSA9IHRoaXMub3B0aW9ucy52aWV3TW9kZTtcblxuICAgIGxldCBtaW5EYXRlID0gdGhpcy50YXNrc1swXS5zdGFydDtcbiAgICBsZXQgbWF4RGF0ZSA9IHRoaXMudGFza3NbMF0uZW5kO1xuXG4gICAgZm9yIChjb25zdCB0YXNrIG9mIHRoaXMudGFza3MpIHtcbiAgICAgIGlmICh0YXNrLnN0YXJ0IDwgbWluRGF0ZSkge1xuICAgICAgICBtaW5EYXRlID0gdGFzay5zdGFydDtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhc2suZW5kID4gbWF4RGF0ZSkge1xuICAgICAgICBtYXhEYXRlID0gdGFzay5lbmQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQWRkIG1hcmdpblxuICAgIGNvbnN0IG1hcmdpbmVkTWF4ID0gYWRkRGF5cyhtYXhEYXRlLCAxKTtcblxuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5zbG90U3RhcnQobWluRGF0ZSwgbW9kZSk7XG4gICAgY29uc3QgZW5kID0gdGhpcy5zbG90U3RhcnQoYWRkRGF5cyhtYXJnaW5lZE1heCwgMSksIG1vZGUpO1xuICAgIGNvbnN0IGRhdGVzOiBEYXRlW10gPSBbXTtcblxuICAgIGxldCBjdXJzb3IgPSBuZXcgRGF0ZShzdGFydCk7XG4gICAgLy8gU2FmZXR5IGxpbWl0IHRvIGF2b2lkIGluZmluaXRlIGxvb3BzXG4gICAgbGV0IHNhZmV0eSA9IDA7XG4gICAgd2hpbGUgKGN1cnNvciA8IGVuZCAmJiBzYWZldHkgPCBEQVRFX1JBTkdFX1NBRkVUWV9MSU1JVCkge1xuICAgICAgZGF0ZXMucHVzaChuZXcgRGF0ZShjdXJzb3IpKTtcbiAgICAgIGN1cnNvciA9IHRoaXMubmV4dFNsb3QoY3Vyc29yLCBtb2RlKTtcbiAgICAgIHNhZmV0eSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7IHN0YXJ0LCBlbmQsIGRhdGVzIH07XG4gIH1cblxuICBwcml2YXRlIHNsb3RTdGFydChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogRGF0ZSB7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZIb3VyKGRhdGUpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZEYXkoZGF0ZSk7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZXZWVrKGRhdGUpO1xuICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICByZXR1cm4gc3RhcnRPZk1vbnRoKGRhdGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIHN0YXJ0T2ZEYXkoZGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBuZXh0U2xvdChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogRGF0ZSB7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGFkZEhvdXJzKGRhdGUsIDEpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgMSk7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgREFZU19JTl9XRUVLKTtcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBkID0gbmV3IERhdGUoZGF0ZSk7XG4gICAgICAgIGQuc2V0TW9udGgoZC5nZXRNb250aCgpICsgMSk7XG4gICAgICAgIHJldHVybiBkO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGFkZERheXMoZGF0ZSwgMSk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIEdyaWQgZHJhd2luZ1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGRyYXdHcmlkKGRhdGVzOiBEYXRlW10sIGNvbFc6IG51bWJlciwgdG90YWxXaWR0aDogbnVtYmVyLCB0b3RhbEhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbW9kZSA9IHRoaXMub3B0aW9ucy52aWV3TW9kZTtcblxuICAgIC8vIFJvdyBiYWNrZ3JvdW5kc1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YXNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3QgeSA9IHRoaXMuSEVBREVSX0hFSUdIVCArIGkgKiB0aGlzLlJPV19IRUlHSFQ7XG4gICAgICBjb25zdCBiZyA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgYmcuc2V0QXR0cmlidXRlKCd4JywgJzAnKTtcbiAgICAgIGJnLnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyh5KSk7XG4gICAgICBiZy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKHRvdGFsV2lkdGgpKTtcbiAgICAgIGJnLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuUk9XX0hFSUdIVCkpO1xuICAgICAgYmcuc2V0QXR0cmlidXRlKCdjbGFzcycsIGBzZGMtZ2FudHQtcm93LWJnICR7aSAlIDIgPT09IDAgPyAnc2RjLWdhbnR0LXJvdy1iZy0tZXZlbicgOiAnc2RjLWdhbnR0LXJvdy1iZy0tb2RkJ31gKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGJnKTtcbiAgICB9XG5cbiAgICAvLyBDb2x1bW4gc2xvdHMg4oCTIGJhY2tncm91bmRzICsgc2VwYXJhdG9ycyArIGxhYmVsc1xuICAgIGNvbnN0IHRvZGF5ID0gc3RhcnRPZkRheShuZXcgRGF0ZSgpKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZGF0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHggPSBpICogY29sVztcbiAgICAgIGNvbnN0IGRhdGUgPSBkYXRlc1tpXTtcblxuICAgICAgLy8gV2Vla2VuZCBoaWdobGlnaHQgKGRheS9ob3VyIG1vZGVzKVxuICAgICAgaWYgKChtb2RlID09PSAnZGF5JyB8fCBtb2RlID09PSAnaG91cicpICYmIGlzV2Vla2VuZChkYXRlKSkge1xuICAgICAgICBjb25zdCB3a1JlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICAgICAgd2tSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyh4KSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcodGhpcy5IRUFERVJfSEVJR0hUKSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKGNvbFcpKTtcbiAgICAgICAgd2tSZWN0LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMudGFza3MubGVuZ3RoICogdGhpcy5ST1dfSEVJR0hUKSk7XG4gICAgICAgIHdrUmVjdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC13ZWVrZW5kJyk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHdrUmVjdCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFRvZGF5IGhpZ2hsaWdodFxuICAgICAgaWYgKG1vZGUgPT09ICdkYXknICYmIGlzU2FtZURheShkYXRlLCB0b2RheSkpIHtcbiAgICAgICAgY29uc3QgdG9kYXlSZWN0ID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdyZWN0Jyk7XG4gICAgICAgIHRvZGF5UmVjdC5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoeCkpO1xuICAgICAgICB0b2RheVJlY3Quc2V0QXR0cmlidXRlKCd5JywgJzAnKTtcbiAgICAgICAgdG9kYXlSZWN0LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcoY29sVykpO1xuICAgICAgICB0b2RheVJlY3Quc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICAgICAgdG9kYXlSZWN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LXRvZGF5Jyk7XG4gICAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRvZGF5UmVjdCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFZlcnRpY2FsIGdyaWQgbGluZVxuICAgICAgY29uc3QgbGluZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnbGluZScpO1xuICAgICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgU3RyaW5nKHgpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCd5MScsIFN0cmluZyh0aGlzLkhFQURFUl9IRUlHSFQpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCd4MicsIFN0cmluZyh4KSk7XG4gICAgICBsaW5lLnNldEF0dHJpYnV0ZSgneTInLCBTdHJpbmcodG90YWxIZWlnaHQpKTtcbiAgICAgIGxpbmUuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtZ3JpZC1saW5lJyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChsaW5lKTtcblxuICAgICAgLy8gSGVhZGVyIGJhY2tncm91bmRcbiAgICAgIGNvbnN0IGhkclJlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKHgpKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd5JywgJzAnKTtcbiAgICAgIGhkclJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhjb2xXKSk7XG4gICAgICBoZHJSZWN0LnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuSEVBREVSX0hFSUdIVCkpO1xuICAgICAgaGRyUmVjdC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1oZWFkZXItY2VsbCcpO1xuICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoaGRyUmVjdCk7XG5cbiAgICAgIC8vIEhlYWRlciBsYWJlbFxuICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3RleHQnKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyh4ICsgY29sVyAvIDIpKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyh0aGlzLkhFQURFUl9IRUlHSFQgLyAyICsgSEVBREVSX0xBQkVMX1ZFUlRJQ0FMX09GRlNFVCkpO1xuICAgICAgbGFiZWwuc2V0QXR0cmlidXRlKCd0ZXh0LWFuY2hvcicsICdtaWRkbGUnKTtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWhlYWRlci1sYWJlbCcpO1xuICAgICAgbGFiZWwudGV4dENvbnRlbnQgPSB0aGlzLmZvcm1hdENvbHVtbkxhYmVsKGRhdGUsIG1vZGUpO1xuICAgICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQobGFiZWwpO1xuICAgIH1cblxuICAgIC8vIEJvdHRvbSBoZWFkZXIgYm9yZGVyIGxpbmVcbiAgICBjb25zdCBoZHJCb3JkZXIgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2xpbmUnKTtcbiAgICBoZHJCb3JkZXIuc2V0QXR0cmlidXRlKCd4MScsICcwJyk7XG4gICAgaGRyQm9yZGVyLnNldEF0dHJpYnV0ZSgneTEnLCBTdHJpbmcodGhpcy5IRUFERVJfSEVJR0hUKSk7XG4gICAgaGRyQm9yZGVyLnNldEF0dHJpYnV0ZSgneDInLCBTdHJpbmcodG90YWxXaWR0aCkpO1xuICAgIGhkckJvcmRlci5zZXRBdHRyaWJ1dGUoJ3kyJywgU3RyaW5nKHRoaXMuSEVBREVSX0hFSUdIVCkpO1xuICAgIGhkckJvcmRlci5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1oZWFkZXItYm9yZGVyJyk7XG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoaGRyQm9yZGVyKTtcblxuICAgIC8vIEhvcml6b250YWwgcm93IHNlcGFyYXRvcnNcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0aGlzLnRhc2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB5ID0gdGhpcy5IRUFERVJfSEVJR0hUICsgaSAqIHRoaXMuUk9XX0hFSUdIVDtcbiAgICAgIGNvbnN0IGhMaW5lID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdsaW5lJyk7XG4gICAgICBoTGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgJzAnKTtcbiAgICAgIGhMaW5lLnNldEF0dHJpYnV0ZSgneTEnLCBTdHJpbmcoeSkpO1xuICAgICAgaExpbmUuc2V0QXR0cmlidXRlKCd4MicsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgICBoTGluZS5zZXRBdHRyaWJ1dGUoJ3kyJywgU3RyaW5nKHkpKTtcbiAgICAgIGhMaW5lLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWdyaWQtbGluZSBzZGMtZ2FudHQtZ3JpZC1saW5lLS1ob3Jpem9udGFsJyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChoTGluZSk7XG4gICAgfVxuXG4gICAgLy8gUmlnaHQgYm9yZGVyIGxpbmVcbiAgICBjb25zdCByaWdodExpbmUgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2xpbmUnKTtcbiAgICByaWdodExpbmUuc2V0QXR0cmlidXRlKCd4MScsIFN0cmluZyh0b3RhbFdpZHRoKSk7XG4gICAgcmlnaHRMaW5lLnNldEF0dHJpYnV0ZSgneTEnLCAnMCcpO1xuICAgIHJpZ2h0TGluZS5zZXRBdHRyaWJ1dGUoJ3gyJywgU3RyaW5nKHRvdGFsV2lkdGgpKTtcbiAgICByaWdodExpbmUuc2V0QXR0cmlidXRlKCd5MicsIFN0cmluZyh0b3RhbEhlaWdodCkpO1xuICAgIHJpZ2h0TGluZS5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgJ3NkYy1nYW50dC1ncmlkLWxpbmUnKTtcbiAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChyaWdodExpbmUpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRDb2x1bW5MYWJlbChkYXRlOiBEYXRlLCBtb2RlOiBHYW50dFZpZXdNb2RlKTogc3RyaW5nIHtcbiAgICBzd2l0Y2ggKG1vZGUpIHtcbiAgICAgIGNhc2UgJ2hvdXInOlxuICAgICAgICByZXR1cm4gZm9ybWF0SG91ckxhYmVsKGRhdGUpO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdERheU1vbnRoKGRhdGUpO1xuICAgICAgY2FzZSAnd2Vlayc6XG4gICAgICAgIHJldHVybiBmb3JtYXRXZWVrTGFiZWwoZGF0ZSk7XG4gICAgICBjYXNlICdtb250aCc6XG4gICAgICAgIHJldHVybiBmb3JtYXRNb250aExhYmVsKGRhdGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuIGZvcm1hdERheU1vbnRoKGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBCYXIgZHJhd2luZ1xuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIGRyYXdCYXJzKHJhbmdlU3RhcnQ6IERhdGUsIGNvbFc6IG51bWJlcik6IHZvaWQge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy50YXNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgdGhpcy5kcmF3QmFyRWxlbWVudCh0aGlzLnRhc2tzW2ldLCBpLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGRyYXdCYXJFbGVtZW50KHRhc2s6IEdhbnR0VGFzaywgcm93SW5kZXg6IG51bWJlciwgcmFuZ2VTdGFydDogRGF0ZSwgY29sVzogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgYmFyWCA9IHRoaXMuY29tcHV0ZUJhclgodGFzay5zdGFydCwgcmFuZ2VTdGFydCwgY29sVyk7XG4gICAgY29uc3QgYmFyVyA9IE1hdGgubWF4KHRoaXMuY29tcHV0ZUJhcldpZHRoKHRhc2ssIGNvbFcpLCA0KTtcbiAgICBjb25zdCBiYXJZID0gdGhpcy5IRUFERVJfSEVJR0hUICsgcm93SW5kZXggKiB0aGlzLlJPV19IRUlHSFQgKyAodGhpcy5ST1dfSEVJR0hUIC0gdGhpcy5CQVJfSEVJR0hUKSAvIDI7XG4gICAgY29uc3QgY29sb3IgPSB0YXNrLmNvbG9yID8/IEdBTlRUX0RFRkFVTFRfQkFSX0NPTE9SO1xuXG4gICAgY29uc3QgZ3JvdXAgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ2cnKTtcbiAgICBncm91cC5zZXRBdHRyaWJ1dGUoJ2NsYXNzJywgYHNkYy1nYW50dC1iYXItZ3JvdXAke3Rhc2suY3VzdG9tQ2xhc3MgPyAnICcgKyB0YXNrLmN1c3RvbUNsYXNzIDogJyd9YCk7XG4gICAgZ3JvdXAuc2V0QXR0cmlidXRlKCdkYXRhLXRhc2staWQnLCB0YXNrLmlkKTtcbiAgICBncm91cC5zdHlsZS5jdXJzb3IgPSB0aGlzLm9wdGlvbnMuYWxsb3dNb3ZlbWVudCA/ICdncmFiJyA6ICdwb2ludGVyJztcblxuICAgIC8vIE1haW4gYmFyIHJlY3RhbmdsZVxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmNyZWF0ZVN2Z0VsZW1lbnQoJ3JlY3QnKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhiYXJYKSk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgIHJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhiYXJXKSk7XG4gICAgcmVjdC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIFN0cmluZyh0aGlzLkJBUl9IRUlHSFQpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgncngnLCBTdHJpbmcoUlhfVkFMVUUpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgncnknLCBTdHJpbmcoUlhfVkFMVUUpKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgnZmlsbCcsIGNvbG9yKTtcbiAgICByZWN0LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWJhcicpO1xuICAgIGdyb3VwLmFwcGVuZENoaWxkKHJlY3QpO1xuXG4gICAgLy8gVGFzayBuYW1lIGluc2lkZSBiYXJcbiAgICBpZiAodGFzay5zaG93VGFza05hbWUpIHtcbiAgICAgIGNvbnN0IHRleHRFbCA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgndGV4dCcpO1xuICAgICAgdGV4dEVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhiYXJYICsgVEFTS19MQUJFTF9IT1JJWk9OVEFMX1BBRERJTkcpKTtcbiAgICAgIHRleHRFbC5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSArIHRoaXMuQkFSX0hFSUdIVCAvIDIgKyA0KSk7XG4gICAgICB0ZXh0RWwuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtYmFyLWxhYmVsJyk7XG4gICAgICB0ZXh0RWwuc2V0QXR0cmlidXRlKCdjbGlwLXBhdGgnLCBgdXJsKCNjbGlwLSR7dGFzay5pZH0pYCk7XG4gICAgICB0ZXh0RWwudGV4dENvbnRlbnQgPSB0YXNrLm5hbWU7XG4gICAgICBncm91cC5hcHBlbmRDaGlsZCh0ZXh0RWwpO1xuXG4gICAgICAvLyBDbGlwIHBhdGggc28gdGV4dCBzdGF5cyBpbnNpZGUgdGhlIGJhclxuICAgICAgY29uc3QgZGVmcyA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnZGVmcycpO1xuICAgICAgY29uc3QgY2xpcCA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgnY2xpcFBhdGgnKTtcbiAgICAgIGNsaXAuc2V0QXR0cmlidXRlKCdpZCcsIGBjbGlwLSR7dGFzay5pZH1gKTtcbiAgICAgIGNvbnN0IGNsaXBSZWN0ID0gdGhpcy5jcmVhdGVTdmdFbGVtZW50KCdyZWN0Jyk7XG4gICAgICBjbGlwUmVjdC5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoYmFyWCArIDIpKTtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneScsIFN0cmluZyhiYXJZKSk7XG4gICAgICBjbGlwUmVjdC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKE1hdGgubWF4KGJhclcgLSA0LCAwKSkpO1xuICAgICAgY2xpcFJlY3Quc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBTdHJpbmcodGhpcy5CQVJfSEVJR0hUKSk7XG4gICAgICBjbGlwLmFwcGVuZENoaWxkKGNsaXBSZWN0KTtcbiAgICAgIGRlZnMuYXBwZW5kQ2hpbGQoY2xpcCk7XG4gICAgICB0aGlzLnN2Zy5pbnNlcnRCZWZvcmUoZGVmcywgdGhpcy5zdmcuZmlyc3RDaGlsZCk7XG4gICAgfVxuXG4gICAgLy8gUmVzaXplIGhhbmRsZXMgKG9ubHkgd2hlbiBtb3ZlbWVudCBpcyBhbGxvd2VkKVxuICAgIGlmICh0aGlzLm9wdGlvbnMuYWxsb3dNb3ZlbWVudCkge1xuICAgICAgY29uc3QgbGVmdEhhbmRsZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcoYmFyWCkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgU3RyaW5nKEhBTkRMRV9XSURUSCkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIFN0cmluZyh0aGlzLkJBUl9IRUlHSFQpKTtcbiAgICAgIGxlZnRIYW5kbGUuc2V0QXR0cmlidXRlKCdyeCcsIFN0cmluZyhSWF9WQUxVRSkpO1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAncmdiYSgwLDAsMCwwLjIpJyk7XG4gICAgICBsZWZ0SGFuZGxlLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnc2RjLWdhbnR0LWJhci1oYW5kbGUgc2RjLWdhbnR0LWJhci1oYW5kbGUtLWxlZnQnKTtcbiAgICAgIGxlZnRIYW5kbGUuc3R5bGUuY3Vyc29yID0gJ2V3LXJlc2l6ZSc7XG4gICAgICBsZWZ0SGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgIHRoaXMuc3RhcnREcmFnKGUsIHRhc2ssIGdyb3VwLCBEcmFnTW9kZS5SZXNpemVMZWZ0LCB7XG4gICAgICAgICAgcmFuZ2VTdGFydCxcbiAgICAgICAgICBjb2xXLFxuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwLmFwcGVuZENoaWxkKGxlZnRIYW5kbGUpO1xuXG4gICAgICBjb25zdCByaWdodEhhbmRsZSA9IHRoaXMuY3JlYXRlU3ZnRWxlbWVudCgncmVjdCcpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKGJhclggKyBiYXJXIC0gSEFORExFX1dJRFRIKSk7XG4gICAgICByaWdodEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3knLCBTdHJpbmcoYmFyWSkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhIQU5ETEVfV0lEVEgpKTtcbiAgICAgIHJpZ2h0SGFuZGxlLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgU3RyaW5nKHRoaXMuQkFSX0hFSUdIVCkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdyeCcsIFN0cmluZyhSWF9WQUxVRSkpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdmaWxsJywgJ3JnYmEoMCwwLDAsMC4yKScpO1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCdjbGFzcycsICdzZGMtZ2FudHQtYmFyLWhhbmRsZSBzZGMtZ2FudHQtYmFyLWhhbmRsZS0tcmlnaHQnKTtcbiAgICAgIHJpZ2h0SGFuZGxlLnN0eWxlLmN1cnNvciA9ICdldy1yZXNpemUnO1xuICAgICAgcmlnaHRIYW5kbGUuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgKGU6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5zdGFydERyYWcoZSwgdGFzaywgZ3JvdXAsIERyYWdNb2RlLlJlc2l6ZVJpZ2h0LCB7XG4gICAgICAgICAgcmFuZ2VTdGFydCxcbiAgICAgICAgICBjb2xXLFxuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIGNsaWVudFg6IGUuY2xpZW50WCxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwLmFwcGVuZENoaWxkKHJpZ2h0SGFuZGxlKTtcbiAgICB9XG5cbiAgICAvLyBDbGljayAvIGRyYWcgb24gbWFpbiBiYXJcbiAgICByZWN0LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIChlOiBNb3VzZUV2ZW50KSA9PiB7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmFsbG93TW92ZW1lbnQpIHtcbiAgICAgICAgdGhpcy5zdGFydERyYWcoZSwgdGFzaywgZ3JvdXAsIERyYWdNb2RlLk1vdmUsIHtcbiAgICAgICAgICByYW5nZVN0YXJ0LFxuICAgICAgICAgIGNvbFcsXG4gICAgICAgICAgcm93SW5kZXgsXG4gICAgICAgICAgY2xpZW50WDogZS5jbGllbnRYLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJlY3QuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgLy8gT25seSBmaXJlIGNsaWNrIGlmIG5vdCBkcmFnZ2luZ1xuICAgICAgaWYgKHRoaXMuZHJhZykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5vcHRpb25zLmhhc1BvcHVwKSB7XG4gICAgICAgIHRoaXMuc2hvd1BvcHVwKHRhc2ssIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICAgIH1cbiAgICAgIHRoaXMub3B0aW9ucy5vblRhc2tDbGljaz8uKHRhc2spO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoZ3JvdXApO1xuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIERyYWctYW5kLWRyb3BcbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcHJpdmF0ZSBzdGFydERyYWcoXG4gICAgZTogTW91c2VFdmVudCxcbiAgICB0YXNrOiBHYW50dFRhc2ssXG4gICAgYmFyR3JvdXA6IFNWR0dFbGVtZW50LFxuICAgIG1vZGU6IERyYWdNb2RlLFxuICAgIHNlZWQ6IERyYWdTdGF0ZVNlZWQsXG4gICk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBiYXIgPSBiYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5kcmFnID0gdGhpcy5jcmVhdGVEcmFnU3RhdGUodGFzaywgYmFyR3JvdXAsIGJhciwgbW9kZSwgc2VlZCk7XG4gICAgdGhpcy51cGRhdGVCYXJWaXN1YWxGb3JEcmFnKGJhciwgYmFyR3JvdXApO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVEcmFnU3RhdGUoXG4gICAgdGFzazogR2FudHRUYXNrLFxuICAgIGJhckdyb3VwOiBTVkdHRWxlbWVudCxcbiAgICBiYXI6IFNWR1JlY3RFbGVtZW50LFxuICAgIG1vZGU6IERyYWdNb2RlLFxuICAgIHNlZWQ6IERyYWdTdGF0ZVNlZWRcbiAgKTogRHJhZ1N0YXRlIHtcbiAgICBjb25zdCBzdGFydFggPSBzZWVkLmNsaWVudFg7XG4gICAgY29uc3QgY29sdW1uV2lkdGggPSBzZWVkLmNvbFc7XG4gICAgY29uc3QgZHJhZ1JhbmdlU3RhcnQgPSBzZWVkLnJhbmdlU3RhcnQ7XG4gICAgY29uc3QgZHJhZ1Jvd0luZGV4ID0gc2VlZC5yb3dJbmRleDtcblxuICAgIHJldHVybiB7XG4gICAgICBzdGFydFgsXG4gICAgICB0YXNrLFxuICAgICAgYmFyR3JvdXAsXG4gICAgICBtb2RlLFxuICAgICAgb3JpZ2luYWxYOiBwYXJzZUZsb2F0KGJhci5nZXRBdHRyaWJ1dGUoJ3gnKSA/PyAnMCcpLFxuICAgICAgb3JpZ2luYWxXaWR0aDogcGFyc2VGbG9hdChiYXIuZ2V0QXR0cmlidXRlKCd3aWR0aCcpID8/ICcwJyksXG4gICAgICBjb2xXOiBjb2x1bW5XaWR0aCxcbiAgICAgIHJhbmdlU3RhcnQ6IGRyYWdSYW5nZVN0YXJ0LFxuICAgICAgcm93SW5kZXg6IGRyYWdSb3dJbmRleCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVCYXJWaXN1YWxGb3JEcmFnKGJhcjogU1ZHUmVjdEVsZW1lbnQsIGJhckdyb3VwOiBTVkdHRWxlbWVudCk6IHZvaWQge1xuICAgIGJhckdyb3VwLnN0eWxlLmN1cnNvciA9ICdncmFiYmluZyc7XG4gICAgYmFyLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgJ3ZhcigtLXNkYy1nYW50dC1iYXItc2VsZWN0ZWQtc3Ryb2tlLCAjMjEyNTMzKScpO1xuICAgIGJhci5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICcyJyk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBkcmFnID0gdGhpcy5kcmFnO1xuICAgIGlmICghZHJhZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGR4ID0gZS5jbGllbnRYIC0gZHJhZy5zdGFydFg7XG4gICAgY29uc3QgYmFyID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBtb2RlLCBvcmlnaW5hbFgsIG9yaWdpbmFsV2lkdGggfSA9IGRyYWc7XG5cbiAgICBpZiAobW9kZSA9PT0gRHJhZ01vZGUuTW92ZSkge1xuICAgICAgdGhpcy5oYW5kbGVEcmFnTW92ZShkcmFnLCBvcmlnaW5hbFgsIG9yaWdpbmFsV2lkdGgsIGJhciwgZHgpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gRHJhZ01vZGUuUmVzaXplUmlnaHQpIHtcbiAgICAgIHRoaXMuaGFuZGxlRHJhZ1Jlc2l6ZVJpZ2h0KGRyYWcsIG9yaWdpbmFsWCwgb3JpZ2luYWxXaWR0aCwgYmFyLCBkeCk7XG4gICAgfSBlbHNlIGlmIChtb2RlID09PSBEcmFnTW9kZS5SZXNpemVMZWZ0KSB7XG4gICAgICB0aGlzLmhhbmRsZURyYWdSZXNpemVMZWZ0KGRyYWcsIG9yaWdpbmFsWCwgb3JpZ2luYWxXaWR0aCwgYmFyLCBkeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERyYWcgbW9kZSBpcyBleGhhdXN0aXZlIGJ5IHR5cGUsIHRoaXMgZ3VhcmRzIGZ1dHVyZSBjaGFuZ2VzLlxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRHJhZ01vdmUoZHJhZzogRHJhZ1N0YXRlLCBvcmlnaW5hbFg6IG51bWJlciwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBiYXI6IFNWR1JlY3RFbGVtZW50LCBkeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV3WCA9IE1hdGgubWF4KDAsIG9yaWdpbmFsWCArIGR4KTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1gpKTtcblxuICAgIGNvbnN0IGxlZnRIYW5kbGUgPSBkcmFnLmJhckdyb3VwLnF1ZXJ5U2VsZWN0b3I8U1ZHUmVjdEVsZW1lbnQ+KCcuc2RjLWdhbnR0LWJhci1oYW5kbGUtLWxlZnQnKTtcbiAgICBjb25zdCByaWdodEhhbmRsZSA9IGRyYWcuYmFyR3JvdXAucXVlcnlTZWxlY3RvcjxTVkdSZWN0RWxlbWVudD4oJy5zZGMtZ2FudHQtYmFyLWhhbmRsZS0tcmlnaHQnKTtcbiAgICBpZiAobGVmdEhhbmRsZSkge1xuICAgICAgbGVmdEhhbmRsZS5zZXRBdHRyaWJ1dGUoJ3gnLCBTdHJpbmcobmV3WCkpO1xuICAgIH1cblxuICAgIGlmIChyaWdodEhhbmRsZSkge1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1ggKyBvcmlnaW5hbFdpZHRoIC0gSEFORExFX1dJRFRIKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgMikpO1xuICAgIH1cblxuICAgIGNvbnN0IGxhYmVsID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1RleHRFbGVtZW50PignLnNkYy1nYW50dC1iYXItbGFiZWwnKTtcbiAgICBpZiAobGFiZWwpIHtcbiAgICAgIGxhYmVsLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgVEFTS19MQUJFTF9IT1JJWk9OVEFMX1BBRERJTkcpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZURyYWdSZXNpemVSaWdodChkcmFnOiBEcmFnU3RhdGUsIG9yaWdpbmFsWDogbnVtYmVyLCBvcmlnaW5hbFdpZHRoOiBudW1iZXIsIGJhcjogU1ZHUmVjdEVsZW1lbnQsIGR4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWF4KGRyYWcuY29sVyAvIERSQUdfTUlOX0hBTkRMRV9GQUNUT1IsIG9yaWdpbmFsV2lkdGggKyBkeCk7XG4gICAgYmFyLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcobmV3V2lkdGgpKTtcblxuICAgIGNvbnN0IHJpZ2h0SGFuZGxlID0gZHJhZy5iYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PignLnNkYy1nYW50dC1iYXItaGFuZGxlLS1yaWdodCcpO1xuICAgIGlmIChyaWdodEhhbmRsZSkge1xuICAgICAgcmlnaHRIYW5kbGUuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG9yaWdpbmFsWCArIG5ld1dpZHRoIC0gSEFORExFX1dJRFRIKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBTdHJpbmcoTWF0aC5tYXgobmV3V2lkdGggLSA0LCAwKSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlRHJhZ1Jlc2l6ZUxlZnQoZHJhZzogRHJhZ1N0YXRlLCBvcmlnaW5hbFg6IG51bWJlciwgb3JpZ2luYWxXaWR0aDogbnVtYmVyLCBiYXI6IFNWR1JlY3RFbGVtZW50LCBkeDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV3V2lkdGggPSBNYXRoLm1heChkcmFnLmNvbFcgLyBEUkFHX01JTl9IQU5ETEVfRkFDVE9SLCBvcmlnaW5hbFdpZHRoIC0gZHgpO1xuICAgIGNvbnN0IG5ld1ggPSBvcmlnaW5hbFggKyAob3JpZ2luYWxXaWR0aCAtIG5ld1dpZHRoKTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1gpKTtcbiAgICBiYXIuc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhuZXdXaWR0aCkpO1xuXG4gICAgY29uc3QgbGVmdEhhbmRsZSA9IGRyYWcuYmFyR3JvdXAucXVlcnlTZWxlY3RvcjxTVkdSZWN0RWxlbWVudD4oJy5zZGMtZ2FudHQtYmFyLWhhbmRsZS0tbGVmdCcpO1xuICAgIGlmIChsZWZ0SGFuZGxlKSB7XG4gICAgICBsZWZ0SGFuZGxlLnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYKSk7XG4gICAgfVxuXG4gICAgY29uc3QgY2xpcFJlY3QgPSB0aGlzLnN2Zy5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihgI2NsaXAtJHtkcmFnLnRhc2suaWR9IHJlY3RgKTtcbiAgICBpZiAoY2xpcFJlY3QpIHtcbiAgICAgIGNsaXBSZWN0LnNldEF0dHJpYnV0ZSgneCcsIFN0cmluZyhuZXdYICsgMikpO1xuICAgICAgY2xpcFJlY3Quc2V0QXR0cmlidXRlKCd3aWR0aCcsIFN0cmluZyhNYXRoLm1heChuZXdXaWR0aCAtIDQsIDApKSk7XG4gICAgfVxuXG4gICAgY29uc3QgbGFiZWwgPSBkcmFnLmJhckdyb3VwLnF1ZXJ5U2VsZWN0b3I8U1ZHVGV4dEVsZW1lbnQ+KCcuc2RjLWdhbnR0LWJhci1sYWJlbCcpO1xuICAgIGlmIChsYWJlbCkge1xuICAgICAgbGFiZWwuc2V0QXR0cmlidXRlKCd4JywgU3RyaW5nKG5ld1ggKyBUQVNLX0xBQkVMX0hPUklaT05UQUxfUEFERElORykpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgb25Nb3VzZVVwKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgdGFzaywgYmFyR3JvdXAsIHJhbmdlU3RhcnQsIGNvbFcsIG1vZGUgfSA9IHRoaXMuZHJhZztcbiAgICBjb25zdCBiYXIgPSBiYXJHcm91cC5xdWVyeVNlbGVjdG9yPFNWR1JlY3RFbGVtZW50PihCQVJfU0VMRUNUT1IpO1xuICAgIGlmICghYmFyKSB7XG4gICAgICB0aGlzLmRyYWcgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpbmFsWCA9IHBhcnNlRmxvYXQoYmFyLmdldEF0dHJpYnV0ZSgneCcpID8/ICcwJyk7XG4gICAgY29uc3QgZmluYWxXID0gcGFyc2VGbG9hdChiYXIuZ2V0QXR0cmlidXRlKCd3aWR0aCcpID8/ICcwJyk7XG4gICAgY29uc3QgZHggPSBlLmNsaWVudFggLSB0aGlzLmRyYWcuc3RhcnRYO1xuXG4gICAgdGhpcy5lbWl0RGF0ZUNoYW5nZUlmU2lnbmlmaWNhbnRNb3ZlbWVudCh0YXNrLCBmaW5hbFgsIGZpbmFsVywgZHgsIHJhbmdlU3RhcnQsIGNvbFcsIG1vZGUpO1xuXG4gICAgLy8gUmVzZXQgdmlzdWFsIHN0YXRlc1xuICAgIGJhci5yZW1vdmVBdHRyaWJ1dGUoJ3N0cm9rZScpO1xuICAgIGJhci5yZW1vdmVBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcpO1xuICAgIGJhckdyb3VwLnN0eWxlLmN1cnNvciA9ICdncmFiJztcblxuICAgIHRoaXMuZHJhZyA9IG51bGw7XG4gIH1cblxuICBwcml2YXRlIGVtaXREYXRlQ2hhbmdlSWZTaWduaWZpY2FudE1vdmVtZW50KFxuICAgIHRhc2s6IEdhbnR0VGFzayxcbiAgICBmaW5hbFg6IG51bWJlcixcbiAgICBmaW5hbFc6IG51bWJlcixcbiAgICBkeDogbnVtYmVyLFxuICAgIHJhbmdlU3RhcnQ6IERhdGUsXG4gICAgY29sVzogbnVtYmVyLFxuICAgIG1vZGU6IERyYWdNb2RlXG4gICk6IHZvaWQge1xuICAgIC8vIE9ubHkgZW1pdCBpZiB0aGVyZSB3YXMgbWVhbmluZ2Z1bCBtb3ZlbWVudFxuICAgIGlmIChNYXRoLmFicyhkeCkgPiAyICYmIHRoaXMub3B0aW9ucy5vbkRhdGVDaGFuZ2UpIHtcbiAgICAgIGNvbnN0IHsgbmV3U3RhcnQsIG5ld0VuZCB9ID0gdGhpcy5jYWxjdWxhdGVOZXdEYXRlcyh0YXNrLCBmaW5hbFgsIGZpbmFsVywgcmFuZ2VTdGFydCwgY29sVywgbW9kZSk7XG4gICAgICB0aGlzLm9wdGlvbnMub25EYXRlQ2hhbmdlKHRhc2ssIG5ld1N0YXJ0LCBuZXdFbmQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2FsY3VsYXRlTmV3RGF0ZXMoXG4gICAgdGFzazogR2FudHRUYXNrLFxuICAgIGZpbmFsWDogbnVtYmVyLFxuICAgIGZpbmFsVzogbnVtYmVyLFxuICAgIHJhbmdlU3RhcnQ6IERhdGUsXG4gICAgY29sVzogbnVtYmVyLFxuICAgIG1vZGU6IERyYWdNb2RlXG4gICk6IHsgbmV3U3RhcnQ6IERhdGU7IG5ld0VuZDogRGF0ZSB9IHtcbiAgICBjb25zdCBkdXJhdGlvbk1zID0gdGFzay5lbmQuZ2V0VGltZSgpIC0gdGFzay5zdGFydC5nZXRUaW1lKCk7XG4gICAgbGV0IG5ld1N0YXJ0OiBEYXRlO1xuICAgIGxldCBuZXdFbmQ6IERhdGU7XG5cbiAgICBpZiAobW9kZSA9PT0gRHJhZ01vZGUuTW92ZSkge1xuICAgICAgbmV3U3RhcnQgPSB0aGlzLnhUb0RhdGUoZmluYWxYLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICAgIG5ld0VuZCA9IG5ldyBEYXRlKG5ld1N0YXJ0LmdldFRpbWUoKSArIGR1cmF0aW9uTXMpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PT0gRHJhZ01vZGUuUmVzaXplUmlnaHQpIHtcbiAgICAgIG5ld1N0YXJ0ID0gdGFzay5zdGFydDtcbiAgICAgIG5ld0VuZCA9IHRoaXMueFRvRGF0ZShmaW5hbFggKyBmaW5hbFcsIHJhbmdlU3RhcnQsIGNvbFcpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyByZXNpemUtbGVmdFxuICAgICAgbmV3U3RhcnQgPSB0aGlzLnhUb0RhdGUoZmluYWxYLCByYW5nZVN0YXJ0LCBjb2xXKTtcbiAgICAgIG5ld0VuZCA9IHRhc2suZW5kO1xuICAgIH1cblxuICAgIHJldHVybiB7IG5ld1N0YXJ0LCBuZXdFbmQgfTtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQb3B1cFxuICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwcml2YXRlIHNob3dQb3B1cCh0YXNrOiBHYW50dFRhc2ssIGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5yZW1vdmVQb3B1cCgpO1xuXG4gICAgY29uc3QgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgZGl2LmNsYXNzTmFtZSA9ICdzZGMtZ2FudHQtcG9wdXAnO1xuICAgIGRpdi5zdHlsZS5jc3NUZXh0ID0gYFxuICAgICAgcG9zaXRpb246IGZpeGVkO1xuICAgICAgei1pbmRleDogOTk5OTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmY7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjY2NjO1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgcGFkZGluZzogOHB4IDEycHg7XG4gICAgICBib3gtc2hhZG93OiAwIDJweCA4cHggcmdiYSgwLDAsMCwuMik7XG4gICAgICBmb250LXNpemU6IDEzcHg7XG4gICAgICBwb2ludGVyLWV2ZW50czogbm9uZTtcbiAgICAgIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gICAgYDtcblxuICAgIGNvbnN0IGZvcm1hdE9wdHM6IEludGwuRGF0ZVRpbWVGb3JtYXRPcHRpb25zID0geyBkYXk6ICcyLWRpZ2l0JywgbW9udGg6ICdzaG9ydCcsIHllYXI6ICdudW1lcmljJyB9O1xuICAgIGNvbnN0IHN0YXJ0ID0gdGFzay5zdGFydC50b0xvY2FsZURhdGVTdHJpbmcoJ3B0LUJSJywgZm9ybWF0T3B0cyk7XG4gICAgY29uc3QgZW5kID0gdGFzay5lbmQudG9Mb2NhbGVEYXRlU3RyaW5nKCdwdC1CUicsIGZvcm1hdE9wdHMpO1xuXG4gICAgY29uc3QgdGl0bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzdHJvbmcnKTtcbiAgICB0aXRsZS5zdHlsZS5kaXNwbGF5ID0gJ2Jsb2NrJztcbiAgICB0aXRsZS5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnNHB4JztcbiAgICB0aXRsZS50ZXh0Q29udGVudCA9IHRhc2submFtZTtcblxuICAgIGNvbnN0IHN0YXJ0TGFiZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgc3RhcnRMYWJlbC50ZXh0Q29udGVudCA9IGBJbmljaW86ICR7c3RhcnR9YDtcblxuICAgIGNvbnN0IGxpbmVCcmVhayA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2JyJyk7XG5cbiAgICBjb25zdCBlbmRMYWJlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NwYW4nKTtcbiAgICBlbmRMYWJlbC50ZXh0Q29udGVudCA9IGBGaW06ICR7ZW5kfWA7XG5cbiAgICBkaXYucmVwbGFjZUNoaWxkcmVuKHRpdGxlLCBzdGFydExhYmVsLCBsaW5lQnJlYWssIGVuZExhYmVsKTsgLypcbiAgICAgIDxzdHJvbmcgc3R5bGU9XCJkaXNwbGF5OmJsb2NrO21hcmdpbi1ib3R0b206NHB4O1wiPiR7dGFzay5uYW1lfTwvc3Ryb25nPlxuICAgICAgPHNwYW4+SW7DrWNpbzogJHtzdGFydH08L3NwYW4+PGJyPlxuICAgICAgPHNwYW4+RmltOiAke2VuZH08L3NwYW4+XG4gICAgKi9cblxuICAgIGRpdi5zdHlsZS5sZWZ0ID0gYCR7Y2xpZW50WCArIHRoaXMuUEFERElOR31weGA7XG4gICAgZGl2LnN0eWxlLnRvcCA9IGAke2NsaWVudFkgLSAxMH1weGA7XG5cbiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdik7XG4gICAgdGhpcy5wb3B1cCA9IGRpdjtcblxuICAgIC8vIEF1dG8tcmVtb3ZlIGFmdGVyIDMgc1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5yZW1vdmVQb3B1cCgpLCBQT1BVUF9BVVRPX1JFTU9WRV9ERUxBWV9NUyk7XG5cbiAgICAvLyBSZW1vdmUgb24gbmV4dCBjbGljayBhbnl3aGVyZVxuICAgIGNvbnN0IHJlbW92ZU9uQ2xpY2sgPSAoKTogdm9pZCA9PiB7XG4gICAgICB0aGlzLnJlbW92ZVBvcHVwKCk7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHJlbW92ZU9uQ2xpY2ssIHRydWUpO1xuICAgIH07XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCByZW1vdmVPbkNsaWNrLCB0cnVlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUG9wdXAoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucG9wdXA/LnBhcmVudE5vZGUpIHtcbiAgICAgIHRoaXMucG9wdXAucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnBvcHVwKTtcbiAgICB9XG5cbiAgICB0aGlzLnBvcHVwID0gbnVsbDtcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAvLyBQb3NpdGlvbiAvIGRpbWVuc2lvbiBoZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY29tcHV0ZUJhclgodGFza1N0YXJ0OiBEYXRlLCByYW5nZVN0YXJ0OiBEYXRlLCBjb2xXOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLm9wdGlvbnMudmlld01vZGU7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGRpZmZIb3VycyhyYW5nZVN0YXJ0LCB0YXNrU3RhcnQpICogY29sVztcbiAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgIHJldHVybiBkaWZmRGF5cyhyYW5nZVN0YXJ0LCB0YXNrU3RhcnQpICogY29sVztcbiAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICByZXR1cm4gKGRpZmZEYXlzKHJhbmdlU3RhcnQsIHRhc2tTdGFydCkgLyBEQVlTX0lOX1dFRUspICogY29sVztcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBtb250aERpZmYgPVxuICAgICAgICAgICh0YXNrU3RhcnQuZ2V0RnVsbFllYXIoKSAtIHJhbmdlU3RhcnQuZ2V0RnVsbFllYXIoKSkgKiBNT05USFNfSU5fWUVBUiArXG4gICAgICAgICAgKHRhc2tTdGFydC5nZXRNb250aCgpIC0gcmFuZ2VTdGFydC5nZXRNb250aCgpKTtcbiAgICAgICAgY29uc3QgZGF5RnJhY3Rpb24gPSAodGFza1N0YXJ0LmdldERhdGUoKSAtIDEpIC8gbmV3IERhdGUodGFza1N0YXJ0LmdldEZ1bGxZZWFyKCksIHRhc2tTdGFydC5nZXRNb250aCgpICsgMSwgMCkuZ2V0RGF0ZSgpO1xuICAgICAgICByZXR1cm4gKG1vbnRoRGlmZiArIGRheUZyYWN0aW9uKSAqIGNvbFc7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGlmZkRheXMocmFuZ2VTdGFydCwgdGFza1N0YXJ0KSAqIGNvbFc7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlQmFyV2lkdGgodGFzazogR2FudHRUYXNrLCBjb2xXOiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLm9wdGlvbnMudmlld01vZGU7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGRpZmZIb3Vycyh0YXNrLnN0YXJ0LCB0YXNrLmVuZCkgKiBjb2xXO1xuICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgcmV0dXJuIGRpZmZEYXlzKHRhc2suc3RhcnQsIHRhc2suZW5kKSAqIGNvbFc7XG4gICAgICBjYXNlICd3ZWVrJzpcbiAgICAgICAgcmV0dXJuIChkaWZmRGF5cyh0YXNrLnN0YXJ0LCB0YXNrLmVuZCkgLyBEQVlTX0lOX1dFRUspICogY29sVztcbiAgICAgIGNhc2UgJ21vbnRoJzoge1xuICAgICAgICBjb25zdCBkYXlzSW5SYW5nZSA9IGRpZmZEYXlzKHRhc2suc3RhcnQsIHRhc2suZW5kKTtcbiAgICAgICAgY29uc3QgZGF5c0luTW9udGggPSBuZXcgRGF0ZSh0YXNrLnN0YXJ0LmdldEZ1bGxZZWFyKCksIHRhc2suc3RhcnQuZ2V0TW9udGgoKSArIDEsIDApLmdldERhdGUoKTtcbiAgICAgICAgcmV0dXJuIChkYXlzSW5SYW5nZSAvIGRheXNJbk1vbnRoKSAqIGNvbFc7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGlmZkRheXModGFzay5zdGFydCwgdGFzay5lbmQpICogY29sVztcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHhUb0RhdGUoeDogbnVtYmVyLCByYW5nZVN0YXJ0OiBEYXRlLCBjb2xXOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCBtb2RlID0gdGhpcy5vcHRpb25zLnZpZXdNb2RlO1xuICAgIGNvbnN0IHNsb3RzID0geCAvIGNvbFc7XG4gICAgc3dpdGNoIChtb2RlKSB7XG4gICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgcmV0dXJuIGFkZEhvdXJzKHJhbmdlU3RhcnQsIE1hdGgucm91bmQoc2xvdHMpKTtcbiAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgIHJldHVybiBhZGREYXlzKHJhbmdlU3RhcnQsIE1hdGgucm91bmQoc2xvdHMpKTtcbiAgICAgIGNhc2UgJ3dlZWsnOlxuICAgICAgICByZXR1cm4gYWRkRGF5cyhyYW5nZVN0YXJ0LCBNYXRoLnJvdW5kKHNsb3RzICogREFZU19JTl9XRUVLKSk7XG4gICAgICBjYXNlICdtb250aCc6IHtcbiAgICAgICAgY29uc3QgZCA9IG5ldyBEYXRlKHJhbmdlU3RhcnQpO1xuICAgICAgICBkLnNldE1vbnRoKGQuZ2V0TW9udGgoKSArIE1hdGguZmxvb3Ioc2xvdHMpKTtcbiAgICAgICAgcmV0dXJuIGQ7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gYWRkRGF5cyhyYW5nZVN0YXJ0LCBNYXRoLnJvdW5kKHNsb3RzKSk7XG4gICAgfVxuICB9XG5cbiAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFNWRyBoZWxwZXJzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gIHByaXZhdGUgY2xlYXJTdmcoKTogdm9pZCB7XG4gICAgd2hpbGUgKHRoaXMuc3ZnLmZpcnN0Q2hpbGQpIHtcbiAgICAgIHRoaXMuc3ZnLnJlbW92ZUNoaWxkKHRoaXMuc3ZnLmZpcnN0Q2hpbGQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlU3ZnRWxlbWVudDxLIGV4dGVuZHMga2V5b2YgU1ZHRWxlbWVudFRhZ05hbWVNYXA+KHRhZzogSyk6IFNWR0VsZW1lbnRUYWdOYW1lTWFwW0tdIHtcbiAgICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgdGFnKTtcbiAgfVxufVxuIl19
|