tool-dom-ang15 0.0.8 → 0.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -52,9 +52,11 @@ tool-dom-ang15/
52
52
  ├── tool-dom-ang15.component.html # шаблон (панели + лог)
53
53
  ├── tool-dom-ang15.component.scss # стили
54
54
  └── dom/
55
- ├── dom-element.ts # сервис DomElement
56
- ├── dom-class.ts # сервис DomClass
57
- └── dom-style.ts # сервис DomStyle
55
+ ├── dom-tools.ts # сервис DomToolsService
56
+ ├── root
57
+ ├── dom-element.ts # сервис DomElement
58
+ ├── dom-class.ts # сервис DomClass
59
+ └── dom-style.ts # сервис DomStyle
58
60
  ```
59
61
 
60
62
  ---
@@ -95,7 +97,7 @@ tool-dom-ang15/
95
97
  **Инициализация (`ngOnInit`):**
96
98
 
97
99
  ```ts
98
- this.dom = new DomElement(this.document);
100
+ this.elt = new DomElement(this.document);
99
101
  this.cls = new DomClass(this.document);
100
102
  this.style = new DomStyle();
101
103
  ```
@@ -0,0 +1,31 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { DOCUMENT } from '@angular/common';
3
+ import { DomClass } from './source/dom-class';
4
+ import { DomElement } from './source/dom-element';
5
+ import { DomStyle } from './source/dom-style';
6
+ import * as i0 from "@angular/core";
7
+ export function createDomTools(document) {
8
+ return {
9
+ elt: new DomElement(document),
10
+ cls: new DomClass(document),
11
+ style: new DomStyle(),
12
+ };
13
+ }
14
+ export class DomToolsService {
15
+ constructor(document) {
16
+ const t = createDomTools(document);
17
+ this.elt = t.elt;
18
+ this.cls = t.cls;
19
+ this.style = t.style;
20
+ }
21
+ }
22
+ DomToolsService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DomToolsService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
23
+ DomToolsService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DomToolsService, providedIn: 'root' });
24
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DomToolsService, decorators: [{
25
+ type: Injectable,
26
+ args: [{ providedIn: 'root' }]
27
+ }], ctorParameters: function () { return [{ type: Document, decorators: [{
28
+ type: Inject,
29
+ args: [DOCUMENT]
30
+ }] }]; } });
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLXRvb2xzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9vbC1kb20tYW5nMTUvc3JjL2xpYi9kb20vZG9tLXRvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUUxQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQzs7QUFROUMsTUFBTSxVQUFVLGNBQWMsQ0FBQyxRQUFrQjtJQUM3QyxPQUFPO1FBQ0gsR0FBRyxFQUFFLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQztRQUM3QixHQUFHLEVBQUUsSUFBSSxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQzNCLEtBQUssRUFBRSxJQUFJLFFBQVEsRUFBRTtLQUN4QixDQUFDO0FBQ04sQ0FBQztBQUdELE1BQU0sT0FBTyxlQUFlO0lBS3hCLFlBQThCLFFBQWtCO1FBQzVDLE1BQU0sQ0FBQyxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUM7UUFDakIsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN6QixDQUFDOzs2R0FWUSxlQUFlLGtCQUtKLFFBQVE7aUhBTG5CLGVBQWUsY0FESCxNQUFNOzRGQUNsQixlQUFlO2tCQUQzQixVQUFVO21CQUFDLEVBQUMsVUFBVSxFQUFFLE1BQU0sRUFBQzs7MEJBTWYsTUFBTTsyQkFBQyxRQUFRIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJ1xyXG5cclxuaW1wb3J0IHsgRG9tQ2xhc3MgfSBmcm9tICcuL3NvdXJjZS9kb20tY2xhc3MnO1xyXG5pbXBvcnQgeyBEb21FbGVtZW50IH0gZnJvbSAnLi9zb3VyY2UvZG9tLWVsZW1lbnQnO1xyXG5pbXBvcnQgeyBEb21TdHlsZSB9IGZyb20gJy4vc291cmNlL2RvbS1zdHlsZSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIERvbVRvb2xzIHtcclxuICAgIGVsdDogRG9tRWxlbWVudDtcclxuICAgIGNsczogRG9tQ2xhc3M7XHJcbiAgICBzdHlsZTogRG9tU3R5bGU7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVEb21Ub29scyhkb2N1bWVudDogRG9jdW1lbnQpOiBEb21Ub29scyB7XHJcbiAgICByZXR1cm4ge1xyXG4gICAgICAgIGVsdDogbmV3IERvbUVsZW1lbnQoZG9jdW1lbnQpLFxyXG4gICAgICAgIGNsczogbmV3IERvbUNsYXNzKGRvY3VtZW50KSxcclxuICAgICAgICBzdHlsZTogbmV3IERvbVN0eWxlKCksXHJcbiAgICB9O1xyXG59XHJcblxyXG5ASW5qZWN0YWJsZSh7cHJvdmlkZWRJbjogJ3Jvb3QnfSlcclxuZXhwb3J0IGNsYXNzIERvbVRvb2xzU2VydmljZSB7XHJcbiAgICByZWFkb25seSBlbHQ6IERvbUVsZW1lbnQ7XHJcbiAgICByZWFkb25seSBjbHM6IERvbUNsYXNzO1xyXG4gICAgcmVhZG9ubHkgc3R5bGU6IERvbVN0eWxlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKEBJbmplY3QoRE9DVU1FTlQpIGRvY3VtZW50OiBEb2N1bWVudCkge1xyXG4gICAgICAgIGNvbnN0IHQgPSBjcmVhdGVEb21Ub29scyhkb2N1bWVudCk7XHJcbiAgICAgICAgdGhpcy5lbHQgPSB0LmVsdDtcclxuICAgICAgICB0aGlzLmNscyA9IHQuY2xzO1xyXG4gICAgICAgIHRoaXMuc3R5bGUgPSB0LnN0eWxlO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==
@@ -0,0 +1,198 @@
1
+ import { __decorate, __param } from "tslib";
2
+ import { Inject } from '@angular/core';
3
+ import { DOCUMENT } from "@angular/common";
4
+ import { DomElement } from "./dom-element";
5
+ /**
6
+ * Класс для работы с классами DOM
7
+ */
8
+ let DomClass = class DomClass {
9
+ constructor(document) {
10
+ this.document = document;
11
+ this.elt = new DomElement(this.document);
12
+ }
13
+ //region Управление классами
14
+ /**
15
+ * Проверяет наличие класса у элемента
16
+ *
17
+ * @param {HTMLElement} element - Элемент
18
+ * @param {string} className - Класс
19
+ *
20
+ * @returns {boolean} true, если класс присутствует
21
+ */
22
+ hasClass(element, className) {
23
+ return !!(className && element?.classList.contains(className));
24
+ }
25
+ /**
26
+ * Добавляет класс элементу
27
+ *
28
+ * @param {HTMLElement} element - Элемент
29
+ * @param {string} className - Класс
30
+ *
31
+ * @returns {boolean} true, если класс добавили
32
+ */
33
+ addClass(element, className) {
34
+ if (className && element && 'classList' in element) {
35
+ element.classList.add(className);
36
+ return true;
37
+ }
38
+ return false;
39
+ }
40
+ /**
41
+ * Массовое добавление CSS-классов
42
+ *
43
+ * @param {HTMLElement} element - Элемент
44
+ * @param classNames - Массив названий CSS-классов для добавления
45
+ */
46
+ addClasses(element, classNames) {
47
+ if (!element || !classNames || classNames.length === 0) {
48
+ return;
49
+ }
50
+ classNames.forEach(className => {
51
+ if (className && className.trim() !== '') {
52
+ this.addClass(element, className.trim());
53
+ }
54
+ });
55
+ }
56
+ /**
57
+ * Создает CSS-классы для margin и padding на основе переменных --evo{n}.
58
+ * Классы генерируются для всех направлений (top, right, bottom, left).
59
+ *
60
+ * @param elementRef - Элемент для которого будут создаваться классы.
61
+ * @param {number[]} arrVars - Значения для генерации классов.
62
+ *
63
+ */
64
+ addClassMarginPadding(elementRef, arrVars = []) {
65
+ const root = this.elt.elementGetParent(elementRef.nativeElement);
66
+ if (!root) {
67
+ console.error('Root element not found');
68
+ return;
69
+ }
70
+ const properties = ['m', 'p']; // margin, padding
71
+ const directions = ['t', 'r', 'b', 'l']; // top, right, bottom, left
72
+ let style = this.document.querySelector('style[data-dynamic-style]');
73
+ if (!style) {
74
+ style = this.document.createElement('style');
75
+ style.setAttribute('data-dynamic-style', '');
76
+ root.appendChild(style);
77
+ }
78
+ let cssContent = '';
79
+ // Добавляем классы для arrVars (если массив не пустой)
80
+ if (arrVars && arrVars.length > 0) {
81
+ arrVars.forEach(value => {
82
+ properties.forEach(prop => {
83
+ directions.forEach(dir => {
84
+ const className = `.evo-${prop}${dir}-${value}`;
85
+ const cssProperty = prop === 'm' ? 'margin' : 'padding';
86
+ const cssDirection = this._getCssDirection(dir);
87
+ cssContent += `${className} { ${cssProperty}-${cssDirection}: var(--evo${value}); }\n`;
88
+ });
89
+ });
90
+ });
91
+ }
92
+ style.textContent = cssContent;
93
+ }
94
+ /**
95
+ * Удаление всех классов созданных в addClassMarginPadding (<style data-dynamic-style="">)
96
+ * @see {@link addClassMarginPadding} - Создает CSS-классы для margin и padding на основе переменных --evo{n}.
97
+ */
98
+ deleteClassMarginPadding() {
99
+ this.document.querySelector('style[data-dynamic-style]')?.remove();
100
+ }
101
+ /**
102
+ * Удаляет класс у элемента
103
+ *
104
+ * @param {HTMLElement} element - Элемент
105
+ * @param {string} className - Класс
106
+ *
107
+ * @returns {boolean} true, если класс был удален
108
+ */
109
+ removeClass(element, className) {
110
+ if (className && element && 'classList' in element) {
111
+ element.classList.remove(className);
112
+ return true;
113
+ }
114
+ return false;
115
+ }
116
+ /**
117
+ * Переключает CSS-класс у корневого элемента
118
+ *
119
+ * @param {HTMLElement} element - Элемент
120
+ * @param className - Название CSS-класса для переключения
121
+ * @param force - Принудительно установить или удалить класс (true - добавить, false - удалить)
122
+ */
123
+ toggleClass(element, className, force) {
124
+ if (!element || !className) {
125
+ return;
126
+ }
127
+ const trimmedClassName = className.trim();
128
+ if (force !== undefined) {
129
+ if (force) {
130
+ this.addClass(element, trimmedClassName);
131
+ }
132
+ else {
133
+ this.removeClass(element, trimmedClassName);
134
+ }
135
+ }
136
+ else {
137
+ // Переключаем на основе текущего состояния
138
+ if (this.hasClass(element, trimmedClassName)) {
139
+ this.removeClass(element, trimmedClassName);
140
+ }
141
+ else {
142
+ this.addClass(element, trimmedClassName);
143
+ }
144
+ }
145
+ }
146
+ /**
147
+ * Возвращает массив всех CSS-классов корневого элемента
148
+ *
149
+ * @param {HTMLElement} element - Элемент
150
+ *
151
+ * @returns Массив названий CSS-классов
152
+ */
153
+ getClasses(element) {
154
+ if (element) {
155
+ // Получаем актуальные классы с элемента
156
+ return Array.from(element.classList);
157
+ }
158
+ return [];
159
+ }
160
+ /**
161
+ * Удаляет все CSS-классы у корневого элемента и очищает кэш
162
+ *
163
+ * @param {HTMLElement} element - Элемент
164
+ */
165
+ clearClasses(element) {
166
+ // Удаляем все классы с элемента
167
+ if (element) {
168
+ element.className = '';
169
+ }
170
+ }
171
+ //endregion
172
+ //region Приватные методы
173
+ /**
174
+ * Преобразует сокращенное направление (t, r, b, l) в полное название CSS-свойства.
175
+ *
176
+ * @param {string} dir - Сокращенное направление (t, r, b, l).
177
+ * @returns {string} Полное название направления (top, right, bottom, left).
178
+ */
179
+ _getCssDirection(dir) {
180
+ switch (dir) {
181
+ case 't':
182
+ return 'top';
183
+ case 'r':
184
+ return 'right';
185
+ case 'b':
186
+ return 'bottom';
187
+ case 'l':
188
+ return 'left';
189
+ default:
190
+ return '';
191
+ }
192
+ }
193
+ };
194
+ DomClass = __decorate([
195
+ __param(0, Inject(DOCUMENT))
196
+ ], DomClass);
197
+ export { DomClass };
198
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLWNsYXNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9vbC1kb20tYW5nMTUvc3JjL2xpYi9kb20vc291cmNlL2RvbS1jbGFzcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFhLE1BQU0sRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUV6Qzs7R0FFRztBQUNJLElBQU0sUUFBUSxHQUFkLE1BQU0sUUFBUTtJQUdqQixZQUM2QixRQUFrQjtRQUFsQixhQUFRLEdBQVIsUUFBUSxDQUFVO1FBRTNDLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCw0QkFBNEI7SUFDNUI7Ozs7Ozs7T0FPRztJQUNILFFBQVEsQ0FBQyxPQUFvQixFQUFFLFNBQWlCO1FBQzVDLE9BQU8sQ0FBQyxDQUFDLENBQUMsU0FBUyxJQUFJLE9BQU8sRUFBRSxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxRQUFRLENBQUMsT0FBMkIsRUFBRSxTQUFpQjtRQUNuRCxJQUFJLFNBQVMsSUFBSSxPQUFPLElBQUksV0FBVyxJQUFJLE9BQU8sRUFBRTtZQUNoRCxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUVqQyxPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsVUFBVSxDQUFDLE9BQTJCLEVBQUUsVUFBb0I7UUFDeEQsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLFVBQVUsSUFB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QUssR0FBRztnQkFDSixPQUFPLEtBQUssQ0FBQztZQUNqQixLQUFLLEdBQUc7Z0JBQ0osT0FBTyxPQUFPLENBQUM7WUFDbkIsS0FBSyxHQUFHO2dCQUNKLE9BQU8sUUFBUSxDQUFDO1lBQ3BCLEtBQUssR0FBRztnQkFDSixPQUFPLE1BQU0sQ0FBQztZQUNsQjtnQkFDSSxPQUFPLEVBQUUsQ0FBQztTQUNqQjtJQUNMLENBQUM7Q0FHSixDQUFBO0FBdE5ZLFFBQVE7SUFJWixXQUFBLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQTtHQUpaLFFBQVEsQ0FzTnBCO1NBdE5ZLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0VsZW1lbnRSZWYsIEluamVjdH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gXCJAYW5ndWxhci9jb21tb25cIjtcclxuaW1wb3J0IHtEb21FbGVtZW50fSBmcm9tIFwiLi9kb20tZWxlbWVudFwiO1xyXG5cclxuLyoqXHJcbiAqINCa0LvQsNGB0YEg0LTQu9GPINGA0LDQsdC+0YLRiyDRgSDQutC70LDRgdGB0LDQvNC4IERPTVxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIERvbUNsYXNzIHtcclxuICAgIHB1YmxpYyBlbHQ6IERvbUVsZW1lbnQ7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgQEluamVjdChET0NVTUVOVCkgcHVibGljIGRvY3VtZW50OiBEb2N1bWVudCxcclxuICAgICkge1xyXG4gICAgICAgIHRoaXMuZWx0ID0gbmV3IERvbUVsZW1lbnQodGhpcy5kb2N1bWVudClcclxuICAgIH1cclxuXHJcbiAgICAvL3JlZ2lvbiDQo9C/0YDQsNCy0LvQtdC90LjQtSDQutC70LDRgdGB0LDQvNC4XHJcbiAgICAvKipcclxuICAgICAqINCf0YDQvtCy0LXRgNGP0LXRgiDQvdCw0LvQuNGH0LjQtSDQutC70LDRgdGB0LAg0YMg0Y3Qu9C10LzQtdC90YLQsFxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgLSDQrdC70LXQvNC10L3RglxyXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZSAtINCa0LvQsNGB0YFcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSwg0LXRgdC70Lgg0LrQu9Cw0YHRgSDQv9GA0LjRgdGD0YLRgdGC0LLRg9C10YJcclxuICAgICAqL1xyXG4gICAgaGFzQ2xhc3MoZWxlbWVudDogSFRNTEVsZW1lbnQsIGNsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuICEhKGNsYXNzTmFtZSAmJiBlbGVtZW50Py5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQlNC+0LHQsNCy0LvRj9C10YIg0LrQu9Cw0YHRgSDRjdC70LXQvNC10L3RgtGDXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCAtINCt0LvQtdC80LXQvdGCXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIC0g0JrQu9Cw0YHRgVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlLCDQtdGB0LvQuCDQutC70LDRgdGBINC00L7QsdCw0LLQuNC70LhcclxuICAgICAqL1xyXG4gICAgYWRkQ2xhc3MoZWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsLCBjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmIChjbGFzc05hbWUgJiYgZWxlbWVudCAmJiAnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQnNCw0YHRgdC+0LLQvtC1INC00L7QsdCw0LLQu9C10L3QuNC1IENTUy3QutC70LDRgdGB0L7QslxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVsZW1lbnQgLSDQrdC70LXQvNC10L3RglxyXG4gICAgICogQHBhcmFtIGNsYXNzTmFtZXMgLSDQnNCw0YHRgdC40LIg0L3QsNC30LLQsNC90LjQuSBDU1Mt0LrQu9Cw0YHRgdC+0LIg0LTQu9GPINC00L7QsdCw0LLQu9C10L3QuNGPXHJcbiAgICAgKi9cclxuICAgIGFkZENsYXNzZXMoZWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsLCBjbGFzc05hbWVzOiBzdHJpbmdbXSk6IHZvaWQge1xyXG4gICAgICAgIGlmICghZWxlbWVudCB8fCAhY2xhc3NOYW1lcyB8fCBjbGFzc05hbWVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjbGFzc05hbWVzLmZvckVhY2goY2xhc3NOYW1lID0+IHtcclxuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSAmJiBjbGFzc05hbWUudHJpbSgpICE9PSAnJykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDbGFzcyhlbGVtZW50LCBjbGFzc05hbWUudHJpbSgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0KHQvtC30LTQsNC10YIgQ1NTLdC60LvQsNGB0YHRiyDQtNC70Y8gbWFyZ2luINC4IHBhZGRpbmcg0L3QsCDQvtGB0L3QvtCy0LUg0L/QtdGA0LXQvNC10L3QvdGL0YUgLS1ldm97bn0uXHJcbiAgICAgKiDQmtC70LDRgdGB0Ysg0LPQtdC90LXRgNC40YDRg9GO0YLRgdGPINC00LvRjyDQstGB0LXRhSDQvdCw0L/RgNCw0LLQu9C10L3QuNC5ICh0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQpLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBlbGVtZW50UmVmIC0g0K3Qu9C10LzQtdC90YIg0LTQu9GPINC60L7RgtC+0YDQvtCz0L4g0LHRg9C00YPRgiDRgdC+0LfQtNCw0LLQsNGC0YzRgdGPINC60LvQsNGB0YHRiy5cclxuICAgICAqIEBwYXJhbSB7bnVtYmVyW119IGFyclZhcnMgLSDQl9C90LDRh9C10L3QuNGPINC00LvRjyDQs9C10L3QtdGA0LDRhtC40Lgg0LrQu9Cw0YHRgdC+0LIuXHJcbiAgICAgKlxyXG4gICAgICovXHJcbiAgICBhZGRDbGFzc01hcmdpblBhZGRpbmcoZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sIGFyclZhcnM6IG51bWJlcltdID0gW10pOiB2b2lkIHtcclxuICAgICAgICBjb25zdCByb290ID0gdGhpcy5lbHQuZWxlbWVudEdldFBhcmVudChlbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAoIXJvb3QpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcignUm9vdCBlbGVtZW50IG5vdCBmb3VuZCcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBwcm9wZXJ0aWVzID0gWydtJywgJ3AnXTsgLy8gbWFyZ2luLCBwYWRkaW5nXHJcbiAgICAgICAgY29uc3QgZGlyZWN0aW9ucyA9IFsndCcsICdyJywgJ2InLCAnbCddOyAvLyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnRcclxuICAgICAgICBsZXQgc3R5bGUgPSB0aGlzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N0eWxlW2RhdGEtZHluYW1pYy1zdHlsZV0nKTtcclxuXHJcbiAgICAgICAgaWYgKCFzdHlsZSkge1xyXG4gICAgICAgICAgICBzdHlsZSA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3R5bGUnKTtcclxuICAgICAgICAgICAgc3R5bGUuc2V0QXR0cmlidXRlKCdkYXRhLWR5bmFtaWMtc3R5bGUnLCAnJyk7XHJcbiAgICAgICAgICAgIHJvb3QuYXBwZW5kQ2hpbGQoc3R5bGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbGV0IGNzc0NvbnRlbnQgPSAnJztcclxuXHJcbiAgICAgICAgLy8g0JTQvtCx0LDQstC70Y/QtdC8INC60LvQsNGB0YHRiyDQtNC70Y8gYXJyVmFycyAo0LXRgdC70Lgg0LzQsNGB0YHQuNCyINC90LUg0L/Rg9GB0YLQvtC5KVxyXG4gICAgICAgIGlmIChhcnJWYXJzICYmIGFyclZhcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBhcnJWYXJzLmZvckVhY2godmFsdWUgPT4ge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5mb3JFYWNoKHByb3AgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGRpcmVjdGlvbnMuZm9yRWFjaChkaXIgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjbGFzc05hbWUgPSBgLmV2by0ke3Byb3B9JHtkaXJ9LSR7dmFsdWV9YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3NzUHJvcGVydHkgPSBwcm9wID09PSAnbScgPyAnbWFyZ2luJyA6ICdwYWRkaW5nJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3NzRGlyZWN0aW9uID0gdGhpcy5fZ2V0Q3NzRGlyZWN0aW9uKGRpcik7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjc3NDb250ZW50ICs9IGAke2NsYXNzTmFtZX0geyAke2Nzc1Byb3BlcnR5fS0ke2Nzc0RpcmVjdGlvbn06IHZhcigtLWV2byR7dmFsdWV9KTsgfVxcbmA7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBzdHlsZS50ZXh0Q29udGVudCA9IGNzc0NvbnRlbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQo9C00LDQu9C10L3QuNC1INCy0YHQtdGFINC60LvQsNGB0YHQvtCyINGB0L7Qt9C00LDQvdC90YvRhSDQsiBhZGRDbGFzc01hcmdpblBhZGRpbmcgKDxzdHlsZSBkYXRhLWR5bmFtaWMtc3R5bGU9XCJcIj4pXHJcbiAgICAgKiAgQHNlZSB7QGxpbmsgYWRkQ2xhc3NNYXJnaW5QYWRkaW5nfSAtINCh0L7Qt9C00LDQtdGCIENTUy3QutC70LDRgdGB0Ysg0LTQu9GPIG1hcmdpbiDQuCBwYWRkaW5nINC90LAg0L7RgdC90L7QstC1INC/0LXRgNC10LzQtdC90L3Ri9GFIC0tZXZve259LlxyXG4gICAgICovXHJcbiAgICBkZWxldGVDbGFzc01hcmdpblBhZGRpbmcoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCdzdHlsZVtkYXRhLWR5bmFtaWMtc3R5bGVdJyk/LnJlbW92ZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0KPQtNCw0LvRj9C10YIg0LrQu9Cw0YHRgSDRgyDRjdC70LXQvNC10L3RgtCwXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCAtINCt0LvQtdC80LXQvdGCXHJcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIC0g0JrQu9Cw0YHRgVxyXG4gICAgICpcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlLCDQtdGB0LvQuCDQutC70LDRgdGBINCx0YvQuyDRg9C00LDQu9C10L1cclxuICAgICAqL1xyXG4gICAgcmVtb3ZlQ2xhc3MoZWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsLCBjbGFzc05hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmIChjbGFzc05hbWUgJiYgZWxlbWVudCAmJiAnY2xhc3NMaXN0JyBpbiBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQn9C10YDQtdC60LvRjtGH0LDQtdGCIENTUy3QutC70LDRgdGBINGDINC60L7RgNC90LXQstC+0LPQviDRjdC70LXQvNC10L3RgtCwXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudCAtINCt0LvQtdC80LXQvdGCXHJcbiAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIC0g0J3QsNC30LLQsNC90LjQtSBDU1Mt0LrQu9Cw0YHRgdCwINC00LvRjyDQv9C10YDQtdC60LvRjtGH0LXQvdC40Y9cclxuICAgICAqIEBwYXJhbSBmb3JjZSAtINCf0YDQuNC90YPQtNC40YLQtdC70YzQvdC+INGD0YHRgtCw0L3QvtCy0LjRgtGMINC40LvQuCDRg9C00LDQu9C40YLRjCDQutC70LDRgdGBICh0cnVlIC0g0LTQvtCx0LDQstC40YLRjCwgZmFsc2UgLSDRg9C00LDQu9C40YLRjClcclxuICAgICAqL1xyXG4gICAgdG9nZ2xlQ2xhc3MoZWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsLCBjbGFzc05hbWU6IHN0cmluZywgZm9yY2U/OiBib29sZWFuKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCFlbGVtZW50IHx8ICFjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdHJpbW1lZENsYXNzTmFtZSA9IGNsYXNzTmFtZS50cmltKCk7XHJcblxyXG4gICAgICAgIGlmIChmb3JjZSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIGlmIChmb3JjZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDbGFzcyhlbGVtZW50LCB0cmltbWVkQ2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2xhc3MoZWxlbWVudCwgdHJpbW1lZENsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyDQn9C10YDQtdC60LvRjtGH0LDQtdC8INC90LAg0L7RgdC90L7QstC1INGC0LXQutGD0YnQtdCz0L4g0YHQvtGB0YLQvtGP0L3QuNGPXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc0NsYXNzKGVsZW1lbnQsIHRyaW1tZWRDbGFzc05hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZUNsYXNzKGVsZW1lbnQsIHRyaW1tZWRDbGFzc05hbWUpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5hZGRDbGFzcyhlbGVtZW50LCB0cmltbWVkQ2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINC80LDRgdGB0LjQsiDQstGB0LXRhSBDU1Mt0LrQu9Cw0YHRgdC+0LIg0LrQvtGA0L3QtdCy0L7Qs9C+INGN0LvQtdC80LXQvdGC0LBcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50IC0g0K3Qu9C10LzQtdC90YJcclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyDQnNCw0YHRgdC40LIg0L3QsNC30LLQsNC90LjQuSBDU1Mt0LrQu9Cw0YHRgdC+0LJcclxuICAgICAqL1xyXG4gICAgZ2V0Q2xhc3NlcyhlbGVtZW50OiBIVE1MRWxlbWVudCB8IG51bGwpOiBzdHJpbmdbXSB7XHJcbiAgICAgICAgaWYgKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgLy8g0J/QvtC70YPRh9Cw0LXQvCDQsNC60YLRg9Cw0LvRjNC90YvQtSDQutC70LDRgdGB0Ysg0YEg0Y3Qu9C10LzQtdC90YLQsFxyXG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuZnJvbShlbGVtZW50LmNsYXNzTGlzdCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQo9C00LDQu9GP0LXRgiDQstGB0LUgQ1NTLdC60LvQsNGB0YHRiyDRgyDQutC+0YDQvdC10LLQvtCz0L4g0Y3Qu9C10LzQtdC90YLQsCDQuCDQvtGH0LjRidCw0LXRgiDQutGN0YhcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50IC0g0K3Qu9C10LzQtdC90YJcclxuICAgICAqL1xyXG4gICAgY2xlYXJDbGFzc2VzKGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCk6IHZvaWQge1xyXG4gICAgICAgIC8vINCj0LTQsNC70Y/QtdC8INCy0YHQtSDQutC70LDRgdGB0Ysg0YEg0Y3Qu9C10LzQtdC90YLQsFxyXG4gICAgICAgIGlmIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vZW5kcmVnaW9uXHJcblxyXG4gICAgLy9yZWdpb24g0J/RgNC40LLQsNGC0L3Ri9C1INC80LXRgtC+0LTRi1xyXG5cclxuICAgIC8qKlxyXG4gICAgICog0J/RgNC10L7QsdGA0LDQt9GD0LXRgiDRgdC+0LrRgNCw0YnQtdC90L3QvtC1INC90LDQv9GA0LDQstC70LXQvdC40LUgKHQsIHIsIGIsIGwpINCyINC/0L7Qu9C90L7QtSDQvdCw0LfQstCw0L3QuNC1IENTUy3RgdCy0L7QudGB0YLQstCwLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkaXIgLSDQodC+0LrRgNCw0YnQtdC90L3QvtC1INC90LDQv9GA0LDQstC70LXQvdC40LUgKHQsIHIsIGIsIGwpLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30g0J/QvtC70L3QvtC1INC90LDQt9Cy0LDQvdC40LUg0L3QsNC/0YDQsNCy0LvQtdC90LjRjyAodG9wLCByaWdodCwgYm90dG9tLCBsZWZ0KS5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfZ2V0Q3NzRGlyZWN0aW9uKGRpcjogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBzd2l0Y2ggKGRpcikge1xyXG4gICAgICAgICAgICBjYXNlICd0JzpcclxuICAgICAgICAgICAgICAgIHJldHVybiAndG9wJztcclxuICAgICAgICAgICAgY2FzZSAncic6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ3JpZ2h0JztcclxuICAgICAgICAgICAgY2FzZSAnYic6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2JvdHRvbSc7XHJcbiAgICAgICAgICAgIGNhc2UgJ2wnOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuICdsZWZ0JztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAgIHJldHVybiAnJztcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy9lbmRyZWdpb25cclxufVxyXG4iXX0=
@@ -0,0 +1,299 @@
1
+ import { __decorate, __param } from "tslib";
2
+ import { DOCUMENT } from '@angular/common';
3
+ import { Inject } from '@angular/core';
4
+ /**
5
+ * Предоставляет методы для манипуляции DOM элементами
6
+ *
7
+ * Класс включает функционал для:
8
+ * - Создания элементов
9
+ * - Добавления и удаления элементов из DOM
10
+ * - Поиска элементов с повторными попытками
11
+ * - Навигации по DOM дереву
12
+ * - Работы с data-атрибутами
13
+ */
14
+ let DomElement = class DomElement {
15
+ constructor(document) {
16
+ this.document = document;
17
+ this._countGetElement = 0;
18
+ }
19
+ /**
20
+ * Создает новый DOM элемент с указанным тегом и CSS классом
21
+ *
22
+ * @param tagName - HTML тег создаваемого элемента (div, span, button и т.д.)
23
+ * @param className - CSS класс для элемента (опционально)
24
+ * @returns Новый DOM элемент
25
+ *
26
+ * @example
27
+ * const div = worker.createElement('div', 'container');
28
+ * const span = worker.createElement('span');
29
+ */
30
+ createElement(tagName, className) {
31
+ const element = this.document.createElement(tagName);
32
+ if (className) {
33
+ element.className = className;
34
+ }
35
+ return element;
36
+ }
37
+ /**
38
+ * Создает и добавляет новый HTML элемент в DOM
39
+ *
40
+ * @param parentElement - Родительский элемент, к которому будет добавлен новый
41
+ * @param newElement - HTML тег создаваемого элемента
42
+ * @param typeAppend - Способ добавления ('appendChild' или 'insertBefore')
43
+ * @param strInnerHTML - Внутреннее HTML содержимое (опционально)
44
+ * @param dataId - Значение для атрибута data-id (опционально)
45
+ * @param eventName - Тип события для добавления слушателя
46
+ * @param fn - Функция-обработчик события (опционально)
47
+ *
48
+ * @example
49
+ * worker.elementCreate(
50
+ * this.document.body,
51
+ * 'button',
52
+ * 'appendChild',
53
+ * 'Click me',
54
+ * 123,
55
+ * 'click',
56
+ * () => console.log('Clicked')
57
+ * );
58
+ */
59
+ elementCreate(parentElement, newElement, typeAppend, strInnerHTML = '', dataId = '', eventName, fn = null) {
60
+ if (!parentElement || !newElement) {
61
+ return;
62
+ }
63
+ const el$ = this.document.createElement(newElement);
64
+ if (dataId !== null) {
65
+ el$.setAttribute('data-id', String(dataId));
66
+ }
67
+ if (strInnerHTML) {
68
+ el$.innerHTML = strInnerHTML;
69
+ }
70
+ this.elementAdd(parentElement, typeAppend, dataId, eventName, fn, el$);
71
+ }
72
+ /**
73
+ * Добавляет существующий HTML элемент в DOM
74
+ *
75
+ * @param parentElement - Родительский элемент
76
+ * @param typeAppend - Способ добавления ('appendChild' или 'insertBefore')
77
+ * @param dataId - Идентификатор для атрибута data-id
78
+ * @param eventName - Тип события для слушателя
79
+ * @param fn - Функция-обработчик события
80
+ * @param el$ - Добавляемый DOM элемент
81
+ *
82
+ * @remarks
83
+ * Если typeAppend равен 'insertBefore', элемент добавляется в начало родителя.
84
+ * В противном случае элемент добавляется в конец.
85
+ */
86
+ elementAdd(parentElement, typeAppend, dataId, eventName, fn, el$) {
87
+ if ('firstChild' in parentElement) {
88
+ if (typeAppend === 'insertBefore') {
89
+ parentElement.insertBefore(el$, parentElement.firstChild);
90
+ }
91
+ else {
92
+ parentElement.appendChild(el$);
93
+ }
94
+ }
95
+ else {
96
+ parentElement.appendChild(el$);
97
+ }
98
+ if (fn) {
99
+ el$.addEventListener(eventName, event => {
100
+ fn.call(null, event, null, el$, dataId);
101
+ });
102
+ }
103
+ }
104
+ /**
105
+ * Удаляет HTML элемент из DOM
106
+ *
107
+ * @param parentElement - Родительский элемент, содержащий удаляемый элемент
108
+ * @param el$ - Удаляемый DOM элемент
109
+ *
110
+ * @remarks
111
+ * Метод безопасно завершается, если parentElement или el$ отсутствуют
112
+ */
113
+ elementRemove(parentElement, el$) {
114
+ if (parentElement && el$) {
115
+ parentElement.removeChild(el$);
116
+ }
117
+ }
118
+ /**
119
+ * Асинхронно получает HTML элемент с повторными попытками
120
+ *
121
+ * @param identifier - Селектор для поиска элемента
122
+ * @param selector - Метод поиска ('querySelector' или 'querySelectorAll')
123
+ * @param node - DOM узел для поиска (по умолчанию this.document)
124
+ * @param time - Задержка между попытками в мс (по умолчанию 300)
125
+ * @param max - Максимальное количество попыток (по умолчанию 10)
126
+ * @returns Промис с найденным DOM элементом
127
+ *
128
+ * @remarks
129
+ * Метод полезен для ожидания появления динамически создаваемых элементов
130
+ */
131
+ async elementGet(identifier, selector = 'querySelector', node = this.document, time = 300, max = 10) {
132
+ let result = await this._getElementResult(identifier, selector, node, time);
133
+ if ((!result || (result instanceof NodeList && result.length < 1)) && this._countGetElement < max) {
134
+ this._countGetElement++;
135
+ result = await this.elementGet(identifier, selector, node, time, max);
136
+ }
137
+ return result;
138
+ }
139
+ /**
140
+ * Находит элементы по data-атрибуту или его значению
141
+ *
142
+ * @param elementToSelect - Название data-атрибута (например, 'data-id')
143
+ * @param dataValue - Значение атрибута для фильтрации (опционально)
144
+ * @returns Массив найденных элементов
145
+ * @throws {Error} Если elementToSelect не указан
146
+ *
147
+ * @example
148
+ * // Найти все элементы с data-id
149
+ * const items = worker.getElementByDataAttribute('data-id');
150
+ *
151
+ * // Найти элемент с конкретным значением
152
+ * const item = worker.getElementByDataAttribute('data-id', '123');
153
+ */
154
+ getElementByDataAttribute(elementToSelect, dataValue = null) {
155
+ if (!elementToSelect) {
156
+ throw new Error('elementToSelect is required for getElementByDataAttribute');
157
+ }
158
+ const selector = dataValue ? `[${elementToSelect}='${dataValue}']` : `[${elementToSelect}]`;
159
+ const elements = this.document.querySelectorAll(selector);
160
+ return Array.from(elements);
161
+ }
162
+ /**
163
+ * Внутренний метод для получения элемента с задержкой
164
+ *
165
+ * @param identifier - Селектор элемента
166
+ * @param selector - Метод поиска
167
+ * @param node - Корневой узел
168
+ * @param time - Время задержки в мс
169
+ * @returns Промис с результатом поиска
170
+ * @private
171
+ */
172
+ async _getElementResult(identifier, selector, node, time) {
173
+ return this._setDelay(time)
174
+ .then(_ => {
175
+ if (!node) {
176
+ return null;
177
+ }
178
+ // Используем type assertion для вызова метода
179
+ const result = node[selector](identifier);
180
+ return result || null;
181
+ })
182
+ .catch(error => console.log('Ошибка в _getElementResult', error));
183
+ }
184
+ /**
185
+ * Создает Promise с задержкой
186
+ *
187
+ * @param ms - Время задержки в миллисекундах
188
+ * @returns Promise, который разрешается через указанное время
189
+ * @private
190
+ */
191
+ _setDelay(ms) {
192
+ return new Promise(resolve => setTimeout(resolve, ms));
193
+ }
194
+ /**
195
+ * Возвращает размеры элемента и его положение относительно viewport
196
+ *
197
+ * @param element - Целевой DOM элемент
198
+ * @returns DOMRect объект с координатами (top, left, right, bottom) и размерами (width, height)
199
+ * @throws {Error} Если element не указан
200
+ *
201
+ * @example
202
+ * const rect = worker.getCoordinates(buttonElement);
203
+ * console.log(rect.top, rect.left, rect.width);
204
+ */
205
+ getCoordinates(element) {
206
+ if (!element) {
207
+ throw new Error('Element is required for getCoordinates');
208
+ }
209
+ return element.getBoundingClientRect();
210
+ }
211
+ /**
212
+ * Возвращает родительский элемент указанного DOM узла
213
+ *
214
+ * @param el - DOM элемент или NodeList
215
+ * @returns Родительский элемент или null, если родителя нет
216
+ */
217
+ elementGetParent(el) {
218
+ if (el && 'parentNode' in el) {
219
+ return el.parentNode;
220
+ }
221
+ return null;
222
+ }
223
+ /**
224
+ * Возвращает все соседние элементы (включая сам элемент)
225
+ *
226
+ * @param el - Исходный DOM элемент
227
+ * @returns Массив всех элементов в текущей ветке DOM дерева
228
+ *
229
+ * @remarks
230
+ * Метод собирает все элементы на одном уровне вложенности
231
+ */
232
+ elementsGetSiblingAll(el) {
233
+ if (el && 'parentNode' in el) {
234
+ const parent = el.parentNode;
235
+ const firstElement = parent.firstChild;
236
+ return this.elementGetSiblingNext(firstElement);
237
+ }
238
+ return [];
239
+ }
240
+ /**
241
+ * Возвращает все следующие соседние элементы (nextElementSibling)
242
+ *
243
+ * @param el - Исходный DOM элемент
244
+ * @returns Массив элементов, начиная с указанного и включая все следующие
245
+ *
246
+ * @example
247
+ * const nextElements = worker.elementGetSiblingNext(currentElement);
248
+ * // Возвращает [currentElement, nextElement, nextNextElement, ...]
249
+ */
250
+ elementGetSiblingNext(el) {
251
+ const result = [];
252
+ while (el) {
253
+ if ('nextElementSibling' in el) {
254
+ result.push(el);
255
+ el = el.nextElementSibling;
256
+ }
257
+ else {
258
+ break;
259
+ }
260
+ }
261
+ return result;
262
+ }
263
+ /**
264
+ * Возвращает все предыдущие соседние элементы (previousSibling)
265
+ *
266
+ * @param el - Исходный DOM элемент
267
+ * @returns Массив предыдущих элементов
268
+ *
269
+ * @remarks
270
+ * Возвращает все элементы, включая указанный, в обратном порядке
271
+ */
272
+ elementGetSiblingPrevious(el) {
273
+ const result = [];
274
+ let current = el;
275
+ while (current) {
276
+ result.push(current);
277
+ current = current.previousSibling;
278
+ }
279
+ return result;
280
+ }
281
+ /**
282
+ * Возвращает все прямые дочерние элементы указанного родителя
283
+ *
284
+ * @param el - Родительский DOM элемент
285
+ * @returns Массив дочерних элементов
286
+ *
287
+ * @example
288
+ * const children = worker.elementGetChildren(parentElement);
289
+ * children.forEach(child => console.log(child.tagName));
290
+ */
291
+ elementGetChildren(el) {
292
+ return Array.from(el.children);
293
+ }
294
+ };
295
+ DomElement = __decorate([
296
+ __param(0, Inject(DOCUMENT))
297
+ ], DomElement);
298
+ export { DomElement };
299
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tLWVsZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy90b29sLWRvbS1hbmcxNS9zcmMvbGliL2RvbS9zb3VyY2UvZG9tLWVsZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBS3JDOzs7Ozs7Ozs7R0FTRztBQUNJLElBQU0sVUFBVSxHQUFoQixNQUFNLFVBQVU7SUFJbkIsWUFBcUMsUUFBa0I7UUFBbEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUYvQyxxQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFHN0IsQ0FBQztJQUVEOzs7Ozs7Ozs7O09BVUc7SUFDSCxhQUFhLENBQUMsT0FBZSxFQUFFLFNBQWtCO1FBQzdDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELElBQUksU0FBUyxFQUFFO1lBQ1gsT0FBTyxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7U0FDakM7UUFDRCxPQUFPLE9BQU8sQ0FBQztJQUNuQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNILGFBQWEsQ0FDVCxhQUEwQixFQUMxQixVQUFrQixFQUNsQixVQUF1QixFQUN2QixlQUF1QixFQUFFLEVBQ3pCLFNBQTBCLEVBQUUsRUFDNUIsU0FBcUIsRUFDckIsS0FBc0QsSUFBSTtRQUUxRCxJQUFJLENBQUMsYUFBYSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQy9CLE9BQU87U0FDVjtRQUVELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXBELElBQUksTUFBTSxLQUFLLElBQUksRUFBRTtZQUNqQixHQUFHLENBQUMs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bnQiOlsiaW1wb3J0IHtET0NVTUVOVH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtJbmplY3R9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0IHtUQWxsRXZlbnRzLCBUU2VsZWN0b3IsIFRUeXBlQXBwZW5kfSBmcm9tICcuL2RvbS5pbnRlcmZhY2UnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiDQn9GA0LXQtNC+0YHRgtCw0LLQu9GP0LXRgiDQvNC10YLQvtC00Ysg0LTQu9GPINC80LDQvdC40L/Rg9C70Y/RhtC40LggRE9NINGN0LvQtdC80LXQvdGC0LDQvNC4XHJcbiAqXHJcbiAqINCa0LvQsNGB0YEg0LLQutC70Y7Rh9Cw0LXRgiDRhNGD0L3QutGG0LjQvtC90LDQuyDQtNC70Y86XHJcbiAqIC0g0KHQvtC30LTQsNC90LjRjyDRjdC70LXQvNC10L3RgtC+0LJcclxuICogLSDQlNC+0LHQsNCy0LvQtdC90LjRjyDQuCDRg9C00LDQu9C10L3QuNGPINGN0LvQtdC80LXQvdGC0L7QsiDQuNC3IERPTVxyXG4gKiAtINCf0L7QuNGB0LrQsCDRjdC70LXQvNC10L3RgtC+0LIg0YEg0L/QvtCy0YLQvtGA0L3Ri9C80Lgg0L/QvtC/0YvRgtC60LDQvNC4XHJcbiAqIC0g0J3QsNCy0LjQs9Cw0YbQuNC4INC/0L4gRE9NINC00LXRgNC10LLRg1xyXG4gKiAtINCg0LDQsdC+0YLRiyDRgSBkYXRhLdCw0YLRgNC40LHRg9GC0LDQvNC4XHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgRG9tRWxlbWVudCB7XHJcblxyXG4gICAgcHJpdmF0ZSBfY291bnRHZXRFbGVtZW50ID0gMDtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihASW5qZWN0KERPQ1VNRU5UKSBwdWJsaWMgZG9jdW1lbnQ6IERvY3VtZW50KSB7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQodC+0LfQtNCw0LXRgiDQvdC+0LLRi9C5IERPTSDRjdC70LXQvNC10L3RgiDRgSDRg9C60LDQt9Cw0L3QvdGL0Lwg0YLQtdCz0L7QvCDQuCBDU1Mg0LrQu9Cw0YHRgdC+0LxcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gdGFnTmFtZSAtIEhUTUwg0YLQtdCzINGB0L7Qt9C00LDQstCw0LXQvNC+0LPQviDRjdC70LXQvNC10L3RgtCwIChkaXYsIHNwYW4sIGJ1dHRvbiDQuCDRgi7QtC4pXHJcbiAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIC0gQ1NTINC60LvQsNGB0YEg0LTQu9GPINGN0LvQtdC80LXQvdGC0LAgKNC+0L/RhtC40L7QvdCw0LvRjNC90L4pXHJcbiAgICAgKiBAcmV0dXJucyDQndC+0LLRi9C5IERPTSDRjdC70LXQvNC10L3RglxyXG4gICAgICpcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiBjb25zdCBkaXYgPSB3b3JrZXIuY3JlYXRlRWxlbWVudCgnZGl2JywgJ2NvbnRhaW5lcicpO1xyXG4gICAgICogY29uc3Qgc3BhbiA9IHdvcmtlci5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XHJcbiAgICAgKi9cclxuICAgIGNyZWF0ZUVsZW1lbnQodGFnTmFtZTogc3RyaW5nLCBjbGFzc05hbWU/OiBzdHJpbmcpOiBIVE1MRWxlbWVudCB7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcclxuICAgICAgICBpZiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZWxlbWVudDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqINCh0L7Qt9C00LDQtdGCINC4INC00L7QsdCw0LLQu9GP0LXRgiDQvdC+0LLRi9C5IEhUTUwg0Y3Qu9C10LzQtdC90YIg0LIgRE9NXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHBhcmVudEVsZW1lbnQgLSDQoNC+0LTQuNGC0LXQu9GM0YHQutC40Lkg0Y3Qu9C10LzQtdC90YIsINC6INC60L7RgtC+0YDQvtC80YMg0LHRg9C00LXRgiDQtNC+0LHQsNCy0LvQtdC9INC90L7QstGL0LlcclxuICAgICAqIEBwYXJhbSBuZXdFbGVtZW50IC0gSFRNTCDRgtC10LMg0YHQvtC30LTQsNCy0LDQtdC80L7Qs9C+INGN0LvQtdC80LXQvdGC0LBcclxuICAgICAqIEBwYXJhbSB0eXBlQXBwZW5kIC0g0KHQv9C+0YHQvtCxINC00L7QsdCw0LLQu9C10L3QuNGPICgnYXBwZW5kQ2hpbGQnINC40LvQuCAnaW5zZXJ0QmVmb3JlJylcclxuICAgICAqIEBwYXJhbSBzdHJJbm5lckhUTUwgLSDQktC90YPRgtGA0LXQvdC90LXQtSBIVE1MINGB0L7QtNC10YDQttC40LzQvtC1ICjQvtC/0YbQuNC+0L3QsNC70YzQvdC+KVxyXG4gICAgICogQHBhcmFtIGRhdGFJZCAtINCX0L3QsNGH0LXQvdC40LUg0LTQu9GPINCw0YLRgNC40LHRg9GC0LAgZGF0YS1pZCAo0L7Qv9GG0LjQvtC90LDQu9GM0L3QvilcclxuICAgICAqIEBwYXJhbSBldmVudE5hbWUgLSDQotC40L8g0YHQvtCx0YvRgtC40Y8g0LTQu9GPINC00L7QsdCw0LLQu9C10L3QuNGPINGB0LvRg9GI0LDRgtC10LvRj1xyXG4gICAgICogQHBhcmFtIGZuIC0g0KTRg9C90LrRhtC40Y8t0L7QsdGA0LDQsdC+0YLRh9C40Log0YHQvtCx0YvRgtC40Y8gKNC+0L/RhtC40L7QvdCw0LvRjNC90L4pXHJcbiAgICAgKlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHdvcmtlci5lbGVtZW50Q3JlYXRlKFxyXG4gICAgICogICB0aGlzLmRvY3VtZW50LmJvZHksXHJcbiAgICAgKiAgICdidXR0b24nLFxyXG4gICAgICogICAnYXBwZW5kQ2hpbGQnLFxyXG4gICAgICogICAnQ2xpY2sgbWUnLFxyXG4gICAgICogICAxMjMsXHJcbiAgICAgKiAgICdjbGljaycsXHJcbiAgICAgKiAgICgpID0+IGNvbnNvbGUubG9nKCdDbGlja2VkJylcclxuICAgICAqICk7XHJcbiAgICAgKi9cclxuICAgIGVsZW1lbnRDcmVhdGUoXHJcbiAgICAgICAgcGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQsXHJcbiAgICAgICAgbmV3RWxlbWVudDogc3RyaW5nLFxyXG4gICAgICAgIHR5cGVBcHBlbmQ6IFRUeXBlQXBwZW5kLFxyXG4gICAgICAgIHN0cklubmVySFRNTDogc3RyaW5nID0gJycsXHJcbiAgICAgICAgZGF0YUlkOiBudW1iZXIgfCBzdHJpbmcgPSAnJyxcclxuICAgICAgICBldmVudE5hbWU6IFRBbGxFdmVudHMsXHJcbiAgICAgICAgZm46ICgoZXZlbnQ6IEV2ZW50LCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkgfCBudWxsID0gbnVsbFxyXG4gICAgKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCFwYXJlbnRFbGVtZW50IHx8ICFuZXdFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGVsJCA9IHRoaXMuZG9jdW1lbnQuY3JlYXRlRWxlbWVudChuZXdFbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKGRhdGFJZCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBlbCQuc2V0QXR0cmlidXRlKCdkYXRhLWlkJywgU3RyaW5nKGRhdGFJZCkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHN0cklubmVySFRNTCkge1xyXG4gICAgICAgICAgICBlbCQuaW5uZXJIVE1MID0gc3RySW5uZXJIVE1MO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5lbGVtZW50QWRkKHBhcmVudEVsZW1lbnQsIHR5cGVBcHBlbmQsIGRhdGFJZCwgZXZlbnROYW1lLCBmbiwgZWwkKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqINCU0L7QsdCw0LLQu9GP0LXRgiDRgdGD0YnQtdGB0YLQstGD0Y7RidC40LkgSFRNTCDRjdC70LXQvNC10L3RgiDQsiBET01cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gcGFyZW50RWxlbWVudCAtINCg0L7QtNC40YLQtdC70YzRgdC60LjQuSDRjdC70LXQvNC10L3RglxyXG4gICAgICogQHBhcmFtIHR5cGVBcHBlbmQgLSDQodC/0L7RgdC+0LEg0LTQvtCx0LDQstC70LXQvdC40Y8gKCdhcHBlbmRDaGlsZCcg0LjQu9C4ICdpbnNlcnRCZWZvcmUnKVxyXG4gICAgICogQHBhcmFtIGRhdGFJZCAtINCY0LTQtdC90YLQuNGE0LjQutCw0YLQvtGAINC00LvRjyDQsNGC0YDQuNCx0YPRgtCwIGRhdGEtaWRcclxuICAgICAqIEBwYXJhbSBldmVudE5hbWUgLSDQotC40L8g0YHQvtCx0YvRgtC40Y8g0LTQu9GPINGB0LvRg9GI0LDRgtC10LvRj1xyXG4gICAgICogQHBhcmFtIGZuIC0g0KTRg9C90LrRhtC40Y8t0L7QsdGA0LDQsdC+0YLRh9C40Log0YHQvtCx0YvRgtC40Y9cclxuICAgICAqIEBwYXJhbSBlbCQgLSDQlNC+0LHQsNCy0LvRj9C10LzRi9C5IERPTSDRjdC70LXQvNC10L3RglxyXG4gICAgICpcclxuICAgICAqIEByZW1hcmtzXHJcbiAgICAgKiDQldGB0LvQuCB0eXBlQXBwZW5kINGA0LDQstC10L0gJ2luc2VydEJlZm9yZScsINGN0LvQtdC80LXQvdGCINC00L7QsdCw0LLQu9GP0LXRgtGB0Y8g0LIg0L3QsNGH0LDQu9C+INGA0L7QtNC40YLQtdC70Y8uXHJcbiAgICAgKiDQkiDQv9GA0L7RgtC40LLQvdC+0Lwg0YHQu9GD0YfQsNC1INGN0LvQtdC80LXQvdGCINC00L7QsdCw0LLQu9GP0LXRgtGB0Y8g0LIg0LrQvtC90LXRhi5cclxuICAgICAqL1xyXG4gICAgZWxlbWVudEFkZChcclxuICAgICAgICBwYXJlbnRFbGVtZW50OiBIVE1MRWxlbWVudCxcclxuICAgICAgICB0eXBlQXBwZW5kOiBUVHlwZUFwcGVuZCxcclxuICAgICAgICBkYXRhSWQ6IG51bWJlciB8IHN0cmluZyxcclxuICAgICAgICBldmVudE5hbWU6IFRBbGxFdmVudHMsXHJcbiAgICAgICAgZm46ICgoZXZlbnQ6IEV2ZW50LCAuLi5hcmdzOiBhbnlbXSkgPT4gdm9pZCkgfCBudWxsLFxyXG4gICAgICAgIGVsJDogSFRNTEVsZW1lbnRcclxuICAgICk6IHZvaWQge1xyXG4gICAgICAgIGlmICgnZmlyc3RDaGlsZCcgaW4gcGFyZW50RWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAodHlwZUFwcGVuZCA9PT0gJ2luc2VydEJlZm9yZScpIHtcclxuICAgICAgICAgICAgICAgIChwYXJlbnRFbGVtZW50IGFzIE5vZGUpLmluc2VydEJlZm9yZShlbCQsIHBhcmVudEVsZW1lbnQuZmlyc3RDaGlsZCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAocGFyZW50RWxlbWVudCBhcyBOb2RlKS5hcHBlbmRDaGlsZChlbCQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgKHBhcmVudEVsZW1lbnQgYXMgTm9kZSkuYXBwZW5kQ2hpbGQoZWwkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChmbikge1xyXG4gICAgICAgICAgICBlbCQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIGV2ZW50ID0+IHtcclxuICAgICAgICAgICAgICAgIGZuLmNhbGwobnVsbCwgZXZlbnQsIG51bGwsIGVsJCwgZGF0YUlkKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0KPQtNCw0LvRj9C10YIgSFRNTCDRjdC70LXQvNC10L3RgiDQuNC3IERPTVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBwYXJlbnRFbGVtZW50IC0g0KDQvtC00LjRgtC10LvRjNGB0LrQuNC5INGN0LvQtdC80LXQvdGCLCDRgdC+0LTQtdGA0LbQsNGJ0LjQuSDRg9C00LDQu9GP0LXQvNGL0Lkg0Y3Qu9C10LzQtdC90YJcclxuICAgICAqIEBwYXJhbSBlbCQgLSDQo9C00LDQu9GP0LXQvNGL0LkgRE9NINGN0LvQtdC80LXQvdGCXHJcbiAgICAgKlxyXG4gICAgICogQHJlbWFya3NcclxuICAgICAqINCc0LXRgtC+0LQg0LHQtdC30L7Qv9Cw0YHQvdC+INC30LDQstC10YDRiNCw0LXRgtGB0Y8sINC10YHQu9C4IHBhcmVudEVsZW1lbnQg0LjQu9C4IGVsJCDQvtGC0YHRg9GC0YHRgtCy0YPRjtGCXHJcbiAgICAgKi9cclxuICAgIGVsZW1lbnRSZW1vdmUocGFyZW50RWxlbWVudDogSFRNTEVsZW1lbnQsIGVsJDogSFRNTEVsZW1lbnQpOiB2b2lkIHtcclxuICAgICAgICBpZiAocGFyZW50RWxlbWVudCAmJiBlbCQpIHtcclxuICAgICAgICAgICAgKHBhcmVudEVsZW1lbnQgYXMgTm9kZSkucmVtb3ZlQ2hpbGQoZWwkKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQkNGB0LjQvdGF0YDQvtC90L3QviDQv9C+0LvRg9GH0LDQtdGCIEhUTUwg0Y3Qu9C10LzQtdC90YIg0YEg0L/QvtCy0YLQvtGA0L3Ri9C80Lgg0L/QvtC/0YvRgtC60LDQvNC4XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGlkZW50aWZpZXIgLSDQodC10LvQtdC60YLQvtGAINC00LvRjyDQv9C+0LjRgdC60LAg0Y3Qu9C10LzQtdC90YLQsFxyXG4gICAgICogQHBhcmFtIHNlbGVjdG9yIC0g0JzQtdGC0L7QtCDQv9C+0LjRgdC60LAgKCdxdWVyeVNlbGVjdG9yJyDQuNC70LggJ3F1ZXJ5U2VsZWN0b3JBbGwnKVxyXG4gICAgICogQHBhcmFtIG5vZGUgLSBET00g0YPQt9C10Lsg0LTQu9GPINC/0L7QuNGB0LrQsCAo0L/QviDRg9C80L7Qu9GH0LDQvdC40Y4gdGhpcy5kb2N1bWVudClcclxuICAgICAqIEBwYXJhbSB0aW1lIC0g0JfQsNC00LXRgNC20LrQsCDQvNC10LbQtNGDINC/0L7Qv9GL0YLQutCw0LzQuCDQsiDQvNGBICjQv9C+INGD0LzQvtC70YfQsNC90LjRjiAzMDApXHJcbiAgICAgKiBAcGFyYW0gbWF4IC0g0JzQsNC60YHQuNC80LDQu9GM0L3QvtC1INC60L7Qu9C40YfQtdGB0YLQstC+INC/0L7Qv9GL0YLQvtC6ICjQv9C+INGD0LzQvtC70YfQsNC90LjRjiAxMClcclxuICAgICAqIEByZXR1cm5zINCf0YDQvtC80LjRgSDRgSDQvdCw0LnQtNC10L3QvdGL0LwgRE9NINGN0LvQtdC80LXQvdGC0L7QvFxyXG4gICAgICpcclxuICAgICAqIEByZW1hcmtzXHJcbiAgICAgKiDQnNC10YLQvtC0INC/0L7Qu9C10LfQtdC9INC00LvRjyDQvtC20LjQtNCw0L3QuNGPINC/0L7Rj9Cy0LvQtdC90LjRjyDQtNC40L3QsNC80LjRh9C10YHQutC4INGB0L7Qt9C00LDQstCw0LXQvNGL0YUg0Y3Qu9C10LzQtdC90YLQvtCyXHJcbiAgICAgKi9cclxuICAgIGFzeW5jIGVsZW1lbnRHZXQoXHJcbiAgICAgICAgaWRlbnRpZmllcjogc3RyaW5nLFxyXG4gICAgICAgIHNlbGVjdG9yOiBUU2VsZWN0b3IgPSAncXVlcnlTZWxlY3RvcicsXHJcbiAgICAgICAgbm9kZTogRG9jdW1lbnQgfCBIVE1MRWxlbWVudCB8IG51bGwgPSB0aGlzLmRvY3VtZW50LFxyXG4gICAgICAgIHRpbWU6IG51bWJlciA9IDMwMCxcclxuICAgICAgICBtYXg6IG51bWJlciA9IDEwXHJcbiAgICApOiBQcm9taXNlPEhUTUxFbGVtZW50PiB7XHJcbiAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IHRoaXMuX2dldEVsZW1lbnRSZXN1bHQoaWRlbnRpZmllciwgc2VsZWN0b3IsIG5vZGUsIHRpbWUpO1xyXG5cclxuICAgICAgICBpZiAoKCFyZXN1bHQgfHwgKHJlc3VsdCBpbnN0YW5jZW9mIE5vZGVMaXN0ICYmIHJlc3VsdC5sZW5ndGggPCAxKSkgJiYgdGhpcy5fY291bnRHZXRFbGVtZW50IDwgbWF4KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvdW50R2V0RWxlbWVudCsrO1xyXG4gICAgICAgICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmVsZW1lbnRHZXQoaWRlbnRpZmllciwgc2VsZWN0b3IsIG5vZGUsIHRpbWUsIG1heCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0J3QsNGF0L7QtNC40YIg0Y3Qu9C10LzQtdC90YLRiyDQv9C+IGRhdGEt0LDRgtGA0LjQsdGD0YLRgyDQuNC70Lgg0LXQs9C+INC30L3QsNGH0LXQvdC40Y5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudFRvU2VsZWN0IC0g0J3QsNC30LLQsNC90LjQtSBkYXRhLdCw0YLRgNC40LHRg9GC0LAgKNC90LDQv9GA0LjQvNC10YAsICdkYXRhLWlkJylcclxuICAgICAqIEBwYXJhbSBkYXRhVmFsdWUgLSDQl9C90LDRh9C10L3QuNC1INCw0YLRgNC40LHRg9GC0LAg0LTQu9GPINGE0LjQu9GM0YLRgNCw0YbQuNC4ICjQvtC/0YbQuNC+0L3QsNC70YzQvdC+KVxyXG4gICAgICogQHJldHVybnMg0JzQsNGB0YHQuNCyINC90LDQudC00LXQvdC90YvRhSDRjdC70LXQvNC10L3RgtC+0LJcclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSDQldGB0LvQuCBlbGVtZW50VG9TZWxlY3Qg0L3QtSDRg9C60LDQt9Cw0L1cclxuICAgICAqXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogLy8g0J3QsNC50YLQuCDQstGB0LUg0Y3Qu9C10LzQtdC90YLRiyDRgSBkYXRhLWlkXHJcbiAgICAgKiBjb25zdCBpdGVtcyA9IHdvcmtlci5nZXRFbGVtZW50QnlEYXRhQXR0cmlidXRlKCdkYXRhLWlkJyk7XHJcbiAgICAgKlxyXG4gICAgICogLy8g0J3QsNC50YLQuCDRjdC70LXQvNC10L3RgiDRgSDQutC+0L3QutGA0LXRgtC90YvQvCDQt9C90LDRh9C10L3QuNC10LxcclxuICAgICAqIGNvbnN0IGl0ZW0gPSB3b3JrZXIuZ2V0RWxlbWVudEJ5RGF0YUF0dHJpYnV0ZSgnZGF0YS1pZCcsICcxMjMnKTtcclxuICAgICAqL1xyXG4gICAgZ2V0RWxlbWVudEJ5RGF0YUF0dHJpYnV0ZShlbGVtZW50VG9TZWxlY3Q6IHN0cmluZywgZGF0YVZhbHVlOiBzdHJpbmcgfCBudWxsID0gbnVsbCk6IEhUTUxFbGVtZW50W10ge1xyXG4gICAgICAgIGlmICghZWxlbWVudFRvU2VsZWN0KSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZWxlbWVudFRvU2VsZWN0IGlzIHJlcXVpcmVkIGZvciBnZXRFbGVtZW50QnlEYXRhQXR0cmlidXRlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHNlbGVjdG9yID0gZGF0YVZhbHVlID8gYFske2VsZW1lbnRUb1NlbGVjdH09JyR7ZGF0YVZhbHVlfSddYCA6IGBbJHtlbGVtZW50VG9TZWxlY3R9XWA7XHJcbiAgICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xyXG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKGVsZW1lbnRzKSBhcyBIVE1MRWxlbWVudFtdO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0JLQvdGD0YLRgNC10L3QvdC40Lkg0LzQtdGC0L7QtCDQtNC70Y8g0L/QvtC70YPRh9C10L3QuNGPINGN0LvQtdC80LXQvdGC0LAg0YEg0LfQsNC00LXRgNC20LrQvtC5XHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGlkZW50aWZpZXIgLSDQodC10LvQtdC60YLQvtGAINGN0LvQtdC80LXQvdGC0LBcclxuICAgICAqIEBwYXJhbSBzZWxlY3RvciAtINCc0LXRgtC+0LQg0L/QvtC40YHQutCwXHJcbiAgICAgKiBAcGFyYW0gbm9kZSAtINCa0L7RgNC90LXQstC+0Lkg0YPQt9C10LtcclxuICAgICAqIEBwYXJhbSB0aW1lIC0g0JLRgNC10LzRjyDQt9Cw0LTQtdGA0LbQutC4INCyINC80YFcclxuICAgICAqIEByZXR1cm5zINCf0YDQvtC80LjRgSDRgSDRgNC10LfRg9C70YzRgtCw0YLQvtC8INC/0L7QuNGB0LrQsFxyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBhc3luYyBfZ2V0RWxlbWVudFJlc3VsdChcclxuICAgICAgICBpZGVudGlmaWVyOiBzdHJpbmcsXHJcbiAgICAgICAgc2VsZWN0b3I6IFRTZWxlY3RvcixcclxuICAgICAgICBub2RlOiBEb2N1bWVudCB8IEhUTUxFbGVtZW50IHwgbnVsbCxcclxuICAgICAgICB0aW1lOiBudW1iZXJcclxuICAgICk6IFByb21pc2U8SFRNTEVsZW1lbnQ+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2V0RGVsYXkodGltZSlcclxuICAgICAgICAgICAgLnRoZW4oXyA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW5vZGUpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vINCY0YHQv9C+0LvRjNC30YPQtdC8IHR5cGUgYXNzZXJ0aW9uINC00LvRjyDQstGL0LfQvtCy0LAg0LzQtdGC0L7QtNCwXHJcbiAgICAgICAgICAgICAgICBjb25zdCByZXN1bHQgPSAobm9kZSBhcyBhbnkpW3NlbGVjdG9yXShpZGVudGlmaWVyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgfHwgbnVsbDtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgLmNhdGNoKGVycm9yID0+IGNvbnNvbGUubG9nKCfQntGI0LjQsdC60LAg0LIgX2dldEVsZW1lbnRSZXN1bHQnLCBlcnJvcikpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0KHQvtC30LTQsNC10YIgUHJvbWlzZSDRgSDQt9Cw0LTQtdGA0LbQutC+0LlcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gbXMgLSDQktGA0LXQvNGPINC30LDQtNC10YDQttC60Lgg0LIg0LzQuNC70LvQuNGB0LXQutGD0L3QtNCw0YVcclxuICAgICAqIEByZXR1cm5zIFByb21pc2UsINC60L7RgtC+0YDRi9C5INGA0LDQt9GA0LXRiNCw0LXRgtGB0Y8g0YfQtdGA0LXQtyDRg9C60LDQt9Cw0L3QvdC+0LUg0LLRgNC10LzRj1xyXG4gICAgICogQHByaXZhdGVcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfc2V0RGVsYXkobXM6IG51bWJlcik6IFByb21pc2U8dW5rbm93bj4ge1xyXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShyZXNvbHZlID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINGA0LDQt9C80LXRgNGLINGN0LvQtdC80LXQvdGC0LAg0Lgg0LXQs9C+INC/0L7Qu9C+0LbQtdC90LjQtSDQvtGC0L3QvtGB0LjRgtC10LvRjNC90L4gdmlld3BvcnRcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudCAtINCm0LXQu9C10LLQvtC5IERPTSDRjdC70LXQvNC10L3RglxyXG4gICAgICogQHJldHVybnMgRE9NUmVjdCDQvtCx0YrQtdC60YIg0YEg0LrQvtC+0YDQtNC40L3QsNGC0LDQvNC4ICh0b3AsIGxlZnQsIHJpZ2h0LCBib3R0b20pINC4INGA0LDQt9C80LXRgNCw0LzQuCAod2lkdGgsIGhlaWdodClcclxuICAgICAqIEB0aHJvd3Mge0Vycm9yfSDQldGB0LvQuCBlbGVtZW50INC90LUg0YPQutCw0LfQsNC9XHJcbiAgICAgKlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIGNvbnN0IHJlY3QgPSB3b3JrZXIuZ2V0Q29vcmRpbmF0ZXMoYnV0dG9uRWxlbWVudCk7XHJcbiAgICAgKiBjb25zb2xlLmxvZyhyZWN0LnRvcCwgcmVjdC5sZWZ0LCByZWN0LndpZHRoKTtcclxuICAgICAqL1xyXG4gICAgZ2V0Q29vcmRpbmF0ZXMoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBET01SZWN0IHtcclxuICAgICAgICBpZiAoIWVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdFbGVtZW50IGlzIHJlcXVpcmVkIGZvciBnZXRDb29yZGluYXRlcycpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqINCS0L7Qt9Cy0YDQsNGJ0LDQtdGCINGA0L7QtNC40YLQtdC70YzRgdC60LjQuSDRjdC70LXQvNC10L3RgiDRg9C60LDQt9Cw0L3QvdC+0LPQviBET00g0YPQt9C70LBcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gZWwgLSBET00g0Y3Qu9C10LzQtdC90YIg0LjQu9C4IE5vZGVMaXN0XHJcbiAgICAgKiBAcmV0dXJucyDQoNC+0LTQuNGC0LXQu9GM0YHQutC40Lkg0Y3Qu9C10LzQtdC90YIg0LjQu9C4IG51bGwsINC10YHQu9C4INGA0L7QtNC40YLQtdC70Y8g0L3QtdGCXHJcbiAgICAgKi9cclxuICAgIGVsZW1lbnRHZXRQYXJlbnQoZWw6IEVsZW1lbnQgfCBOb2RlTGlzdCk6IE5vZGUgJiBQYXJlbnROb2RlIHwgbnVsbCB7XHJcbiAgICAgICAgaWYgKGVsICYmICdwYXJlbnROb2RlJyBpbiBlbCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZWwucGFyZW50Tm9kZSBhcyBOb2RlICYgUGFyZW50Tm9kZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0LLRgdC1INGB0L7RgdC10LTQvdC40LUg0Y3Qu9C10LzQtdC90YLRiyAo0LLQutC70Y7Rh9Cw0Y8g0YHQsNC8INGN0LvQtdC80LXQvdGCKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBlbCAtINCY0YHRhdC+0LTQvdGL0LkgRE9NINGN0LvQtdC80LXQvdGCXHJcbiAgICAgKiBAcmV0dXJucyDQnNCw0YHRgdC40LIg0LLRgdC10YUg0Y3Qu9C10LzQtdC90YLQvtCyINCyINGC0LXQutGD0YnQtdC5INCy0LXRgtC60LUgRE9NINC00LXRgNC10LLQsFxyXG4gICAgICpcclxuICAgICAqIEByZW1hcmtzXHJcbiAgICAgKiDQnNC10YLQvtC0INGB0L7QsdC40YDQsNC10YIg0LLRgdC1INGN0LvQtdC80LXQvdGC0Ysg0L3QsCDQvtC00L3QvtC8INGD0YDQvtCy0L3QtSDQstC70L7QttC10L3QvdC+0YHRgtC4XHJcbiAgICAgKi9cclxuICAgIGVsZW1lbnRzR2V0U2libGluZ0FsbChlbDogRWxlbWVudCB8IE5vZGVMaXN0KTogRWxlbWVudFtdIHtcclxuICAgICAgICBpZiAoZWwgJiYgJ3BhcmVudE5vZGUnIGluIGVsKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmVudCA9IGVsLnBhcmVudE5vZGUgYXMgTm9kZSAmIFBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpcnN0RWxlbWVudCA9IHBhcmVudC5maXJzdENoaWxkIGFzIEVsZW1lbnQ7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRHZXRTaWJsaW5nTmV4dChmaXJzdEVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gW107XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQktC+0LfQstGA0LDRidCw0LXRgiDQstGB0LUg0YHQu9C10LTRg9GO0YnQuNC1INGB0L7RgdC10LTQvdC40LUg0Y3Qu9C10LzQtdC90YLRiyAobmV4dEVsZW1lbnRTaWJsaW5nKVxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBlbCAtINCY0YHRhdC+0LTQvdGL0LkgRE9NINGN0LvQtdC80LXQvdGCXHJcbiAgICAgKiBAcmV0dXJucyDQnNCw0YHRgdC40LIg0Y3Qu9C10LzQtdC90YLQvtCyLCDQvdCw0YfQuNC90LDRjyDRgSDRg9C60LDQt9Cw0L3QvdC+0LPQviDQuCDQstC60LvRjtGH0LDRjyDQstGB0LUg0YHQu9C10LTRg9GO0YnQuNC1XHJcbiAgICAgKlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIGNvbnN0IG5leHRFbGVtZW50cyA9IHdvcmtlci5lbGVtZW50R2V0U2libGluZ05leHQoY3VycmVudEVsZW1lbnQpO1xyXG4gICAgICogLy8g0JLQvtC30LLRgNCw0YnQsNC10YIgW2N1cnJlbnRFbGVtZW50LCBuZXh0RWxlbWVudCwgbmV4dE5leHRFbGVtZW50LCAuLi5dXHJcbiAgICAgKi9cclxuICAgIGVsZW1lbnRHZXRTaWJsaW5nTmV4dChlbDogRWxlbWVudCB8IE5vZGVMaXN0KTogRWxlbWVudFtdIHtcclxuICAgICAgICBjb25zdCByZXN1bHQ6IEVsZW1lbnRbXSA9IFtdO1xyXG5cclxuICAgICAgICB3aGlsZSAoZWwpIHtcclxuICAgICAgICAgICAgaWYgKCduZXh0RWxlbWVudFNpYmxpbmcnIGluIGVsKSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQucHVzaChlbCBhcyBFbGVtZW50KTtcclxuICAgICAgICAgICAgICAgIGVsID0gKGVsIGFzIEVsZW1lbnQpLm5leHRFbGVtZW50U2libGluZyBhcyBFbGVtZW50O1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQktC+0LfQstGA0LDRidCw0LXRgiDQstGB0LUg0L/RgNC10LTRi9C00YPRidC40LUg0YHQvtGB0LXQtNC90LjQtSDRjdC70LXQvNC10L3RgtGLIChwcmV2aW91c1NpYmxpbmcpXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVsIC0g0JjRgdGF0L7QtNC90YvQuSBET00g0Y3Qu9C10LzQtdC90YJcclxuICAgICAqIEByZXR1cm5zINCc0LDRgdGB0LjQsiDQv9GA0LXQtNGL0LTRg9GJ0LjRhSDRjdC70LXQvNC10L3RgtC+0LJcclxuICAgICAqXHJcbiAgICAgKiBAcmVtYXJrc1xyXG4gICAgICog0JLQvtC30LLRgNCw0YnQsNC10YIg0LLRgdC1INGN0LvQtdC80LXQvdGC0YssINCy0LrQu9GO0YfQsNGPINGD0LrQsNC30LDQvdC90YvQuSwg0LIg0L7QsdGA0LDRgtC90L7QvCDQv9C+0YDRj9C00LrQtVxyXG4gICAgICovXHJcbiAgICBlbGVtZW50R2V0U2libGluZ1ByZXZpb3VzKGVsOiBFbGVtZW50IHwgTm9kZUxpc3QgfCBOb2RlKTogRWxlbWVudFtdIHtcclxuICAgICAgICBjb25zdCByZXN1bHQ6IEVsZW1lbnRbXSA9IFtdO1xyXG4gICAgICAgIGxldCBjdXJyZW50OiBOb2RlIHwgbnVsbCA9IGVsIGFzIE5vZGU7XHJcblxyXG4gICAgICAgIHdoaWxlIChjdXJyZW50KSB7XHJcbiAgICAgICAgICAgIHJlc3VsdC5wdXNoKGN1cnJlbnQgYXMgRWxlbWVudCk7XHJcbiAgICAgICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnByZXZpb3VzU2libGluZztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiDQktC+0LfQstGA0LDRidCw0LXRgiDQstGB0LUg0L/RgNGP0LzRi9C1INC00L7Rh9C10YDQvdC40LUg0Y3Qu9C10LzQtdC90YLRiyDRg9C60LDQt9Cw0L3QvdC+0LPQviDRgNC+0LTQuNGC0LXQu9GPXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGVsIC0g0KDQvtC00LjRgtC10LvRjNGB0LrQuNC5IERPTSDRjdC70LXQvNC10L3RglxyXG4gICAgICogQHJldHVybnMg0JzQsNGB0YHQuNCyINC00L7Rh9C10YDQvdC40YUg0Y3Qu9C10LzQtdC90YLQvtCyXHJcbiAgICAgKlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIGNvbnN0IGNoaWxkcmVuID0gd29ya2VyLmVsZW1lbnRHZXRDaGlsZHJlbihwYXJlbnRFbGVtZW50KTtcclxuICAgICAqIGNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4gY29uc29sZS5sb2coY2hpbGQudGFnTmFtZSkpO1xyXG4gICAgICovXHJcbiAgICBlbGVtZW50R2V0Q2hpbGRyZW4oZWw6IEVsZW1lbnQpOiBFbGVtZW50W10ge1xyXG4gICAgICAgIHJldHVybiBBcnJheS5mcm9tKGVsLmNoaWxkcmVuKSBhcyBFbGVtZW50W107XHJcbiAgICB9XHJcbn1cclxuIl19