@plait/core 0.52.0 → 0.54.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.
Files changed (56) hide show
  1. package/constants/cursor.d.ts +1 -0
  2. package/constants/selection.d.ts +1 -0
  3. package/esm2022/board/board.component.mjs +8 -6
  4. package/esm2022/constants/cursor.mjs +2 -1
  5. package/esm2022/constants/selection.mjs +2 -1
  6. package/esm2022/interfaces/board.mjs +5 -1
  7. package/esm2022/interfaces/path.mjs +2 -2
  8. package/esm2022/interfaces/rectangle-client.mjs +4 -1
  9. package/esm2022/interfaces/selection.mjs +2 -2
  10. package/esm2022/plugins/create-board.mjs +9 -6
  11. package/esm2022/plugins/with-hotkey.mjs +3 -3
  12. package/esm2022/plugins/with-moving.mjs +41 -21
  13. package/esm2022/plugins/with-related-fragment.mjs +20 -0
  14. package/esm2022/plugins/with-selection.mjs +37 -101
  15. package/esm2022/public-api.mjs +2 -1
  16. package/esm2022/transforms/element.mjs +2 -2
  17. package/esm2022/transforms/group.mjs +47 -0
  18. package/esm2022/transforms/index.mjs +2 -1
  19. package/esm2022/utils/angle.mjs +114 -0
  20. package/esm2022/utils/common.mjs +3 -2
  21. package/esm2022/utils/debug.mjs +91 -0
  22. package/esm2022/utils/element.mjs +17 -5
  23. package/esm2022/utils/fragment.mjs +5 -0
  24. package/esm2022/utils/group.mjs +88 -87
  25. package/esm2022/utils/helper.mjs +10 -1
  26. package/esm2022/utils/index.mjs +3 -1
  27. package/esm2022/utils/math.mjs +11 -1
  28. package/esm2022/utils/moving-snap.mjs +372 -0
  29. package/esm2022/utils/selection.mjs +90 -5
  30. package/esm2022/utils/touch.mjs +15 -4
  31. package/esm2022/utils/weak-maps.mjs +2 -1
  32. package/fesm2022/plait-core.mjs +587 -251
  33. package/fesm2022/plait-core.mjs.map +1 -1
  34. package/interfaces/board.d.ts +5 -2
  35. package/interfaces/rectangle-client.d.ts +1 -0
  36. package/interfaces/selection.d.ts +1 -1
  37. package/package.json +1 -1
  38. package/plugins/with-moving.d.ts +1 -1
  39. package/plugins/with-related-fragment.d.ts +2 -0
  40. package/public-api.d.ts +1 -0
  41. package/transforms/group.d.ts +7 -0
  42. package/transforms/index.d.ts +1 -0
  43. package/utils/angle.d.ts +18 -0
  44. package/utils/debug.d.ts +14 -0
  45. package/utils/fragment.d.ts +2 -0
  46. package/utils/group.d.ts +16 -16
  47. package/utils/helper.d.ts +2 -0
  48. package/utils/index.d.ts +2 -0
  49. package/utils/math.d.ts +8 -0
  50. package/utils/{reaction-manager.d.ts → moving-snap.d.ts} +3 -3
  51. package/utils/selection.d.ts +7 -4
  52. package/utils/touch.d.ts +1 -1
  53. package/utils/weak-maps.d.ts +1 -0
  54. package/esm2022/plugins/with-group.mjs +0 -27
  55. package/esm2022/utils/reaction-manager.mjs +0 -371
  56. package/plugins/with-group.d.ts +0 -2
@@ -29,6 +29,7 @@ export interface PlaitBoard {
29
29
  apply: (operation: PlaitOperation) => void;
30
30
  onChange: () => void;
31
31
  afterChange: () => void;
32
+ drawActiveRectangle: () => SVGGElement | null;
32
33
  mousedown: (event: MouseEvent) => void;
33
34
  mousemove: (event: MouseEvent) => void;
34
35
  mouseleave: (event: MouseEvent) => void;
@@ -40,9 +41,9 @@ export interface PlaitBoard {
40
41
  keyUp: (event: KeyboardEvent) => void;
41
42
  setFragment: (data: DataTransfer | null, clipboardContext: WritableClipboardContext | null, rectangle: RectangleClient | null, type: 'copy' | 'cut') => void;
42
43
  insertFragment: (data: DataTransfer | null, clipboardData: ClipboardData | null, targetPoint: Point) => void;
43
- deleteFragment: (data: DataTransfer | null) => void;
44
+ deleteFragment: (data: PlaitElement[]) => void;
44
45
  getDeletedFragment: (data: PlaitElement[]) => PlaitElement[];
45
- getRelatedFragment: (data: PlaitElement[]) => PlaitElement[];
46
+ getRelatedFragment: (data: PlaitElement[], originData?: PlaitElement[]) => PlaitElement[];
46
47
  dblClick: (event: MouseEvent) => void;
47
48
  drawElement: (context: PlaitPluginElementContext) => SVGGElement[] | ComponentType<PlaitPluginElementComponent>;
48
49
  redrawElement: (context: PlaitPluginElementContext, previousContext?: PlaitPluginElementContext) => SVGGElement[] | void;
@@ -59,6 +60,7 @@ export interface PlaitBoard {
59
60
  applyTheme: (element: PlaitElement) => void;
60
61
  isAlign: (element: PlaitElement) => boolean;
61
62
  isImageBindingAllowed: (element: PlaitElement) => boolean;
63
+ canAddToGroup: (element: PlaitElement) => boolean;
62
64
  pointerDown: (pointer: PointerEvent) => void;
63
65
  pointerMove: (pointer: PointerEvent) => void;
64
66
  pointerUp: (pointer: PointerEvent) => void;
@@ -87,6 +89,7 @@ export interface PlaitBoardMove {
87
89
  }
88
90
  export declare const PlaitBoard: {
89
91
  isBoard(value: any): value is PlaitBoard;
92
+ isAlive(board: PlaitBoard): boolean;
90
93
  findPath(board: PlaitBoard, node: PlaitNode): Path;
91
94
  getHost(board: PlaitBoard): SVGSVGElement;
92
95
  getElementHost(board: PlaitBoard): SVGSVGElement;
@@ -34,6 +34,7 @@ export declare const RectangleClient: {
34
34
  isEqual: (rectangle: RectangleClient, otherRectangle: RectangleClient) => boolean;
35
35
  getCornerPoints: (rectangle: RectangleClient) => [Point, Point, Point, Point];
36
36
  getCenterPoint: (rectangle: RectangleClient) => Point;
37
+ getCenterPointByPoints: (points: Point[]) => Point;
37
38
  getEdgeCenterPoints: (rectangle: RectangleClient) => [Point, Point, Point, Point];
38
39
  getConnectionPoint: (rectangle: RectangleClient, point: PointOfRectangle) => Point;
39
40
  expand(rectangle: RectangleClient, left: number, top?: number, right?: number, bottom?: number): {
@@ -1,6 +1,6 @@
1
1
  import { Point } from './point';
2
2
  export declare const SELECTION_BORDER_COLOR = "#6698FF";
3
- export declare const SELECTION_FILL_COLOR = "#6698FF19";
3
+ export declare const SELECTION_FILL_COLOR = "#6698FF25";
4
4
  export interface Selection {
5
5
  anchor: Point;
6
6
  focus: Point;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plait/core",
3
- "version": "0.52.0",
3
+ "version": "0.54.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": "^17.2.4",
6
6
  "@angular/core": "^17.2.4",
@@ -2,5 +2,5 @@ import { PlaitBoard } from '../interfaces/board';
2
2
  import { PlaitElement } from '../interfaces/element';
3
3
  export declare function withMoving(board: PlaitBoard): PlaitBoard;
4
4
  export declare function withArrowMoving(board: PlaitBoard): PlaitBoard;
5
- export declare function getTargetElements(board: PlaitBoard): PlaitElement[];
5
+ export declare function getSelectedTargetElements(board: PlaitBoard): PlaitElement[];
6
6
  export declare function updatePoints(board: PlaitBoard, targetElements: PlaitElement[], offsetX: number, offsetY: number): PlaitElement[];
@@ -0,0 +1,2 @@
1
+ import { PlaitBoard } from '../interfaces';
2
+ export declare function withRelatedFragment(board: PlaitBoard): PlaitBoard;
package/public-api.d.ts CHANGED
@@ -13,3 +13,4 @@ export * from './plugins/with-moving';
13
13
  export * from './plugins/with-options';
14
14
  export * from './testing';
15
15
  export * from './services/image-context.service';
16
+ export * from './utils/debug';
@@ -0,0 +1,7 @@
1
+ import { PlaitBoard, PlaitElement } from '../interfaces';
2
+ export declare const addGroup: (board: PlaitBoard, elements?: PlaitElement[]) => void;
3
+ export declare const removeGroup: (board: PlaitBoard, elements?: PlaitElement[]) => void;
4
+ export declare const GroupTransforms: {
5
+ addGroup: (board: PlaitBoard, elements?: PlaitElement[]) => void;
6
+ removeGroup: (board: PlaitBoard, elements?: PlaitElement[]) => void;
7
+ };
@@ -4,4 +4,5 @@ import { SelectionTransforms } from './selection';
4
4
  import { ViewportTransforms } from './viewport';
5
5
  export { BoardTransforms } from './board';
6
6
  export { CoreTransforms } from './element';
7
+ export { GroupTransforms } from './group';
7
8
  export declare const Transforms: GeneralTransforms & ViewportTransforms & SelectionTransforms & NodeTransforms;
@@ -0,0 +1,18 @@
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;
4
+ export declare const hasSameAngle: (elements: PlaitElement[]) => boolean;
5
+ export declare const getRotatedBoundingRectangle: (rectanglesCornerPoints: [Point, Point, Point, Point][], angle: number) => RectangleClient;
6
+ export declare const getOffsetAfterRotate: (rectangle: RectangleClient, rotateCenterPoint: Point, angle: number) => {
7
+ offsetX: number;
8
+ offsetY: number;
9
+ };
10
+ export declare const rotatedDataPoints: (points: Point[], rotateCenterPoint: Point, angle: number) => Point[];
11
+ export declare const hasValidAngle: (node: PlaitElement) => any;
12
+ export declare const rotatePointsByElement: <T>(points: T, element: PlaitElement) => T | null;
13
+ export declare const rotateAntiPointsByElement: <T>(points: T, element: PlaitElement) => T | null;
14
+ export declare const getRectangleByAngle: (rectangle: RectangleClient, angle: number) => RectangleClient | null;
15
+ export declare const isAxisChangedByAngle: (angle: number) => boolean;
16
+ export declare function degreesToRadians(d: number): number;
17
+ export declare function radiansToDegrees(r: number): number;
18
+ export declare function rotateElements(board: PlaitBoard, elements: PlaitElement[], angle: number): void;
@@ -0,0 +1,14 @@
1
+ import { Options } from 'roughjs/bin/core';
2
+ import { PlaitBoard, Point, RectangleClient } from '../interfaces';
3
+ export declare class DebugGenerator {
4
+ private debugKey;
5
+ constructor(debugKey: string);
6
+ isDebug(): boolean;
7
+ clear(): void;
8
+ drawPolygon(board: PlaitBoard, points: Point[], options?: Options): SVGGElement | undefined;
9
+ drawLine(board: PlaitBoard, points: Point[], options?: Options): SVGGElement | undefined;
10
+ drawRectangle(board: PlaitBoard, data: Point[] | RectangleClient, options?: Options): SVGGElement | undefined;
11
+ drawCircles(board: PlaitBoard, points: Point[], diameter?: number, isCumulativeDiameter?: boolean, options?: Options): SVGGElement[] | undefined;
12
+ }
13
+ export declare const createDebugGenerator: (debugKey: string) => DebugGenerator;
14
+ export declare const isDebug: (key?: string) => boolean;
@@ -0,0 +1,2 @@
1
+ import { PlaitBoard } from "../interfaces";
2
+ export declare const deleteFragment: (board: PlaitBoard) => void;
package/utils/group.d.ts CHANGED
@@ -1,22 +1,22 @@
1
- import { PlaitBoard, PlaitElement } from '../interfaces';
2
- import { PlaitGroup } from '../interfaces/group';
1
+ import { PlaitBoard, PlaitElement, PlaitGroup, RectangleClient } from '../interfaces';
3
2
  export declare const getElementsInGroup: (board: PlaitBoard, group: PlaitGroup, recursion?: boolean, includeGroup?: boolean) => PlaitElement[];
4
- export declare const getRectangleByGroup: (board: PlaitBoard, group: PlaitGroup, recursion?: boolean) => import("../interfaces").RectangleClient;
5
- export declare const getGroupByElement: (board: PlaitBoard, element: PlaitElement, recursion?: boolean) => PlaitGroup | PlaitGroup[] | null;
3
+ export declare const getAllElementsInGroup: (board: PlaitBoard, group: PlaitGroup, recursion?: boolean, includeGroup?: boolean) => PlaitElement[];
4
+ export declare const getRectangleByGroup: (board: PlaitBoard, group: PlaitGroup, recursion?: boolean) => RectangleClient;
5
+ export declare const getGroupByElement: (board: PlaitBoard, element: PlaitElement, recursion?: boolean, source?: PlaitElement[]) => PlaitGroup | PlaitGroup[] | null;
6
6
  export declare const getHighestGroup: (board: PlaitBoard, element: PlaitElement) => PlaitGroup | null;
7
7
  export declare const getElementsInGroupByElement: (board: PlaitBoard, element: PlaitElement) => PlaitElement[];
8
- export declare const isSelectedElementOrGroup: (board: PlaitBoard, element: PlaitElement) => boolean;
9
- export declare const isSelectedAllElementsInGroup: (board: PlaitBoard, group: PlaitGroup) => boolean;
10
- export declare const getSelectedGroups: (board: PlaitBoard, groups: PlaitGroup[]) => PlaitGroup[];
11
- export declare const getHighestSelectedGroup: (board: PlaitBoard, element: PlaitElement) => PlaitGroup | null;
12
- export declare const getHighestSelectedGroups: (board: PlaitBoard) => PlaitGroup[];
13
- export declare const getSelectedIsolatedElements: (board: PlaitBoard) => PlaitElement[];
14
- export declare const getHighestSelectedElements: (board: PlaitBoard) => PlaitElement[];
8
+ export declare const isSelectedElementOrGroup: (board: PlaitBoard, element: PlaitElement, elements?: PlaitElement[]) => boolean;
9
+ export declare const isSelectedAllElementsInGroup: (board: PlaitBoard, group: PlaitGroup, elements?: PlaitElement[]) => boolean;
10
+ export declare const filterSelectedGroups: (board: PlaitBoard, groups: PlaitGroup[], elements?: PlaitElement[]) => PlaitGroup[];
11
+ export declare const getSelectedGroups: (board: PlaitBoard, elements?: PlaitElement[]) => PlaitGroup[];
12
+ export declare const getHighestSelectedGroup: (board: PlaitBoard, element: PlaitElement, elements?: PlaitElement[]) => PlaitGroup | null;
13
+ export declare const getHighestSelectedGroups: (board: PlaitBoard, elements?: PlaitElement[]) => PlaitGroup[];
14
+ export declare const getSelectedIsolatedElements: (board: PlaitBoard, elements?: PlaitElement[]) => PlaitElement[];
15
+ export declare const getSelectedIsolatedElementsCanAddToGroup: (board: PlaitBoard, elements?: PlaitElement[]) => PlaitElement[];
16
+ export declare const getHighestSelectedElements: (board: PlaitBoard, elements?: PlaitElement[]) => PlaitElement[];
15
17
  export declare const createGroupRectangleG: (board: PlaitBoard, elements: PlaitElement[]) => SVGGElement | null;
16
- export declare const createGroup: () => PlaitGroup;
18
+ export declare const createGroup: (groupId?: string) => PlaitGroup;
17
19
  export declare const nonGroupInHighestSelectedElements: (elements: PlaitElement[]) => boolean;
18
20
  export declare const hasSelectedElementsInSameGroup: (elements: PlaitElement[]) => boolean;
19
- export declare const canAddGroup: (highestSelectedElements: PlaitElement[]) => boolean;
20
- export declare const addGroup: (board: PlaitBoard) => void;
21
- export declare const canRemoveGroup: (board: PlaitBoard, selectedGroups: PlaitGroup[]) => boolean;
22
- export declare const removeGroup: (board: PlaitBoard) => void;
21
+ export declare const canAddGroup: (board: PlaitBoard, elements?: PlaitElement[]) => boolean;
22
+ export declare const canRemoveGroup: (board: PlaitBoard, elements?: PlaitElement[]) => boolean;
package/utils/helper.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { PlaitElement } from "../interfaces";
1
2
  export declare function isNullOrUndefined(value: any): boolean;
2
3
  /**
3
4
  * get {x,y} point
@@ -10,3 +11,4 @@ export declare function normalizePoint(point: number[]): {
10
11
  };
11
12
  export declare const RgbaToHEX: (Rgb: string, opacity: number) => string;
12
13
  export declare function isContextmenu(event: MouseEvent): boolean;
14
+ export declare function uniqueById(elements: PlaitElement[]): any[];
package/utils/index.d.ts CHANGED
@@ -27,3 +27,5 @@ export * from './dnd';
27
27
  export * from './to-point';
28
28
  export * from './group';
29
29
  export * from './selection';
30
+ export * from './angle';
31
+ export * from './fragment';
package/utils/math.d.ts CHANGED
@@ -27,3 +27,11 @@ export declare function getVectorFromPointAndSlope(x: number, y: number, slope:
27
27
  */
28
28
  export declare function toDomPrecision(v: number): number;
29
29
  export declare function toFixed(v: number): number;
30
+ /**
31
+ * Whether two numbers numbers a and b are approximately equal.
32
+ *
33
+ * @param a - The first point.
34
+ * @param b - The second point.
35
+ * @public
36
+ */
37
+ export declare function approximately(a: number, b: number, precision?: number): boolean;
@@ -1,7 +1,7 @@
1
1
  import { PlaitBoard } from '../interfaces/board';
2
2
  import { PlaitElement } from '../interfaces/element';
3
3
  import { Point, RectangleClient } from '../interfaces';
4
- export interface AlignRef {
4
+ export interface SnapRef {
5
5
  deltaX: number;
6
6
  deltaY: number;
7
7
  g: SVGGElement;
@@ -16,14 +16,14 @@ export interface DistributeRef {
16
16
  index: number;
17
17
  }[];
18
18
  }
19
- export declare class AlignReaction {
19
+ export declare class MovingSnapReaction {
20
20
  private board;
21
21
  private activeElements;
22
22
  private activeRectangle;
23
23
  alignRectangles: RectangleClient[];
24
24
  constructor(board: PlaitBoard, activeElements: PlaitElement[], activeRectangle: RectangleClient);
25
25
  getAlignRectangle(): RectangleClient[];
26
- handleAlign(): AlignRef;
26
+ handleSnapping(): SnapRef;
27
27
  calculateClosestDistances(activeRectangle: RectangleClient, alignRectangle: RectangleClient): {
28
28
  absXDistance: number;
29
29
  xDistance: number;
@@ -1,13 +1,16 @@
1
- import { PlaitBoard } from '../interfaces';
1
+ import { PlaitBoard, PlaitElement, PlaitGroup } from '../interfaces';
2
2
  export declare function isSelectionMoving(board: PlaitBoard): boolean;
3
3
  export declare function setSelectionMoving(board: PlaitBoard): void;
4
4
  export declare function clearSelectionMoving(board: PlaitBoard): void;
5
5
  export declare function isHandleSelection(board: PlaitBoard): boolean;
6
6
  export declare function isSetSelectionOperation(board: PlaitBoard): boolean;
7
- export declare function getTemporaryElements(board: PlaitBoard): import("../interfaces").PlaitElement[] | undefined;
7
+ export declare function getTemporaryElements(board: PlaitBoard): PlaitElement[] | undefined;
8
8
  export declare function getTemporaryRef(board: PlaitBoard): {
9
- elements: import("../interfaces").PlaitElement[];
9
+ elements: PlaitElement[];
10
10
  timeoutId: any;
11
11
  } | undefined;
12
12
  export declare function deleteTemporaryElements(board: PlaitBoard): void;
13
- export declare function createSelectionRectangleG(board: PlaitBoard): SVGGElement | null;
13
+ export declare function drawEntireActiveRectangleG(board: PlaitBoard): SVGGElement | null;
14
+ export declare function setSelectedElementsWithGroup(board: PlaitBoard, elements: PlaitElement[], isShift: boolean): void;
15
+ export declare function cacheSelectedElementsWithGroupOnShift(board: PlaitBoard, elements: PlaitElement[], isSelectGroupElement: boolean, elementsInHighestGroup: PlaitElement[]): void;
16
+ export declare function cacheSelectedElementsWithGroup(board: PlaitBoard, elements: PlaitElement[], isSelectGroupElement: boolean, hitElementGroups: PlaitGroup[]): void;
package/utils/touch.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { PlaitBoard } from '../interfaces/board';
2
2
  export interface TouchRef {
3
- target?: SVGElement;
3
+ target?: HTMLElement | SVGElement;
4
4
  state: boolean;
5
5
  host?: SVGGElement;
6
6
  }
@@ -15,6 +15,7 @@ export declare const BOARD_TO_AFTER_CHANGE: WeakMap<PlaitBoard, () => void>;
15
15
  export declare const BOARD_TO_COMPONENT: WeakMap<PlaitBoard, BoardComponentInterface>;
16
16
  export declare const BOARD_TO_ROUGH_SVG: WeakMap<PlaitBoard, RoughSVG>;
17
17
  export declare const BOARD_TO_HOST: WeakMap<PlaitBoard, SVGSVGElement>;
18
+ export declare const IS_BOARD_ALIVE: WeakMap<PlaitBoard, boolean>;
18
19
  export declare const BOARD_TO_ELEMENT_HOST: WeakMap<PlaitBoard, {
19
20
  host: SVGGElement;
20
21
  upperHost: SVGGElement;
@@ -1,27 +0,0 @@
1
- import { PlaitBoard, Selection } from '../interfaces';
2
- import { createGroupRectangleG, toViewBoxPoint, toHostPoint, getHitElementsBySelection } from '../utils';
3
- export function withGroup(board) {
4
- const { pointerMove, globalPointerUp } = board;
5
- let groupRectangleG;
6
- board.pointerMove = (event) => {
7
- groupRectangleG?.remove();
8
- const point = toViewBoxPoint(board, toHostPoint(board, event.x, event.y));
9
- let selection = { anchor: point, focus: point };
10
- if (board.selection && !Selection.isCollapsed(board.selection)) {
11
- selection = board.selection;
12
- }
13
- const hitElements = getHitElementsBySelection(board, selection);
14
- if (hitElements.length) {
15
- groupRectangleG = createGroupRectangleG(board, hitElements);
16
- groupRectangleG && PlaitBoard.getElementActiveHost(board).append(groupRectangleG);
17
- }
18
- pointerMove(event);
19
- };
20
- board.globalPointerUp = (event) => {
21
- groupRectangleG?.remove();
22
- groupRectangleG = null;
23
- globalPointerUp(event);
24
- };
25
- return board;
26
- }
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1ncm91cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL3BsdWdpbnMvd2l0aC1ncm91cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0RCxPQUFPLEVBQ0gscUJBQXFCLEVBQ3JCLGNBQWMsRUFDZCxXQUFXLEVBQ1gseUJBQXlCLEVBQzVCLE1BQU0sVUFBVSxDQUFDO0FBRWxCLE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBaUI7SUFDdkMsTUFBTSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsR0FBRyxLQUFLLENBQUM7SUFDL0MsSUFBSSxlQUFtQyxDQUFDO0lBRXhDLEtBQUssQ0FBQyxXQUFXLEdBQUcsQ0FBQyxLQUFtQixFQUFFLEVBQUU7UUFDeEMsZUFBZSxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQzFCLE1BQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFFLElBQUksU0FBUyxHQUFjLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7UUFDM0QsSUFBSSxLQUFLLENBQUMsU0FBUyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUM3RCxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUNoQyxDQUFDO1FBQ0QsTUFBTSxXQUFXLEdBQUcseUJBQXlCLENBQUMsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ2hFLElBQUksV0FBVyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3JCLGVBQWUsR0FBRyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDNUQsZUFBZSxJQUFJLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDdEYsQ0FBQztRQUVELFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QixDQUFDLENBQUM7SUFFRixLQUFLLENBQUMsZUFBZSxHQUFHLENBQUMsS0FBbUIsRUFBRSxFQUFFO1FBQzVDLGVBQWUsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUMxQixlQUFlLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixDQUFDLENBQUM7SUFFRixPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUGxhaXRCb2FyZCwgU2VsZWN0aW9uIH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQge1xuICAgIGNyZWF0ZUdyb3VwUmVjdGFuZ2xlRyxcbiAgICB0b1ZpZXdCb3hQb2ludCxcbiAgICB0b0hvc3RQb2ludCxcbiAgICBnZXRIaXRFbGVtZW50c0J5U2VsZWN0aW9uXG59IGZyb20gJy4uL3V0aWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhHcm91cChib2FyZDogUGxhaXRCb2FyZCkge1xuICAgIGNvbnN0IHsgcG9pbnRlck1vdmUsIGdsb2JhbFBvaW50ZXJVcCB9ID0gYm9hcmQ7XG4gICAgbGV0IGdyb3VwUmVjdGFuZ2xlRzogU1ZHR0VsZW1lbnQgfCBudWxsO1xuXG4gICAgYm9hcmQucG9pbnRlck1vdmUgPSAoZXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgICBncm91cFJlY3RhbmdsZUc/LnJlbW92ZSgpO1xuICAgICAgICBjb25zdCBwb2ludCA9IHRvVmlld0JveFBvaW50KGJvYXJkLCB0b0hvc3RQb2ludChib2FyZCwgZXZlbnQueCwgZXZlbnQueSkpO1xuICAgICAgICBsZXQgc2VsZWN0aW9uOiBTZWxlY3Rpb24gPSB7IGFuY2hvcjogcG9pbnQsIGZvY3VzOiBwb2ludCB9O1xuICAgICAgICBpZiAoYm9hcmQuc2VsZWN0aW9uICYmICFTZWxlY3Rpb24uaXNDb2xsYXBzZWQoYm9hcmQuc2VsZWN0aW9uKSkge1xuICAgICAgICAgICAgc2VsZWN0aW9uID0gYm9hcmQuc2VsZWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhpdEVsZW1lbnRzID0gZ2V0SGl0RWxlbWVudHNCeVNlbGVjdGlvbihib2FyZCwgc2VsZWN0aW9uKTtcbiAgICAgICAgaWYgKGhpdEVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgZ3JvdXBSZWN0YW5nbGVHID0gY3JlYXRlR3JvdXBSZWN0YW5nbGVHKGJvYXJkLCBoaXRFbGVtZW50cyk7XG4gICAgICAgICAgICBncm91cFJlY3RhbmdsZUcgJiYgUGxhaXRCb2FyZC5nZXRFbGVtZW50QWN0aXZlSG9zdChib2FyZCkuYXBwZW5kKGdyb3VwUmVjdGFuZ2xlRyk7XG4gICAgICAgIH1cblxuICAgICAgICBwb2ludGVyTW92ZShldmVudCk7XG4gICAgfTtcblxuICAgIGJvYXJkLmdsb2JhbFBvaW50ZXJVcCA9IChldmVudDogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICAgIGdyb3VwUmVjdGFuZ2xlRz8ucmVtb3ZlKCk7XG4gICAgICAgIGdyb3VwUmVjdGFuZ2xlRyA9IG51bGw7XG4gICAgICAgIGdsb2JhbFBvaW50ZXJVcChldmVudCk7XG4gICAgfTtcblxuICAgIHJldHVybiBib2FyZDtcbn1cbiJdfQ==