@plait/core 0.56.2 → 0.58.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.
@@ -5,7 +5,6 @@ import { PlaitHistory } from './history';
5
5
  import { PlaitOperation } from './operation';
6
6
  import { Selection } from './selection';
7
7
  import { Viewport } from './viewport';
8
- import { PlaitPluginElementComponent } from '../core/element/plugin-element';
9
8
  import { RoughSVG } from 'roughjs/bin/svg';
10
9
  import { BoardComponentInterface } from '../board/board.component.interface';
11
10
  import { Point } from './point';
@@ -15,6 +14,7 @@ import { PlaitNode } from './node';
15
14
  import { Path } from './path';
16
15
  import { PlaitTheme, ThemeColor } from './theme';
17
16
  import { ClipboardData, WritableClipboardContext, WritableClipboardOperationType } from '../utils';
17
+ import { ElementFlavour } from '../core/element/element-flavour';
18
18
  export interface PlaitBoard {
19
19
  viewport: Viewport;
20
20
  children: PlaitElement[];
@@ -45,7 +45,7 @@ export interface PlaitBoard {
45
45
  getDeletedFragment: (data: PlaitElement[]) => PlaitElement[];
46
46
  getRelatedFragment: (data: PlaitElement[], originData?: PlaitElement[]) => PlaitElement[];
47
47
  dblClick: (event: MouseEvent) => void;
48
- drawElement: (context: PlaitPluginElementContext) => ComponentType<PlaitPluginElementComponent>;
48
+ drawElement: (context: PlaitPluginElementContext) => ComponentType<ElementFlavour>;
49
49
  isRectangleHit: (element: PlaitElement, range: Selection) => boolean;
50
50
  isHit: (element: PlaitElement, point: Point) => boolean;
51
51
  isInsidePoint: (element: PlaitElement, point: Point) => boolean;
@@ -92,11 +92,13 @@ export declare const PlaitBoard: {
92
92
  isAlive(board: PlaitBoard): boolean;
93
93
  findPath(board: PlaitBoard, node: PlaitNode): Path;
94
94
  getHost(board: PlaitBoard): SVGSVGElement;
95
+ getElementLowerHost(board: PlaitBoard): SVGSVGElement;
95
96
  getElementHost(board: PlaitBoard): SVGSVGElement;
96
97
  getElementUpperHost(board: PlaitBoard): SVGSVGElement;
97
98
  getElementActiveHost(board: PlaitBoard): SVGSVGElement;
98
99
  getRoughSVG(board: PlaitBoard): RoughSVG;
99
100
  getComponent(board: PlaitBoard): BoardComponentInterface;
101
+ getViewContainerRef(board: PlaitBoard): import("@angular/core").ViewContainerRef;
100
102
  getBoardContainer(board: PlaitBoard): HTMLElement;
101
103
  getRectangle(board: PlaitBoard): RectangleClient;
102
104
  getViewportContainer(board: PlaitBoard): HTMLElement;
@@ -1,5 +1,3 @@
1
- import { PlaitPluginElementComponent } from '../core/element/plugin-element';
2
- import { PlaitBoard } from './board';
3
1
  import { Point } from './point';
4
2
  import { PlaitElementRef } from '../core/element/element-ref';
5
3
  export interface PlaitElement {
@@ -9,10 +7,10 @@ export interface PlaitElement {
9
7
  points?: Point[];
10
8
  type?: string;
11
9
  groupId?: string;
10
+ angle?: number;
12
11
  }
13
12
  export declare const PlaitElement: {
14
13
  isRootElement(value: PlaitElement): boolean;
15
- getComponent(value: PlaitElement): PlaitPluginElementComponent<PlaitElement, PlaitBoard, PlaitElementRef>;
16
14
  getElementRef<T extends PlaitElementRef = PlaitElementRef>(value: PlaitElement): T;
17
15
  getElementG(value: PlaitElement): SVGGElement;
18
16
  hasMounted(element: PlaitElement): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plait/core",
3
- "version": "0.56.2",
3
+ "version": "0.58.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^17.2.4",
6
6
  "@angular/core": "^17.2.4",
package/public-api.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export * from './board/board.component';
2
2
  export * from './constants';
3
- export * from './core/element/plugin-element';
4
3
  export * from './core/element/context-change';
4
+ export * from './core/element/element-flavour';
5
5
  export * from './core/island/island-base.component';
6
6
  export * from './core/element/element-ref';
7
7
  export * from './interfaces';
package/utils/angle.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PlaitBoard, PlaitElement, Point, RectangleClient } from '../interfaces';
2
- export declare const rotatePoints: <T>(points: T, centerPoint: Point, angle: number) => T;
3
- export declare const getSelectionAngle: (elements: PlaitElement[]) => any;
2
+ export declare const rotatePoints: <T>(points: T, centerPoint: Point, angle?: number) => T;
3
+ export declare const getSelectionAngle: (elements: PlaitElement[]) => number;
4
4
  export declare const hasSameAngle: (elements: PlaitElement[]) => boolean;
5
5
  export declare const getRotatedBoundingRectangle: (rectanglesCornerPoints: [Point, Point, Point, Point][], angle: number) => RectangleClient;
6
6
  export declare const getOffsetAfterRotate: (rectangle: RectangleClient, rotateCenterPoint: Point, angle: number) => {
@@ -8,15 +8,15 @@ export declare const getOffsetAfterRotate: (rectangle: RectangleClient, rotateCe
8
8
  offsetY: number;
9
9
  };
10
10
  export declare const rotatedDataPoints: (points: Point[], rotateCenterPoint: Point, angle: number) => Point[];
11
- export declare const hasValidAngle: (node: PlaitElement) => any;
11
+ export declare const hasValidAngle: (node: PlaitElement) => boolean | 0 | undefined;
12
12
  export declare const rotatePointsByElement: <T>(points: T, element: PlaitElement) => T | null;
13
13
  export declare const rotateAntiPointsByElement: <T>(points: T, element: PlaitElement) => T | null;
14
- export declare const getRectangleByAngle: (rectangle: RectangleClient, angle: number) => RectangleClient | null;
14
+ export declare const getRectangleByAngle: (rectangle: RectangleClient, angle: number) => RectangleClient;
15
15
  export declare const isAxisChangedByAngle: (angle: number) => boolean;
16
16
  export declare function degreesToRadians(d: number): number;
17
17
  export declare function radiansToDegrees(r: number): number;
18
18
  export declare function rotateElements(board: PlaitBoard, elements: PlaitElement[], angle: number): void;
19
19
  export declare const normalizeAngle: (angle: number) => number;
20
20
  export declare const getAngleBetweenPoints: (startPoint: Point, endPoint: Point, centerPoint: Point) => number;
21
- export declare const getAngleByElement: (element: PlaitElement) => number;
21
+ export declare const getAngleByElement: (element: PlaitElement) => number | undefined;
22
22
  export declare const setAngleForG: (g: SVGGElement, centerPoint: Point, angle: number) => void;
@@ -1,5 +1,6 @@
1
1
  import { PlaitBoard, PlaitElement, RectangleClient } from '../interfaces';
2
2
  export declare function getRectangleByElements(board: PlaitBoard, elements: PlaitElement[], recursion: boolean): RectangleClient;
3
+ export declare function getBoundingRectangleByElements(board: PlaitBoard, elements: PlaitElement[], recursion: boolean): RectangleClient;
3
4
  export declare function getBoardRectangle(board: PlaitBoard): RectangleClient;
4
5
  export declare function getElementById<T extends PlaitElement = PlaitElement>(board: PlaitBoard, id: string, dataSource?: PlaitElement[]): T | undefined;
5
6
  export declare function findElements<T extends PlaitElement = PlaitElement>(board: PlaitBoard, options: {
@@ -13,3 +13,5 @@ export declare const removeSelectedElement: (board: PlaitBoard, element: PlaitEl
13
13
  export declare const clearSelectedElement: (board: PlaitBoard) => void;
14
14
  export declare const isSelectedElement: (board: PlaitBoard, element: PlaitElement) => boolean;
15
15
  export declare const temporaryDisableSelection: (board: PlaitOptionsBoard) => void;
16
+ export declare const isHitSelectedRectangle: (board: PlaitBoard, point: Point) => boolean;
17
+ export declare const isHitElement: (board: PlaitBoard, point: Point) => boolean;
@@ -20,6 +20,7 @@ export declare const BOARD_TO_ROUGH_SVG: WeakMap<PlaitBoard, RoughSVG>;
20
20
  export declare const BOARD_TO_HOST: WeakMap<PlaitBoard, SVGSVGElement>;
21
21
  export declare const IS_BOARD_ALIVE: WeakMap<PlaitBoard, boolean>;
22
22
  export declare const BOARD_TO_ELEMENT_HOST: WeakMap<PlaitBoard, {
23
+ lowerHost: SVGGElement;
23
24
  host: SVGGElement;
24
25
  upperHost: SVGGElement;
25
26
  activeHost: SVGGElement;
@@ -1,34 +0,0 @@
1
- import { ChangeDetectorRef, OnDestroy, OnInit, ViewContainerRef } from '@angular/core';
2
- import { PlaitBoard, PlaitElement, PlaitPluginElementContext } from '../../interfaces';
3
- import { ListRender } from '../list-render';
4
- import { PlaitElementRef } from './element-ref';
5
- import * as i0 from "@angular/core";
6
- export declare abstract class PlaitPluginElementComponent<T extends PlaitElement = PlaitElement, K extends PlaitBoard = PlaitBoard, R extends PlaitElementRef = PlaitElementRef> implements OnInit, OnDestroy {
7
- private ref;
8
- viewContainerRef: ViewContainerRef;
9
- cdr: ChangeDetectorRef;
10
- private _g;
11
- private _containerG;
12
- private _rootContainerG?;
13
- initialized: boolean;
14
- protected _context: PlaitPluginElementContext<T, K>;
15
- get hasChildren(): boolean;
16
- set context(value: PlaitPluginElementContext<T, K>);
17
- get context(): PlaitPluginElementContext<T, K>;
18
- get element(): T;
19
- get board(): K;
20
- get selected(): boolean;
21
- listRender?: ListRender;
22
- getContainerG(): SVGGElement;
23
- getElementG(): SVGGElement;
24
- constructor(ref: R);
25
- ngOnInit(): void;
26
- initializeListRender(): void;
27
- getRef(): R;
28
- private updateListRender;
29
- private initializeChildrenContext;
30
- ngOnDestroy(): void;
31
- static ɵfac: i0.ɵɵFactoryDeclaration<PlaitPluginElementComponent<any, any, any>, never>;
32
- static ɵdir: i0.ɵɵDirectiveDeclaration<PlaitPluginElementComponent<any, any, any>, never, never, { "context": { "alias": "context"; "required": false; }; }, {}, never, never, false, never>;
33
- }
34
- export declare const ELEMENT_TO_COMPONENT: WeakMap<PlaitElement, PlaitPluginElementComponent<PlaitElement, PlaitBoard, PlaitElementRef>>;
@@ -1,151 +0,0 @@
1
- import { ChangeDetectorRef, Directive, Input, ViewContainerRef, inject } from '@angular/core';
2
- import { PlaitBoard, PlaitElement, PlaitNode } from '../../interfaces';
3
- import { removeSelectedElement } from '../../utils/selected-element';
4
- import { createG } from '../../utils/dom/common';
5
- import { hasBeforeContextChange, hasOnContextChanged } from './context-change';
6
- import { ListRender } from '../list-render';
7
- import { ELEMENT_TO_REF, NODE_TO_CONTAINER_G, NODE_TO_G } from '../../utils/weak-maps';
8
- import * as i0 from "@angular/core";
9
- export class PlaitPluginElementComponent {
10
- get hasChildren() {
11
- return !!this.element.children;
12
- }
13
- set context(value) {
14
- if (hasBeforeContextChange(this)) {
15
- this.beforeContextChange(value);
16
- }
17
- const previousContext = this._context;
18
- this._context = value;
19
- if (this.element) {
20
- ELEMENT_TO_COMPONENT.set(this.element, this);
21
- }
22
- if (this.initialized) {
23
- const elementG = this.getElementG();
24
- const containerG = this.getContainerG();
25
- NODE_TO_G.set(this.element, elementG);
26
- NODE_TO_CONTAINER_G.set(this.element, containerG);
27
- ELEMENT_TO_REF.set(this.element, this.ref);
28
- this.updateListRender();
29
- this.cdr.markForCheck();
30
- if (hasOnContextChanged(this)) {
31
- this.onContextChanged(value, previousContext);
32
- }
33
- }
34
- else {
35
- if (PlaitElement.isRootElement(this.element) && this.hasChildren) {
36
- this._g = createG();
37
- this._containerG = createG();
38
- this._containerG.append(this._g);
39
- }
40
- else {
41
- this._g = createG();
42
- this._containerG = this._g;
43
- }
44
- NODE_TO_G.set(this.element, this._g);
45
- NODE_TO_CONTAINER_G.set(this.element, this._containerG);
46
- ELEMENT_TO_REF.set(this.element, this.ref);
47
- }
48
- }
49
- get context() {
50
- return this._context;
51
- }
52
- get element() {
53
- return this.context && this.context.element;
54
- }
55
- get board() {
56
- return this.context && this.context.board;
57
- }
58
- get selected() {
59
- return this.context && this.context.selected;
60
- }
61
- getContainerG() {
62
- return this._containerG;
63
- }
64
- getElementG() {
65
- return this._g;
66
- }
67
- constructor(ref) {
68
- this.ref = ref;
69
- this.viewContainerRef = inject(ViewContainerRef);
70
- this.cdr = inject(ChangeDetectorRef);
71
- this.initialized = false;
72
- }
73
- ngOnInit() {
74
- if (this.element.type) {
75
- this.getContainerG().setAttribute(`plait-${this.element.type}`, 'true');
76
- }
77
- if (this.hasChildren) {
78
- if (PlaitElement.isRootElement(this.element)) {
79
- this._rootContainerG = this._containerG;
80
- }
81
- else {
82
- const path = PlaitBoard.findPath(this.board, this.element);
83
- const rootNode = PlaitNode.get(this.board, path.slice(0, 1));
84
- this._rootContainerG = PlaitElement.getContainerG(rootNode, { suppressThrow: false });
85
- }
86
- }
87
- this.getContainerG().setAttribute('plait-data-id', this.element.id);
88
- this.initialized = true;
89
- }
90
- initializeListRender() {
91
- if (this.hasChildren) {
92
- this.listRender = new ListRender(this.board, this.viewContainerRef);
93
- if (this.board.isExpanded(this.element)) {
94
- this.listRender.initialize(this.element.children, this.initializeChildrenContext());
95
- }
96
- }
97
- }
98
- getRef() {
99
- return this.ref;
100
- }
101
- updateListRender() {
102
- if (this.hasChildren) {
103
- if (!this.listRender) {
104
- throw new Error('incorrectly initialize list render');
105
- }
106
- if (this.board.isExpanded(this.element)) {
107
- this.listRender.update(this.element.children, this.initializeChildrenContext());
108
- }
109
- else {
110
- if (this.listRender.initialized) {
111
- this.listRender.destroy();
112
- }
113
- }
114
- }
115
- }
116
- initializeChildrenContext() {
117
- if (!this._rootContainerG) {
118
- throw new Error('can not resolve root container g');
119
- }
120
- return {
121
- board: this.board,
122
- parent: this.element,
123
- parentG: this._rootContainerG
124
- };
125
- }
126
- ngOnDestroy() {
127
- if (ELEMENT_TO_COMPONENT.get(this.element) === this) {
128
- ELEMENT_TO_COMPONENT.delete(this.element);
129
- }
130
- if (NODE_TO_G.get(this.element) === this._g) {
131
- NODE_TO_G.delete(this.element);
132
- }
133
- if (NODE_TO_CONTAINER_G.get(this.element) === this._containerG) {
134
- NODE_TO_CONTAINER_G.delete(this.element);
135
- }
136
- if (ELEMENT_TO_REF.get(this.element) === this.ref) {
137
- ELEMENT_TO_REF.set(this.element, this.ref);
138
- }
139
- removeSelectedElement(this.board, this.element);
140
- this.getContainerG().remove();
141
- }
142
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitPluginElementComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive }); }
143
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.2.4", type: PlaitPluginElementComponent, inputs: { context: "context" }, ngImport: i0 }); }
144
- }
145
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.2.4", ngImport: i0, type: PlaitPluginElementComponent, decorators: [{
146
- type: Directive
147
- }], ctorParameters: () => [{ type: undefined }], propDecorators: { context: [{
148
- type: Input
149
- }] } });
150
- export const ELEMENT_TO_COMPONENT = new WeakMap();
151
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWVsZW1lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9jb3JlL2VsZW1lbnQvcGx1Z2luLWVsZW1lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQXFCLGdCQUFnQixFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsVUFBVSxFQUF3QixZQUFZLEVBQUUsU0FBUyxFQUE2QixNQUFNLGtCQUFrQixDQUFDO0FBQ3hILE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUMvRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7QUFJdkYsTUFBTSxPQUFnQiwyQkFBMkI7SUFvQjdDLElBQUksV0FBVztRQUNYLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDO0lBQ25DLENBQUM7SUFFRCxJQUNJLE9BQU8sQ0FBQyxLQUFzQztRQUM5QyxJQUFJLHNCQUFzQixDQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFDRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQ3RDLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lB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ZXRlY3RvclJlZiwgRGlyZWN0aXZlLCBJbnB1dCwgT25EZXN0cm95LCBPbkluaXQsIFZpZXdDb250YWluZXJSZWYsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgUGxhaXRCb2FyZCwgUGxhaXRDaGlsZHJlbkNvbnRleHQsIFBsYWl0RWxlbWVudCwgUGxhaXROb2RlLCBQbGFpdFBsdWdpbkVsZW1lbnRDb250ZXh0IH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyByZW1vdmVTZWxlY3RlZEVsZW1lbnQgfSBmcm9tICcuLi8uLi91dGlscy9zZWxlY3RlZC1lbGVtZW50JztcbmltcG9ydCB7IGNyZWF0ZUcgfSBmcm9tICcuLi8uLi91dGlscy9kb20vY29tbW9uJztcbmltcG9ydCB7IGhhc0JlZm9yZUNvbnRleHRDaGFuZ2UsIGhhc09uQ29udGV4dENoYW5nZWQgfSBmcm9tICcuL2NvbnRleHQtY2hhbmdlJztcbmltcG9ydCB7IExpc3RSZW5kZXIgfSBmcm9tICcuLi9saXN0LXJlbmRlcic7XG5pbXBvcnQgeyBFTEVNRU5UX1RPX1JFRiwgTk9ERV9UT19DT05UQUlORVJfRywgTk9ERV9UT19HIH0gZnJvbSAnLi4vLi4vdXRpbHMvd2Vhay1tYXBzJztcbmltcG9ydCB7IFBsYWl0RWxlbWVudFJlZiB9IGZyb20gJy4vZWxlbWVudC1yZWYnO1xuXG5ARGlyZWN0aXZlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBQbGFpdFBsdWdpbkVsZW1lbnRDb21wb25lbnQ8XG4gICAgVCBleHRlbmRzIFBsYWl0RWxlbWVudCA9IFBsYWl0RWxlbWVudCxcbiAgICBLIGV4dGVuZHMgUGxhaXRCb2FyZCA9IFBsYWl0Qm9hcmQsXG4gICAgUiBleHRlbmRzIFBsYWl0RWxlbWVudFJlZiA9IFBsYWl0RWxlbWVudFJlZlxuPiBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICB2aWV3Q29udGFpbmVyUmVmID0gaW5qZWN0KFZpZXdDb250YWluZXJSZWYpO1xuICAgIGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgICBwcml2YXRlIF9nITogU1ZHR0VsZW1lbnQ7XG5cbiAgICBwcml2YXRlIF9jb250YWluZXJHITogU1ZHR0VsZW1lbnQ7XG5cbiAgICAvLyBjaGlsZHJlbiBlbGVtZW50cydzIHJlbmRlciBuZWVkIHJvb3RDb250YWluZXJHXG4gICAgLy8gdGhlIHZhbHVlIG9mIHJvb3RDb250YWluZXJHIGNvbWUgZnJvbSB0aGUgY29udGFpbmVyRyBvZiByb290IGVsZW1lbnRcbiAgICBwcml2YXRlIF9yb290Q29udGFpbmVyRz86IFNWR0dFbGVtZW50O1xuXG4gICAgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcblxuICAgIHByb3RlY3RlZCBfY29udGV4dCE6IFBsYWl0UGx1Z2luRWxlbWVudENvbnRleHQ8VCwgSz47XG5cbiAgICBnZXQgaGFzQ2hpbGRyZW4oKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuZWxlbWVudC5jaGlsZHJlbjtcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBjb250ZXh0KHZhbHVlOiBQbGFpdFBsdWdpbkVsZW1lbnRDb250ZXh0PFQsIEs+KSB7XG4gICAgICAgIGlmIChoYXNCZWZvcmVDb250ZXh0Q2hhbmdlPFQsIEs+KHRoaXMpKSB7XG4gICAgICAgICAgICB0aGlzLmJlZm9yZUNvbnRleHRDaGFuZ2UodmFsdWUpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHByZXZpb3VzQ29udGV4dCA9IHRoaXMuX2NvbnRleHQ7XG4gICAgICAgIHRoaXMuX2NvbnRleHQgPSB2YWx1ZTtcbiAgICAgICAgaWYgKHRoaXMuZWxlbWVudCkge1xuICAgICAgICAgICAgRUxFTUVOVF9UT19DT01QT05FTlQuc2V0KHRoaXMuZWxlbWVudCwgdGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRHID0gdGhpcy5nZXRFbGVtZW50RygpO1xuICAgICAgICAgICAgY29uc3QgY29udGFpbmVyRyA9IHRoaXMuZ2V0Q29udGFpbmVyRygpO1xuICAgICAgICAgICAgTk9ERV9UT19HLnNldCh0aGlzLmVsZW1lbnQsIGVsZW1lbnRHKTtcbiAgICAgICAgICAgIE5PREVfVE9fQ09OVEFJTkVSX0cuc2V0KHRoaXMuZWxlbWVudCwgY29udGFpbmVyRyk7XG4gICAgICAgICAgICBFTEVNRU5UX1RPX1JFRi5zZXQodGhpcy5lbGVtZW50LCB0aGlzLnJlZik7XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZUxpc3RSZW5kZXIoKTtcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgaWYgKGhhc09uQ29udGV4dENoYW5nZWQ8VD4odGhpcykpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uQ29udGV4dENoYW5nZWQodmFsdWUsIHByZXZpb3VzQ29udGV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoUGxhaXRFbGVtZW50LmlzUm9vdEVsZW1lbnQodGhpcy5lbGVtZW50KSAmJiB0aGlzLmhhc0NoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5fZyA9IGNyZWF0ZUcoKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9jb250YWluZXJHID0gY3JlYXRlRygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lckcuYXBwZW5kKHRoaXMuX2cpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9nID0gY3JlYXRlRygpO1xuICAgICAgICAgICAgICAgIHRoaXMuX2NvbnRhaW5lckcgPSB0aGlzLl9nO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgTk9ERV9UT19HLnNldCh0aGlzLmVsZW1lbnQsIHRoaXMuX2cpO1xuICAgICAgICAgICAgTk9ERV9UT19DT05UQUlORVJfRy5zZXQodGhpcy5lbGVtZW50LCB0aGlzLl9jb250YWluZXJHKTtcbiAgICAgICAgICAgIEVMRU1FTlRfVE9fUkVGLnNldCh0aGlzLmVsZW1lbnQsIHRoaXMucmVmKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGdldCBjb250ZXh0KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGV4dDtcbiAgICB9XG5cbiAgICBnZXQgZWxlbWVudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dCAmJiB0aGlzLmNvbnRleHQuZWxlbWVudDtcbiAgICB9XG5cbiAgICBnZXQgYm9hcmQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbnRleHQgJiYgdGhpcy5jb250ZXh0LmJvYXJkO1xuICAgIH1cblxuICAgIGdldCBzZWxlY3RlZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGV4dCAmJiB0aGlzLmNvbnRleHQuc2VsZWN0ZWQ7XG4gICAgfVxuXG4gICAgbGlzdFJlbmRlcj86IExpc3RSZW5kZXI7XG5cbiAgICBnZXRDb250YWluZXJHKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29udGFpbmVyRztcbiAgICB9XG5cbiAgICBnZXRFbGVtZW50RygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2c7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWY6IFIpIHt9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZWxlbWVudC50eXBlKSB7XG4gICAgICAgICAgICB0aGlzLmdldENvbnRhaW5lckcoKS5zZXRBdHRyaWJ1dGUoYHBsYWl0LSR7dGhpcy5lbGVtZW50LnR5cGV9YCwgJ3RydWUnKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5oYXNDaGlsZHJlbikge1xuICAgICAgICAgICAgaWYgKFBsYWl0RWxlbWVudC5pc1Jvb3RFbGVtZW50KHRoaXMuZWxlbWVudCkpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9yb290Q29udGFpbmVyRyA9IHRoaXMuX2NvbnRhaW5lckc7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGggPSBQbGFpdEJvYXJkLmZpbmRQYXRoKHRoaXMuYm9hcmQsIHRoaXMuZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgcm9vdE5vZGUgPSBQbGFpdE5vZGUuZ2V0KHRoaXMuYm9hcmQsIHBhdGguc2xpY2UoMCwgMSkpO1xuICAgICAgICAgICAgICAgIHRoaXMuX3Jvb3RDb250YWluZXJHID0gUGxhaXRFbGVtZW50LmdldENvbnRhaW5lckcocm9vdE5vZGUsIHsgc3VwcHJlc3NUaHJvdzogZmFsc2UgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5nZXRDb250YWluZXJHKCkuc2V0QXR0cmlidXRlKCdwbGFpdC1kYXRhLWlkJywgdGhpcy5lbGVtZW50LmlkKTtcbiAgICAgICAgdGhpcy5pbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIGluaXRpYWxpemVMaXN0UmVuZGVyKCkge1xuICAgICAgICBpZiAodGhpcy5oYXNDaGlsZHJlbikge1xuICAgICAgICAgICAgdGhpcy5saXN0UmVuZGVyID0gbmV3IExpc3RSZW5kZXIodGhpcy5ib2FyZCwgdGhpcy52aWV3Q29udGFpbmVyUmVmKTtcbiAgICAgICAgICAgIGlmICh0aGlzLmJvYXJkLmlzRXhwYW5kZWQodGhpcy5lbGVtZW50KSkge1xuICAgICAgICAgICAgICAgIHRoaXMubGlzdFJlbmRlci5pbml0aWFsaXplKHRoaXMuZWxlbWVudC5jaGlsZHJlbiEsIHRoaXMuaW5pdGlhbGl6ZUNoaWxkcmVuQ29udGV4dCgpKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXRSZWYoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlZjtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUxpc3RSZW5kZXIoKSB7XG4gICAgICAgIGlmICh0aGlzLmhhc0NoaWxkcmVuKSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMubGlzdFJlbmRlcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaW5jb3JyZWN0bHkgaW5pdGlhbGl6ZSBsaXN0IHJlbmRlcicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuYm9hcmQuaXNFeHBhbmRlZCh0aGlzLmVsZW1lbnQpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5saXN0UmVuZGVyLnVwZGF0ZSh0aGlzLmVsZW1lbnQuY2hpbGRyZW4hLCB0aGlzLmluaXRpYWxpemVDaGlsZHJlbkNvbnRleHQoKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmxpc3RSZW5kZXIuaW5pdGlhbGl6ZWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5saXN0UmVuZGVyLmRlc3Ryb3koKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRpYWxpemVDaGlsZHJlbkNvbnRleHQoKTogUGxhaXRDaGlsZHJlbkNvbnRleHQge1xuICAgICAgICBpZiAoIXRoaXMuX3Jvb3RDb250YWluZXJHKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2NhbiBub3QgcmVzb2x2ZSByb290IGNvbnRhaW5lciBnJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJvYXJkOiB0aGlzLmJvYXJkLFxuICAgICAgICAgICAgcGFyZW50OiB0aGlzLmVsZW1lbnQsXG4gICAgICAgICAgICBwYXJlbnRHOiB0aGlzLl9yb290Q29udGFpbmVyR1xuICAgICAgICB9O1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAoRUxFTUVOVF9UT19DT01QT05FTlQuZ2V0KHRoaXMuZWxlbWVudCkgPT09IHRoaXMpIHtcbiAgICAgICAgICAgIEVMRU1FTlRfVE9fQ09NUE9ORU5ULmRlbGV0ZSh0aGlzLmVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChOT0RFX1RPX0cuZ2V0KHRoaXMuZWxlbWVudCkgPT09IHRoaXMuX2cpIHtcbiAgICAgICAgICAgIE5PREVfVE9fRy5kZWxldGUodGhpcy5lbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoTk9ERV9UT19DT05UQUlORVJfRy5nZXQodGhpcy5lbGVtZW50KSA9PT0gdGhpcy5fY29udGFpbmVyRykge1xuICAgICAgICAgICAgTk9ERV9UT19DT05UQUlORVJfRy5kZWxldGUodGhpcy5lbGVtZW50KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoRUxFTUVOVF9UT19SRUYuZ2V0KHRoaXMuZWxlbWVudCkgPT09IHRoaXMucmVmKSB7XG4gICAgICAgICAgICBFTEVNRU5UX1RPX1JFRi5zZXQodGhpcy5lbGVtZW50LCB0aGlzLnJlZik7XG4gICAgICAgIH1cbiAgICAgICAgcmVtb3ZlU2VsZWN0ZWRFbGVtZW50KHRoaXMuYm9hcmQsIHRoaXMuZWxlbWVudCk7XG4gICAgICAgIHRoaXMuZ2V0Q29udGFpbmVyRygpLnJlbW92ZSgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IEVMRU1FTlRfVE9fQ09NUE9ORU5UID0gbmV3IFdlYWtNYXA8UGxhaXRFbGVtZW50LCBQbGFpdFBsdWdpbkVsZW1lbnRDb21wb25lbnQ+KCk7XG4iXX0=