angular-three-soba 2.0.0 → 2.2.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 (72) hide show
  1. package/abstractions/lib/catmull-rom-line.d.ts +148 -148
  2. package/abstractions/lib/edges.d.ts +166 -166
  3. package/abstractions/lib/grid.d.ts +30 -30
  4. package/abstractions/lib/line.d.ts +2 -2
  5. package/abstractions/lib/prism-geometry.d.ts +4 -4
  6. package/abstractions/lib/rounded-box.d.ts +1 -1
  7. package/abstractions/lib/text-3d.d.ts +37 -37
  8. package/abstractions/lib/text.d.ts +2 -2
  9. package/cameras/lib/cube-camera.d.ts +1 -1
  10. package/cameras/lib/orthographic-camera.d.ts +1 -1
  11. package/cameras/lib/perspective-camera.d.ts +1 -1
  12. package/controls/index.d.ts +9 -1
  13. package/controls/lib/camera-controls.d.ts +1 -1
  14. package/controls/lib/orbit-controls.d.ts +1 -1
  15. package/esm2022/controls/index.mjs +6 -2
  16. package/esm2022/gizmos/angular-three-soba-gizmos.mjs +5 -0
  17. package/esm2022/gizmos/index.mjs +6 -0
  18. package/esm2022/gizmos/lib/gizmo-helper/gizmo-helper.mjs +187 -0
  19. package/esm2022/gizmos/lib/gizmo-helper/gizmo-viewcube.mjs +304 -0
  20. package/esm2022/gizmos/lib/gizmo-helper/gizmo-viewport.mjs +332 -0
  21. package/esm2022/gizmos/lib/pivot-controls/axis-arrow.mjs +263 -0
  22. package/esm2022/gizmos/lib/pivot-controls/axis-rotator.mjs +264 -0
  23. package/esm2022/gizmos/lib/pivot-controls/pivot-controls.mjs +340 -0
  24. package/esm2022/gizmos/lib/pivot-controls/plane-slider.mjs +266 -0
  25. package/esm2022/gizmos/lib/pivot-controls/scaling-sphere.mjs +232 -0
  26. package/esm2022/gizmos/lib/transform-controls.mjs +177 -0
  27. package/esm2022/staging/index.mjs +2 -1
  28. package/esm2022/staging/lib/mask.mjs +78 -0
  29. package/fesm2022/angular-three-soba-controls.mjs +14 -1337
  30. package/fesm2022/angular-three-soba-controls.mjs.map +1 -1
  31. package/fesm2022/angular-three-soba-gizmos.mjs +2319 -0
  32. package/fesm2022/angular-three-soba-gizmos.mjs.map +1 -0
  33. package/fesm2022/angular-three-soba-staging.mjs +92 -21
  34. package/fesm2022/angular-three-soba-staging.mjs.map +1 -1
  35. package/gizmos/README.md +3 -0
  36. package/gizmos/index.d.ts +5 -0
  37. package/gizmos/lib/gizmo-helper/gizmo-helper.d.ts +45 -0
  38. package/gizmos/lib/gizmo-helper/gizmo-viewcube.d.ts +74 -0
  39. package/gizmos/lib/gizmo-helper/gizmo-viewport.d.ts +64 -0
  40. package/{controls → gizmos}/lib/pivot-controls/pivot-controls.d.ts +1 -1
  41. package/gizmos/lib/transform-controls.d.ts +50 -0
  42. package/materials/lib/custom-shader-material.d.ts +3 -3
  43. package/materials/lib/mesh-refraction-material.d.ts +3 -3
  44. package/materials/lib/mesh-transmission-material.d.ts +1 -1
  45. package/misc/lib/computed-attribute.d.ts +5 -5
  46. package/misc/lib/decal.d.ts +1 -1
  47. package/misc/lib/html/html.d.ts +1 -1
  48. package/misc/lib/sampler.d.ts +1 -1
  49. package/package.json +18 -12
  50. package/performances/lib/instances/instances.d.ts +9 -9
  51. package/performances/lib/points/points.d.ts +20 -20
  52. package/performances/lib/segments/segments.d.ts +4 -4
  53. package/shaders/lib/mesh-refraction-material.d.ts +2 -2
  54. package/staging/index.d.ts +1 -0
  55. package/staging/lib/caustics.d.ts +1 -1
  56. package/staging/lib/center.d.ts +2 -2
  57. package/staging/lib/contact-shadows.d.ts +1 -1
  58. package/staging/lib/lightformer.d.ts +1 -1
  59. package/staging/lib/mask.d.ts +30 -0
  60. package/staging/lib/render-texture.d.ts +1 -1
  61. package/staging/lib/sky.d.ts +1 -1
  62. package/staging/lib/spot-light.d.ts +2 -2
  63. package/staging/lib/stage.d.ts +6 -6
  64. package/esm2022/controls/lib/pivot-controls/axis-arrow.mjs +0 -263
  65. package/esm2022/controls/lib/pivot-controls/axis-rotator.mjs +0 -264
  66. package/esm2022/controls/lib/pivot-controls/pivot-controls.mjs +0 -340
  67. package/esm2022/controls/lib/pivot-controls/plane-slider.mjs +0 -266
  68. package/esm2022/controls/lib/pivot-controls/scaling-sphere.mjs +0 -232
  69. /package/{controls → gizmos}/lib/pivot-controls/axis-arrow.d.ts +0 -0
  70. /package/{controls → gizmos}/lib/pivot-controls/axis-rotator.d.ts +0 -0
  71. /package/{controls → gizmos}/lib/pivot-controls/plane-slider.d.ts +0 -0
  72. /package/{controls → gizmos}/lib/pivot-controls/scaling-sphere.d.ts +0 -0
@@ -1,266 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, input, signal, viewChild, } from '@angular/core';
2
- import { extend, injectStore } from 'angular-three';
3
- import { NgtsLine } from 'angular-three-soba/abstractions';
4
- import { NgtsHTML, NgtsHTMLContent } from 'angular-three-soba/misc';
5
- import { DoubleSide, Group, Matrix4, Mesh, MeshBasicMaterial, Plane, PlaneGeometry, Ray, Vector3 } from 'three';
6
- import { NgtsPivotControls } from './pivot-controls';
7
- import * as i0 from "@angular/core";
8
- function decomposeIntoBasis(e1, e2, offset) {
9
- const i1 = Math.abs(e1.x) >= Math.abs(e1.y) && Math.abs(e1.x) >= Math.abs(e1.z)
10
- ? 0
11
- : Math.abs(e1.y) >= Math.abs(e1.x) && Math.abs(e1.y) >= Math.abs(e1.z)
12
- ? 1
13
- : 2;
14
- const e2DegrowthOrder = [0, 1, 2].sort((a, b) => Math.abs(e2.getComponent(b)) - Math.abs(e2.getComponent(a)));
15
- const i2 = i1 === e2DegrowthOrder[0] ? e2DegrowthOrder[1] : e2DegrowthOrder[0];
16
- const a1 = e1.getComponent(i1);
17
- const a2 = e1.getComponent(i2);
18
- const b1 = e2.getComponent(i1);
19
- const b2 = e2.getComponent(i2);
20
- const c1 = offset.getComponent(i1);
21
- const c2 = offset.getComponent(i2);
22
- const y = (c2 - c1 * (a2 / a1)) / (b2 - b1 * (a2 / a1));
23
- const x = (c1 - y * b1) / a1;
24
- return [x, y];
25
- }
26
- const ray = new Ray();
27
- const intersection = new Vector3();
28
- const offsetMatrix = new Matrix4();
29
- export class NgtsPlaneSlider {
30
- constructor() {
31
- this.DoubleSide = DoubleSide;
32
- this.dir1 = input.required();
33
- this.dir2 = input.required();
34
- this.axis = input.required();
35
- this.groupRef = viewChild.required('group');
36
- this.annotationRef = viewChild('annotation', { read: ElementRef });
37
- this.pivotControls = inject(NgtsPivotControls);
38
- this.store = injectStore();
39
- this.controls = this.store.select('controls');
40
- this.hovered = signal(false);
41
- this.clickInfo = null;
42
- this.offsetX0 = 0;
43
- this.offsetY0 = 0;
44
- this.matrixL = computed(() => {
45
- const dir1N = this.dir1().clone().normalize();
46
- const dir2N = this.dir2().clone().normalize();
47
- return new Matrix4().makeBasis(dir1N, dir2N, dir1N.clone().cross(dir2N));
48
- });
49
- this.pos1 = computed(() => (this.pivotControls.fixed() ? 1 / 7 : this.pivotControls.scale() / 7));
50
- this.length = computed(() => (this.pivotControls.fixed() ? 0.225 : this.pivotControls.scale() * 0.225));
51
- this.color = computed(() => this.hovered() ? this.pivotControls.hoveredColor() : this.pivotControls.axisColors()[this.axis()]);
52
- this.points = computed(() => {
53
- const length = this.length();
54
- return [
55
- new Vector3(0, 0, 0),
56
- new Vector3(0, length, 0),
57
- new Vector3(length, length, 0),
58
- new Vector3(length, 0, 0),
59
- new Vector3(0, 0, 0),
60
- ];
61
- });
62
- extend({ Group, Mesh, PlaneGeometry, MeshBasicMaterial });
63
- }
64
- onPointerDown(event) {
65
- const [annotation, axis, group, controls] = [
66
- this.annotationRef()?.nativeElement,
67
- this.axis(),
68
- this.groupRef().nativeElement,
69
- this.controls(),
70
- ];
71
- if (annotation) {
72
- annotation.innerText = `${this.pivotControls.translation[(axis + 1) % 3].toFixed(2)}, ${this.pivotControls.translation[(axis + 2) % 3].toFixed(2)}`;
73
- annotation.style.display = 'block';
74
- }
75
- event.stopPropagation();
76
- const clickPoint = event.point.clone();
77
- const origin = new Vector3().setFromMatrixPosition(group.matrixWorld);
78
- const e1 = new Vector3().setFromMatrixColumn(group.matrixWorld, 0).normalize();
79
- const e2 = new Vector3().setFromMatrixColumn(group.matrixWorld, 1).normalize();
80
- const normal = new Vector3().setFromMatrixColumn(group.matrixWorld, 2).normalize();
81
- const plane = new Plane().setFromNormalAndCoplanarPoint(normal, origin);
82
- this.clickInfo = { clickPoint, e1, e2, plane };
83
- this.offsetX0 = this.pivotControls.translation[(axis + 1) % 3];
84
- this.offsetY0 = this.pivotControls.translation[(axis + 2) % 3];
85
- this.pivotControls.onDragStart({ component: 'Slider', axis, origin, directions: [e1, e2, normal] });
86
- if (controls) {
87
- controls.enabled = false;
88
- }
89
- // @ts-expect-error - setPointerCapture is not defined on ThreeEvent
90
- event.target.setPointerCapture(event.pointerId);
91
- }
92
- onPointerMove(event) {
93
- event.stopPropagation();
94
- if (!this.hovered())
95
- this.hovered.set(true);
96
- if (this.clickInfo) {
97
- const { clickPoint, e1, e2, plane } = this.clickInfo;
98
- const [translationLimits, axis, annotation] = [
99
- this.pivotControls.translationLimits(),
100
- this.axis(),
101
- this.annotationRef()?.nativeElement,
102
- ];
103
- const [minX, maxX] = translationLimits?.[(axis + 1) % 3] || [undefined, undefined];
104
- const [minY, maxY] = translationLimits?.[(axis + 2) % 3] || [undefined, undefined];
105
- ray.copy(event.ray);
106
- ray.intersectPlane(plane, intersection);
107
- ray.direction.negate();
108
- ray.intersectPlane(plane, intersection);
109
- intersection.sub(clickPoint);
110
- let [offsetX, offsetY] = decomposeIntoBasis(e1, e2, intersection);
111
- /* let offsetY = (intersection.y - (intersection.x * e1.y) / e1.x) / (e2.y - (e2.x * e1.y) / e1.x)
112
- let offsetX = (intersection.x - offsetY * e2.x) / e1.x */
113
- if (minX !== undefined) {
114
- offsetX = Math.max(offsetX, minX - this.offsetX0);
115
- }
116
- if (maxX !== undefined) {
117
- offsetX = Math.min(offsetX, maxX - this.offsetX0);
118
- }
119
- if (minY !== undefined) {
120
- offsetY = Math.max(offsetY, minY - this.offsetY0);
121
- }
122
- if (maxY !== undefined) {
123
- offsetY = Math.min(offsetY, maxY - this.offsetY0);
124
- }
125
- this.pivotControls.translation[(axis + 1) % 3] = this.offsetX0 + offsetX;
126
- this.pivotControls.translation[(axis + 2) % 3] = this.offsetY0 + offsetY;
127
- if (annotation) {
128
- annotation.innerText = `${this.pivotControls.translation[(axis + 1) % 3].toFixed(2)}, ${this.pivotControls.translation[(axis + 2) % 3].toFixed(2)}`;
129
- }
130
- offsetMatrix.makeTranslation(offsetX * e1.x + offsetY * e2.x, offsetX * e1.y + offsetY * e2.y, offsetX * e1.z + offsetY * e2.z);
131
- this.pivotControls.onDrag(offsetMatrix);
132
- }
133
- }
134
- onPointerUp(event) {
135
- const [annotation, controls] = [this.annotationRef()?.nativeElement, this.controls()];
136
- if (annotation) {
137
- annotation.style.display = 'none';
138
- }
139
- event.stopPropagation();
140
- this.clickInfo = null;
141
- this.pivotControls.onDragEnd();
142
- if (controls) {
143
- controls.enabled = true;
144
- }
145
- // @ts-expect-error - releasePointerCapture is not defined on ThreeEvent
146
- event.target.releasePointerCapture(event.pointerId);
147
- }
148
- onPointerOut(event) {
149
- event.stopPropagation();
150
- this.hovered.set(false);
151
- }
152
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtsPlaneSlider, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
153
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: NgtsPlaneSlider, isStandalone: true, selector: "ngts-plane-slider", inputs: { dir1: { classPropertyName: "dir1", publicName: "dir1", isSignal: true, isRequired: true, transformFunction: null }, dir2: { classPropertyName: "dir2", publicName: "dir2", isSignal: true, isRequired: true, transformFunction: null }, axis: { classPropertyName: "axis", publicName: "axis", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "groupRef", first: true, predicate: ["group"], descendants: true, isSignal: true }, { propertyName: "annotationRef", first: true, predicate: ["annotation"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: `
154
- <ngt-group #group [matrix]="matrixL()" [matrixAutoUpdate]="false">
155
- @if (pivotControls.annotations()) {
156
- <ngts-html [options]="{ position: [0, 0, 0] }">
157
- <div
158
- #annotation
159
- ngtsHTMLContent
160
- style="display: none; background: #151520; color: white; padding: 6px 8px; border-radius: 7px; white-space: nowrap"
161
- [class]="pivotControls.annotationsClass()"
162
- ></div>
163
- </ngts-html>
164
- }
165
- <ngt-group [position]="[pos1() * 1.7, pos1() * 1.7, 0]">
166
- <ngt-mesh
167
- [visible]="true"
168
- [scale]="length()"
169
- [userData]="pivotControls.userData()"
170
- (pointerdown)="onPointerDown($any($event))"
171
- (pointermove)="onPointerMove($any($event))"
172
- (pointerup)="onPointerUp($any($event))"
173
- (pointerout)="onPointerOut($any($event))"
174
- >
175
- <ngt-plane-geometry />
176
- <ngt-mesh-basic-material
177
- [transparent]="true"
178
- [depthTest]="pivotControls.depthTest()"
179
- [color]="color()"
180
- [polygonOffset]="true"
181
- [polygonOffsetFactor]="-10"
182
- [side]="DoubleSide"
183
- [fog]="false"
184
- />
185
- </ngt-mesh>
186
- <ngts-line
187
- [points]="points()"
188
- [options]="{
189
- position: [-length() / 2, -length() / 2, 0],
190
- transparent: true,
191
- depthTest: pivotControls.depthTest(),
192
- lineWidth: pivotControls.lineWidth(),
193
- color: color(),
194
- opacity: pivotControls.opacity(),
195
- polygonOffset: true,
196
- polygonOffsetFactor: -10,
197
- userData: pivotControls.userData(),
198
- fog: false,
199
- }"
200
- />
201
- </ngt-group>
202
- </ngt-group>
203
- `, isInline: true, dependencies: [{ kind: "component", type: NgtsHTML, selector: "ngts-html", inputs: ["options"] }, { kind: "component", type: NgtsHTMLContent, selector: "[ngtsHTMLContent]", inputs: ["ngtsHTMLContent"], outputs: ["occluded"] }, { kind: "component", type: NgtsLine, selector: "ngts-line", inputs: ["points", "options"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
204
- }
205
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtsPlaneSlider, decorators: [{
206
- type: Component,
207
- args: [{
208
- selector: 'ngts-plane-slider',
209
- standalone: true,
210
- template: `
211
- <ngt-group #group [matrix]="matrixL()" [matrixAutoUpdate]="false">
212
- @if (pivotControls.annotations()) {
213
- <ngts-html [options]="{ position: [0, 0, 0] }">
214
- <div
215
- #annotation
216
- ngtsHTMLContent
217
- style="display: none; background: #151520; color: white; padding: 6px 8px; border-radius: 7px; white-space: nowrap"
218
- [class]="pivotControls.annotationsClass()"
219
- ></div>
220
- </ngts-html>
221
- }
222
- <ngt-group [position]="[pos1() * 1.7, pos1() * 1.7, 0]">
223
- <ngt-mesh
224
- [visible]="true"
225
- [scale]="length()"
226
- [userData]="pivotControls.userData()"
227
- (pointerdown)="onPointerDown($any($event))"
228
- (pointermove)="onPointerMove($any($event))"
229
- (pointerup)="onPointerUp($any($event))"
230
- (pointerout)="onPointerOut($any($event))"
231
- >
232
- <ngt-plane-geometry />
233
- <ngt-mesh-basic-material
234
- [transparent]="true"
235
- [depthTest]="pivotControls.depthTest()"
236
- [color]="color()"
237
- [polygonOffset]="true"
238
- [polygonOffsetFactor]="-10"
239
- [side]="DoubleSide"
240
- [fog]="false"
241
- />
242
- </ngt-mesh>
243
- <ngts-line
244
- [points]="points()"
245
- [options]="{
246
- position: [-length() / 2, -length() / 2, 0],
247
- transparent: true,
248
- depthTest: pivotControls.depthTest(),
249
- lineWidth: pivotControls.lineWidth(),
250
- color: color(),
251
- opacity: pivotControls.opacity(),
252
- polygonOffset: true,
253
- polygonOffsetFactor: -10,
254
- userData: pivotControls.userData(),
255
- fog: false,
256
- }"
257
- />
258
- </ngt-group>
259
- </ngt-group>
260
- `,
261
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
262
- changeDetection: ChangeDetectionStrategy.OnPush,
263
- imports: [NgtsHTML, NgtsHTMLContent, NgtsLine],
264
- }]
265
- }], ctorParameters: () => [] });
266
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbmUtc2xpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9zb2JhL2NvbnRyb2xzL3NyYy9saWIvcGl2b3QtY29udHJvbHMvcGxhbmUtc2xpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTix1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFFBQVEsRUFDUixzQkFBc0IsRUFDdEIsVUFBVSxFQUNWLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUVOLFNBQVMsR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzNELE9BQU8sRUFBRSxRQUFRLEVBQUUsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxPQUFPLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFDaEgsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7O0FBRXJELFNBQVMsa0JBQWtCLENBQUMsRUFBVyxFQUFFLEVBQVcsRUFBRSxNQUFlO0lBQ3BFLE1BQU0sRUFBRSxHQUNQLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNuRSxDQUFDLENBQUMsQ0FBQztRQUNILENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDckUsQ0FBQyxDQUFDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsTUFBTSxlQUFlLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDOUcsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDL0UsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMvQixNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQy9CLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0IsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUMvQixNQUFNLEVBQUUsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ25DLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFD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T0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxRQUFRLENBQUM7aUJBQzlDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG5cdENvbXBvbmVudCxcblx0Y29tcHV0ZWQsXG5cdENVU1RPTV9FTEVNRU5UU19TQ0hFTUEsXG5cdEVsZW1lbnRSZWYsXG5cdGluamVjdCxcblx0aW5wdXQsXG5cdHNpZ25hbCxcblx0U2lnbmFsLFxuXHR2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZXh0ZW5kLCBpbmplY3RTdG9yZSwgTmd0VGhyZWVFdmVudCB9IGZyb20gJ2FuZ3VsYXItdGhyZWUnO1xuaW1wb3J0IHsgTmd0c0xpbmUgfSBmcm9tICdhbmd1bGFyLXRocmVlLXNvYmEvYWJzdHJhY3Rpb25zJztcbmltcG9ydCB7IE5ndHNIVE1MLCBOZ3RzSFRNTENvbnRlbnQgfSBmcm9tICdhbmd1bGFyLXRocmVlLXNvYmEvbWlzYyc7XG5pbXBvcnQgeyBEb3VibGVTaWRlLCBHcm91cCwgTWF0cml4NCwgTWVzaCwgTWVzaEJhc2ljTWF0ZXJpYWwsIFBsYW5lLCBQbGFuZUdlb21ldHJ5LCBSYXksIFZlY3RvcjMgfSBmcm9tICd0aHJlZSc7XG5pbXBvcnQgeyBOZ3RzUGl2b3RDb250cm9scyB9IGZyb20gJy4vcGl2b3QtY29udHJvbHMnO1xuXG5mdW5jdGlvbiBkZWNvbXBvc2VJbnRvQmFzaXMoZTE6IFZlY3RvcjMsIGUyOiBWZWN0b3IzLCBvZmZzZXQ6IFZlY3RvcjMpIHtcblx0Y29uc3QgaTEgPVxuXHRcdE1hdGguYWJzKGUxLngpID49IE1hdGguYWJzKGUxLnkpICYmIE1hdGguYWJzKGUxLngpID49IE1hdGguYWJzKGUxLnopXG5cdFx0XHQ/IDBcblx0XHRcdDogTWF0aC5hYnMoZTEueSkgPj0gTWF0aC5hYnMoZTEueCkgJiYgTWF0aC5hYnMoZTEueSkgPj0gTWF0aC5hYnMoZTEueilcblx0XHRcdFx0PyAxXG5cdFx0XHRcdDogMjtcblx0Y29uc3QgZTJEZWdyb3d0aE9yZGVyID0gWzAsIDEsIDJdLnNvcnQoKGEsIGIpID0+IE1hdGguYWJzKGUyLmdldENvbXBvbmVudChiKSkgLSBNYXRoLmFicyhlMi5nZXRDb21wb25lbnQoYSkpKTtcblx0Y29uc3QgaTIgPSBpMSA9PT0gZTJEZWdyb3d0aE9yZGVyWzBdID8gZTJEZWdyb3d0aE9yZGVyWzFdIDogZTJEZWdyb3d0aE9yZGVyWzBdO1xuXHRjb25zdCBhMSA9IGUxLmdldENvbXBvbmVudChpMSk7XG5cdGNvbnN0IGEyID0gZTEuZ2V0Q29tcG9uZW50KGkyKTtcblx0Y29uc3QgYjEgPSBlMi5nZXRDb21wb25lbnQoaTEpO1xuXHRjb25zdCBiMiA9IGUyLmdldENvbXBvbmVudChpMik7XG5cdGNvbnN0IGMxID0gb2Zmc2V0LmdldENvbXBvbmVudChpMSk7XG5cdGNvbnN0IGMyID0gb2Zmc2V0LmdldENvbXBvbmVudChpMik7XG5cblx0Y29uc3QgeSA9IChjMiAtIGMxICogKGEyIC8gYTEpKSAvIChiMiAtIGIxICogKGEyIC8gYTEpKTtcblx0Y29uc3QgeCA9IChjMSAtIHkgKiBiMSkgLyBhMTtcblxuXHRyZXR1cm4gW3gsIHldO1xufVxuXG5jb25zdCByYXkgPSBuZXcgUmF5KCk7XG5jb25zdCBpbnRlcnNlY3Rpb24gPSBuZXcgVmVjdG9yMygpO1xuY29uc3Qgb2Zmc2V0TWF0cml4ID0gbmV3IE1hdHJpeDQoKTtcblxuQENvbXBvbmVudCh7XG5cdHNlbGVjdG9yOiAnbmd0cy1wbGFuZS1zbGlkZXInLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxuZ3QtZ3JvdXAgI2dyb3VwIFttYXRyaXhdPVwibWF0cml4TCgpXCIgW21hdHJpeEF1dG9VcGRhdGVdPVwiZmFsc2VcIj5cblx0XHRcdEBpZiAocGl2b3RDb250cm9scy5hbm5vdGF0aW9ucygpKSB7XG5cdFx0XHRcdDxuZ3RzLWh0bWwgW29wdGlvbnNdPVwieyBwb3NpdGlvbjogWzAsIDAsIDBdIH1cIj5cblx0XHRcdFx0XHQ8ZGl2XG5cdFx0XHRcdFx0XHQjYW5ub3RhdGlvblxuXHRcdFx0XHRcdFx0bmd0c0hUTUxDb250ZW50XG5cdFx0XHRcdFx0XHRzdHlsZT1cImRpc3BsYXk6IG5vbmU7IGJhY2tncm91bmQ6ICMxNTE1MjA7IGNvbG9yOiB3aGl0ZTsgcGFkZGluZzogNnB4IDhweDsgYm9yZGVyLXJhZGl1czogN3B4OyB3aGl0ZS1zcGFjZTogbm93cmFwXCJcblx0XHRcdFx0XHRcdFtjbGFzc109XCJwaXZvdENvbnRyb2xzLmFubm90YXRpb25zQ2xhc3MoKVwiXG5cdFx0XHRcdFx0PjwvZGl2PlxuXHRcdFx0XHQ8L25ndHMtaHRtbD5cblx0XHRcdH1cblx0XHRcdDxuZ3QtZ3JvdXAgW3Bvc2l0aW9uXT1cIltwb3MxKCkgKiAxLjcsIHBvczEoKSAqIDEuNywgMF1cIj5cblx0XHRcdFx0PG5ndC1tZXNoXG5cdFx0XHRcdFx0W3Zpc2libGVdPVwidHJ1ZVwiXG5cdFx0XHRcdFx0W3NjYWxlXT1cImxlbmd0aCgpXCJcblx0XHRcdFx0XHRbdXNlckRhdGFdPVwicGl2b3RDb250cm9scy51c2VyRGF0YSgpXCJcblx0XHRcdFx0XHQocG9pbnRlcmRvd24pPVwib25Qb2ludGVyRG93bigkYW55KCRldmVudCkpXCJcblx0XHRcdFx0XHQocG9pbnRlcm1vdmUpPVwib25Qb2ludGVyTW92ZSgkYW55KCRldmVudCkpXCJcblx0XHRcdFx0XHQocG9pbnRlcnVwKT1cIm9uUG9pbnRlclVwKCRhbnkoJGV2ZW50KSlcIlxuXHRcdFx0XHRcdChwb2ludGVyb3V0KT1cIm9uUG9pbnRlck91dCgkYW55KCRldmVudCkpXCJcblx0XHRcdFx0PlxuXHRcdFx0XHRcdDxuZ3QtcGxhbmUtZ2VvbWV0cnkgLz5cblx0XHRcdFx0XHQ8bmd0LW1lc2gtYmFzaWMtbWF0ZXJpYWxcblx0XHRcdFx0XHRcdFt0cmFuc3BhcmVudF09XCJ0cnVlXCJcblx0XHRcdFx0XHRcdFtkZXB0aFRlc3RdPVwicGl2b3RDb250cm9scy5kZXB0aFRlc3QoKVwiXG5cdFx0XHRcdFx0XHRbY29sb3JdPVwiY29sb3IoKVwiXG5cdFx0XHRcdFx0XHRbcG9seWdvbk9mZnNldF09XCJ0cnVlXCJcblx0XHRcdFx0XHRcdFtwb2x5Z29uT2Zmc2V0RmFjdG9yXT1cIi0xMFwiXG5cdFx0XHRcdFx0XHRbc2lkZV09XCJEb3VibGVTaWRlXCJcblx0XHRcdFx0XHRcdFtmb2ddPVwiZmFsc2VcIlxuXHRcdFx0XHRcdC8+XG5cdFx0XHRcdDwvbmd0LW1lc2g+XG5cdFx0XHRcdDxuZ3RzLWxpbmVcblx0XHRcdFx0XHRbcG9pbnRzXT1cInBvaW50cygpXCJcblx0XHRcdFx0XHRbb3B0aW9uc109XCJ7XG5cdFx0XHRcdFx0XHRwb3NpdGlvbjogWy1sZW5ndGgoKSAvIDIsIC1sZW5ndGgoKSAvIDIsIDBdLFxuXHRcdFx0XHRcdFx0dHJhbnNwYXJlbnQ6IHRydWUsXG5cdFx0XHRcdFx0XHRkZXB0aFRlc3Q6IHBpdm90Q29udHJvbHMuZGVwdGhUZXN0KCksXG5cdFx0XHRcdFx0XHRsaW5lV2lkdGg6IHBpdm90Q29udHJvbHMubGluZVdpZHRoKCksXG5cdFx0XHRcdFx0XHRjb2xvcjogY29sb3IoKSxcblx0XHRcdFx0XHRcdG9wYWNpdHk6IHBpdm90Q29udHJvbHMub3BhY2l0eSgpLFxuXHRcdFx0XHRcdFx0cG9seWdvbk9mZnNldDogdHJ1ZSxcblx0XHRcdFx0XHRcdHBvbHlnb25PZmZzZXRGYWN0b3I6IC0xMCxcblx0XHRcdFx0XHRcdHVzZXJEYXRhOiBwaXZvdENvbnRyb2xzLnVzZXJEYXRhKCksXG5cdFx0XHRcdFx0XHRmb2c6IGZhbHNlLFxuXHRcdFx0XHRcdH1cIlxuXHRcdFx0XHQvPlxuXHRcdFx0PC9uZ3QtZ3JvdXA+XG5cdFx0PC9uZ3QtZ3JvdXA+XG5cdGAsXG5cdHNjaGVtYXM6IFtDVVNUT01fRUxFTUVOVFNfU0NIRU1BXSxcblx0Y2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG5cdGltcG9ydHM6IFtOZ3RzSFRNTCwgTmd0c0hUTUxDb250ZW50LCBOZ3RzTGluZV0sXG59KVxuZXhwb3J0IGNsYXNzIE5ndHNQbGFuZVNsaWRlciB7XG5cdHByb3RlY3RlZCByZWFkb25seSBEb3VibGVTaWRlID0gRG91YmxlU2lkZTtcblxuXHRkaXIxID0gaW5wdXQucmVxdWlyZWQ8VmVjdG9yMz4oKTtcblx0ZGlyMiA9IGlucHV0LnJlcXVpcmVkPFZlY3RvcjM+KCk7XG5cdGF4aXMgPSBpbnB1dC5yZXF1aXJlZDwwIHwgMSB8IDI+KCk7XG5cblx0Z3JvdXBSZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZjxHcm91cD4+KCdncm91cCcpO1xuXHRhbm5vdGF0aW9uUmVmID0gdmlld0NoaWxkPHVua25vd24sIEVsZW1lbnRSZWY8SFRNTERpdkVsZW1lbnQ+PignYW5ub3RhdGlvbicsIHsgcmVhZDogRWxlbWVudFJlZiB9KTtcblxuXHRwaXZvdENvbnRyb2xzID0gaW5qZWN0KE5ndHNQaXZvdENvbnRyb2xzKTtcblx0cHJpdmF0ZSBzdG9yZSA9IGluamVjdFN0b3JlKCk7XG5cdHByaXZhdGUgY29udHJvbHMgPSB0aGlzLnN0b3JlLnNlbGVjdCgnY29udHJvbHMnKSBhcyB1bmtub3duIGFzIFNpZ25hbDx7IGVuYWJsZWQ6IGJvb2xlYW4gfT47XG5cblx0cHJpdmF0ZSBob3ZlcmVkID0gc2lnbmFsKGZhbHNlKTtcblx0cHJpdmF0ZSBjbGlja0luZm86IHsgY2xpY2tQb2ludDogVmVjdG9yMzsgZTE6IFZlY3RvcjM7IGUyOiBWZWN0b3IzOyBwbGFuZTogUGxhbmUgfSB8IG51bGwgPSBudWxsO1xuXHRwcml2YXRlIG9mZnNldFgwID0gMDtcblx0cHJpdmF0ZSBvZmZzZXRZMCA9IDA7XG5cblx0bWF0cml4TCA9IGNvbXB1dGVkKCgpID0+IHtcblx0XHRjb25zdCBkaXIxTiA9IHRoaXMuZGlyMSgpLmNsb25lKCkubm9ybWFsaXplKCk7XG5cdFx0Y29uc3QgZGlyMk4gPSB0aGlzLmRpcjIoKS5jbG9uZSgpLm5vcm1hbGl6ZSgpO1xuXHRcdHJldHVybiBuZXcgTWF0cml4NCgpLm1ha2VCYXNpcyhkaXIxTiwgZGlyMk4sIGRpcjFOLmNsb25lKCkuY3Jvc3MoZGlyMk4pKTtcblx0fSk7XG5cblx0cG9zMSA9IGNvbXB1dGVkKCgpID0+ICh0aGlzLnBpdm90Q29udHJvbHMuZml4ZWQoKSA/IDEgLyA3IDogdGhpcy5waXZvdENvbnRyb2xzLnNjYWxlKCkgLyA3KSk7XG5cdGxlbmd0aCA9IGNvbXB1dGVkKCgpID0+ICh0aGlzLnBpdm90Q29udHJvbHMuZml4ZWQoKSA/IDAuMjI1IDogdGhpcy5waXZvdENvbnRyb2xzLnNjYWxlKCkgKiAwLjIyNSkpO1xuXHRjb2xvciA9IGNvbXB1dGVkKCgpID0+XG5cdFx0dGhpcy5ob3ZlcmVkKCkgPyB0aGlzLnBpdm90Q29udHJvbHMuaG92ZXJlZENvbG9yKCkgOiB0aGlzLnBpdm90Q29udHJvbHMuYXhpc0NvbG9ycygpW3RoaXMuYXhpcygpXSxcblx0KTtcblx0cG9pbnRzID0gY29tcHV0ZWQoKCkgPT4ge1xuXHRcdGNvbnN0IGxlbmd0aCA9IHRoaXMubGVuZ3RoKCk7XG5cdFx0cmV0dXJuIFtcblx0XHRcdG5ldyBWZWN0b3IzKDAsIDAsIDApLFxuXHRcdFx0bmV3IFZlY3RvcjMoMCwgbGVuZ3RoLCAwKSxcblx0XHRcdG5ldyBWZWN0b3IzKGxlbmd0aCwgbGVuZ3RoLCAwKSxcblx0XHRcdG5ldyBWZWN0b3IzKGxlbmd0aCwgMCwgMCksXG5cdFx0XHRuZXcgVmVjdG9yMygwLCAwLCAwKSxcblx0XHRdO1xuXHR9KTtcblxuXHRjb25zdHJ1Y3RvcigpIHtcblx0XHRleHRlbmQoeyBHcm91cCwgTWVzaCwgUGxhbmVHZW9tZXRyeSwgTWVzaEJhc2ljTWF0ZXJpYWwgfSk7XG5cdH1cblxuXHRvblBvaW50ZXJEb3duKGV2ZW50OiBOZ3RUaHJlZUV2ZW50PFBvaW50ZXJFdmVudD4pIHtcblx0XHRjb25zdCBbYW5ub3RhdGlvbiwgYXhpcywgZ3JvdXAsIGNvbnRyb2xzXSA9IFtcblx0XHRcdHRoaXMuYW5ub3RhdGlvblJlZigpPy5uYXRpdmVFbGVtZW50LFxuXHRcdFx0dGhpcy5heGlzKCksXG5cdFx0XHR0aGlzLmdyb3VwUmVmKCkubmF0aXZlRWxlbWVudCxcblx0XHRcdHRoaXMuY29udHJvbHMoKSxcblx0XHRdO1xuXG5cdFx0aWYgKGFubm90YXRpb24pIHtcblx0XHRcdGFubm90YXRpb24uaW5uZXJUZXh0ID0gYCR7dGhpcy5waXZvdENvbnRyb2xzLnRyYW5zbGF0aW9uWyhheGlzICsgMSkgJSAzXS50b0ZpeGVkKDIpfSwgJHt0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAyKSAlIDNdLnRvRml4ZWQoMil9YDtcblx0XHRcdGFubm90YXRpb24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0fVxuXG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0Y29uc3QgY2xpY2tQb2ludCA9IGV2ZW50LnBvaW50LmNsb25lKCk7XG5cdFx0Y29uc3Qgb3JpZ2luID0gbmV3IFZlY3RvcjMoKS5zZXRGcm9tTWF0cml4UG9zaXRpb24oZ3JvdXAubWF0cml4V29ybGQpO1xuXHRcdGNvbnN0IGUxID0gbmV3IFZlY3RvcjMoKS5zZXRGcm9tTWF0cml4Q29sdW1uKGdyb3VwLm1hdHJpeFdvcmxkLCAwKS5ub3JtYWxpemUoKTtcblx0XHRjb25zdCBlMiA9IG5ldyBWZWN0b3IzKCkuc2V0RnJvbU1hdHJpeENvbHVtbihncm91cC5tYXRyaXhXb3JsZCwgMSkubm9ybWFsaXplKCk7XG5cdFx0Y29uc3Qgbm9ybWFsID0gbmV3IFZlY3RvcjMoKS5zZXRGcm9tTWF0cml4Q29sdW1uKGdyb3VwLm1hdHJpeFdvcmxkLCAyKS5ub3JtYWxpemUoKTtcblx0XHRjb25zdCBwbGFuZSA9IG5ldyBQbGFuZSgpLnNldEZyb21Ob3JtYWxBbmRDb3BsYW5hclBvaW50KG5vcm1hbCwgb3JpZ2luKTtcblx0XHR0aGlzLmNsaWNrSW5mbyA9IHsgY2xpY2tQb2ludCwgZTEsIGUyLCBwbGFuZSB9O1xuXHRcdHRoaXMub2Zmc2V0WDAgPSB0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAxKSAlIDNdO1xuXHRcdHRoaXMub2Zmc2V0WTAgPSB0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAyKSAlIDNdO1xuXHRcdHRoaXMucGl2b3RDb250cm9scy5vbkRyYWdTdGFydCh7IGNvbXBvbmVudDogJ1NsaWRlcicsIGF4aXMsIG9yaWdpbiwgZGlyZWN0aW9uczogW2UxLCBlMiwgbm9ybWFsXSB9KTtcblx0XHRpZiAoY29udHJvbHMpIHtcblx0XHRcdGNvbnRyb2xzLmVuYWJsZWQgPSBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIC0gc2V0UG9pbnRlckNhcHR1cmUgaXMgbm90IGRlZmluZWQgb24gVGhyZWVFdmVudFxuXHRcdGV2ZW50LnRhcmdldC5zZXRQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuXHR9XG5cblx0b25Qb2ludGVyTW92ZShldmVudDogTmd0VGhyZWVFdmVudDxQb2ludGVyRXZlbnQ+KSB7XG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0aWYgKCF0aGlzLmhvdmVyZWQoKSkgdGhpcy5ob3ZlcmVkLnNldCh0cnVlKTtcblxuXHRcdGlmICh0aGlzLmNsaWNrSW5mbykge1xuXHRcdFx0Y29uc3QgeyBjbGlja1BvaW50LCBlMSwgZTIsIHBsYW5lIH0gPSB0aGlzLmNsaWNrSW5mbztcblx0XHRcdGNvbnN0IFt0cmFuc2xhdGlvbkxpbWl0cywgYXhpcywgYW5ub3RhdGlvbl0gPSBbXG5cdFx0XHRcdHRoaXMucGl2b3RDb250cm9scy50cmFuc2xhdGlvbkxpbWl0cygpLFxuXHRcdFx0XHR0aGlzLmF4aXMoKSxcblx0XHRcdFx0dGhpcy5hbm5vdGF0aW9uUmVmKCk/Lm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRdO1xuXG5cdFx0XHRjb25zdCBbbWluWCwgbWF4WF0gPSB0cmFuc2xhdGlvbkxpbWl0cz8uWyhheGlzICsgMSkgJSAzXSB8fCBbdW5kZWZpbmVkLCB1bmRlZmluZWRdO1xuXHRcdFx0Y29uc3QgW21pblksIG1heFldID0gdHJhbnNsYXRpb25MaW1pdHM/LlsoYXhpcyArIDIpICUgM10gfHwgW3VuZGVmaW5lZCwgdW5kZWZpbmVkXTtcblxuXHRcdFx0cmF5LmNvcHkoZXZlbnQucmF5KTtcblx0XHRcdHJheS5pbnRlcnNlY3RQbGFuZShwbGFuZSwgaW50ZXJzZWN0aW9uKTtcblx0XHRcdHJheS5kaXJlY3Rpb24ubmVnYXRlKCk7XG5cdFx0XHRyYXkuaW50ZXJzZWN0UGxhbmUocGxhbmUsIGludGVyc2VjdGlvbik7XG5cdFx0XHRpbnRlcnNlY3Rpb24uc3ViKGNsaWNrUG9pbnQpO1xuXHRcdFx0bGV0IFtvZmZzZXRYLCBvZmZzZXRZXSA9IGRlY29tcG9zZUludG9CYXNpcyhlMSwgZTIsIGludGVyc2VjdGlvbik7XG5cdFx0XHQvKiBsZXQgb2Zmc2V0WSA9IChpbnRlcnNlY3Rpb24ueSAtIChpbnRlcnNlY3Rpb24ueCAqIGUxLnkpIC8gZTEueCkgLyAoZTIueSAtIChlMi54ICogZTEueSkgLyBlMS54KVxuICAgICAgbGV0IG9mZnNldFggPSAoaW50ZXJzZWN0aW9uLnggLSBvZmZzZXRZICogZTIueCkgLyBlMS54ICovXG5cdFx0XHRpZiAobWluWCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdG9mZnNldFggPSBNYXRoLm1heChvZmZzZXRYLCBtaW5YIC0gdGhpcy5vZmZzZXRYMCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWF4WCAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdG9mZnNldFggPSBNYXRoLm1pbihvZmZzZXRYLCBtYXhYIC0gdGhpcy5vZmZzZXRYMCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWluWSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdG9mZnNldFkgPSBNYXRoLm1heChvZmZzZXRZLCBtaW5ZIC0gdGhpcy5vZmZzZXRZMCk7XG5cdFx0XHR9XG5cdFx0XHRpZiAobWF4WSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdG9mZnNldFkgPSBNYXRoLm1pbihvZmZzZXRZLCBtYXhZIC0gdGhpcy5vZmZzZXRZMCk7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAxKSAlIDNdID0gdGhpcy5vZmZzZXRYMCArIG9mZnNldFg7XG5cdFx0XHR0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAyKSAlIDNdID0gdGhpcy5vZmZzZXRZMCArIG9mZnNldFk7XG5cblx0XHRcdGlmIChhbm5vdGF0aW9uKSB7XG5cdFx0XHRcdGFubm90YXRpb24uaW5uZXJUZXh0ID0gYCR7dGhpcy5waXZvdENvbnRyb2xzLnRyYW5zbGF0aW9uWyhheGlzICsgMSkgJSAzXS50b0ZpeGVkKDIpfSwgJHt0aGlzLnBpdm90Q29udHJvbHMudHJhbnNsYXRpb25bKGF4aXMgKyAyKSAlIDNdLnRvRml4ZWQoMil9YDtcblx0XHRcdH1cblxuXHRcdFx0b2Zmc2V0TWF0cml4Lm1ha2VUcmFuc2xhdGlvbihcblx0XHRcdFx0b2Zmc2V0WCAqIGUxLnggKyBvZmZzZXRZICogZTIueCxcblx0XHRcdFx0b2Zmc2V0WCAqIGUxLnkgKyBvZmZzZXRZICogZTIueSxcblx0XHRcdFx0b2Zmc2V0WCAqIGUxLnogKyBvZmZzZXRZICogZTIueixcblx0XHRcdCk7XG5cdFx0XHR0aGlzLnBpdm90Q29udHJvbHMub25EcmFnKG9mZnNldE1hdHJpeCk7XG5cdFx0fVxuXHR9XG5cblx0b25Qb2ludGVyVXAoZXZlbnQ6IE5ndFRocmVlRXZlbnQ8UG9pbnRlckV2ZW50Pikge1xuXHRcdGNvbnN0IFthbm5vdGF0aW9uLCBjb250cm9sc10gPSBbdGhpcy5hbm5vdGF0aW9uUmVmKCk/Lm5hdGl2ZUVsZW1lbnQsIHRoaXMuY29udHJvbHMoKV07XG5cdFx0aWYgKGFubm90YXRpb24pIHtcblx0XHRcdGFubm90YXRpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHR9XG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0dGhpcy5jbGlja0luZm8gPSBudWxsO1xuXHRcdHRoaXMucGl2b3RDb250cm9scy5vbkRyYWdFbmQoKTtcblx0XHRpZiAoY29udHJvbHMpIHtcblx0XHRcdGNvbnRyb2xzLmVuYWJsZWQgPSB0cnVlO1xuXHRcdH1cblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIC0gcmVsZWFzZVBvaW50ZXJDYXB0dXJlIGlzIG5vdCBkZWZpbmVkIG9uIFRocmVlRXZlbnRcblx0XHRldmVudC50YXJnZXQucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cdH1cblxuXHRvblBvaW50ZXJPdXQoZXZlbnQ6IE5ndFRocmVlRXZlbnQ8UG9pbnRlckV2ZW50Pikge1xuXHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdHRoaXMuaG92ZXJlZC5zZXQoZmFsc2UpO1xuXHR9XG59XG4iXX0=
@@ -1,232 +0,0 @@
1
- import { ChangeDetectionStrategy, Component, computed, CUSTOM_ELEMENTS_SCHEMA, ElementRef, inject, input, signal, viewChild, } from '@angular/core';
2
- import { extend, injectStore, NgtArgs } from 'angular-three';
3
- import { calculateScaleFactor, NgtsHTML, NgtsHTMLContent } from 'angular-three-soba/misc';
4
- import { Group, Matrix4, Mesh, MeshBasicMaterial, Quaternion, SphereGeometry, Vector3 } from 'three';
5
- import { NgtsPivotControls } from './pivot-controls';
6
- import * as i0 from "@angular/core";
7
- const vec1 = new Vector3();
8
- const vec2 = new Vector3();
9
- export function calculateOffset(clickPoint, normal, rayStart, rayDir) {
10
- const e1 = normal.dot(normal);
11
- const e2 = normal.dot(clickPoint) - normal.dot(rayStart);
12
- const e3 = normal.dot(rayDir);
13
- if (e3 === 0) {
14
- return -e2 / e1;
15
- }
16
- vec1
17
- .copy(rayDir)
18
- .multiplyScalar(e1 / e3)
19
- .sub(normal);
20
- vec2
21
- .copy(rayDir)
22
- .multiplyScalar(e2 / e3)
23
- .add(rayStart)
24
- .sub(clickPoint);
25
- return -vec1.dot(vec2) / vec1.dot(vec1);
26
- }
27
- const upV = new Vector3(0, 1, 0);
28
- const scaleV = new Vector3();
29
- const scaleMatrix = new Matrix4();
30
- export class NgtsScalingSphere {
31
- constructor() {
32
- this.direction = input.required();
33
- this.axis = input.required();
34
- this.groupRef = viewChild.required('group');
35
- this.annotationRef = viewChild('annotation', { read: ElementRef });
36
- this.meshRef = viewChild.required('mesh');
37
- this.pivotControls = inject(NgtsPivotControls);
38
- this.store = injectStore();
39
- this.controls = this.store.select('controls');
40
- this.size = this.store.select('size');
41
- this.hovered = signal(false);
42
- this.scale0 = 1;
43
- this.scaleCurrent = 1;
44
- this.clickInfo = null;
45
- this.position = computed(() => (this.pivotControls.fixed() ? 1.2 : 1.2 * this.pivotControls.scale()));
46
- this.radius = computed(() => this.pivotControls.fixed()
47
- ? (this.pivotControls.lineWidth() / this.pivotControls.scale()) * 1.8
48
- : this.pivotControls.scale() / 22.5);
49
- this.matrixL = computed(() => {
50
- const quaternion = new Quaternion().setFromUnitVectors(upV, this.direction().clone().normalize());
51
- return new Matrix4().makeRotationFromQuaternion(quaternion);
52
- });
53
- this.color = computed(() => this.hovered() ? this.pivotControls.hoveredColor() : this.pivotControls.axisColors()[this.axis()]);
54
- extend({ Group, Mesh, SphereGeometry, MeshBasicMaterial });
55
- }
56
- onPointerDown(event) {
57
- const [annotation, controls, fixed, scale, direction, axis, size, group] = [
58
- this.annotationRef()?.nativeElement,
59
- this.controls(),
60
- this.pivotControls.fixed(),
61
- this.pivotControls.scale(),
62
- this.direction(),
63
- this.axis(),
64
- this.size(),
65
- this.groupRef().nativeElement,
66
- ];
67
- if (annotation) {
68
- annotation.innerText = `${scale.toFixed(2)}`;
69
- annotation.style.display = 'block';
70
- }
71
- event.stopPropagation();
72
- const rotation = new Matrix4().extractRotation(group.matrixWorld);
73
- const clickPoint = event.point.clone();
74
- const origin = new Vector3().setFromMatrixPosition(group.matrixWorld);
75
- const dir = direction.clone().applyMatrix4(rotation).normalize();
76
- const mPLG = group.matrixWorld.clone();
77
- const mPLGInv = mPLG.clone().invert();
78
- const offsetMultiplier = fixed
79
- ? 1 / calculateScaleFactor(group.getWorldPosition(vec1), scale, event.camera, size)
80
- : 1;
81
- this.clickInfo = { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier };
82
- this.pivotControls.onDragStart({ component: 'Sphere', axis, origin, directions: [dir] });
83
- if (controls) {
84
- controls.enabled = false;
85
- }
86
- // @ts-expect-error - setPointerCapture is not in the type definition
87
- event.target.setPointerCapture(event.pointerId);
88
- }
89
- onPointerMove(event) {
90
- event.stopPropagation();
91
- if (!this.hovered())
92
- this.hovered.set(true);
93
- if (this.clickInfo) {
94
- const { clickPoint, dir, mPLG, mPLGInv, offsetMultiplier } = this.clickInfo;
95
- const [scaleLimits, axis, position, annotation, fixed, scale, mesh] = [
96
- this.pivotControls.scaleLimits(),
97
- this.axis(),
98
- this.position(),
99
- this.annotationRef()?.nativeElement,
100
- this.pivotControls.fixed(),
101
- this.pivotControls.scale(),
102
- this.meshRef().nativeElement,
103
- ];
104
- const [min, max] = scaleLimits?.[axis] || [1e-5, undefined]; // always limit the minimal value, since setting it very low might break the transform
105
- const offsetW = calculateOffset(clickPoint, dir, event.ray.origin, event.ray.direction);
106
- const offsetL = offsetW * offsetMultiplier;
107
- const offsetH = fixed ? offsetL : offsetL / scale;
108
- let upscale = Math.pow(2, offsetH * 0.2);
109
- if (event.shiftKey) {
110
- upscale = Math.round(upscale * 10) / 10;
111
- }
112
- upscale = Math.max(upscale, min / this.scale0);
113
- if (max !== undefined) {
114
- upscale = Math.min(upscale, max / this.scale0);
115
- }
116
- this.scaleCurrent = this.scale0 * upscale;
117
- mesh.position.set(0, position + offsetL, 0);
118
- if (annotation) {
119
- annotation.innerText = `${this.scaleCurrent.toFixed(2)}`;
120
- }
121
- scaleV.set(1, 1, 1);
122
- scaleV.setComponent(axis, upscale);
123
- scaleMatrix.makeScale(scaleV.x, scaleV.y, scaleV.z).premultiply(mPLG).multiply(mPLGInv);
124
- this.pivotControls.onDrag(scaleMatrix);
125
- }
126
- }
127
- onPointerUp(event) {
128
- const [annotation, controls, position, mesh] = [
129
- this.annotationRef()?.nativeElement,
130
- this.controls(),
131
- this.position(),
132
- this.meshRef().nativeElement,
133
- ];
134
- if (annotation) {
135
- annotation.style.display = 'none';
136
- }
137
- event.stopPropagation();
138
- this.scale0 = this.scaleCurrent;
139
- this.clickInfo = null;
140
- mesh.position.set(0, position, 0);
141
- this.pivotControls.onDragEnd();
142
- if (controls) {
143
- controls.enabled = true;
144
- }
145
- // @ts-expect-error - releasePointerCapture is not in the type definition
146
- event.target.releasePointerCapture(event.pointerId);
147
- }
148
- onPointerOut(event) {
149
- event.stopPropagation();
150
- this.hovered.set(false);
151
- }
152
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtsScalingSphere, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
153
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.0", type: NgtsScalingSphere, isStandalone: true, selector: "ngts-scaling-sphere", inputs: { direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: true, transformFunction: null }, axis: { classPropertyName: "axis", publicName: "axis", isSignal: true, isRequired: true, transformFunction: null } }, viewQueries: [{ propertyName: "groupRef", first: true, predicate: ["group"], descendants: true, isSignal: true }, { propertyName: "annotationRef", first: true, predicate: ["annotation"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "meshRef", first: true, predicate: ["mesh"], descendants: true, isSignal: true }], ngImport: i0, template: `
154
- <ngt-group #group>
155
- <ngt-group
156
- [matrix]="matrixL()"
157
- [matrixAutoUpdate]="false"
158
- (pointerdown)="onPointerDown($any($event))"
159
- (pointermove)="onPointerMove($any($event))"
160
- (pointerup)="onPointerUp($any($event))"
161
- (pointerout)="onPointerOut($any($event))"
162
- >
163
- @if (pivotControls.annotations()) {
164
- <ngts-html [options]="{ position: [0, position() / 2, 0] }">
165
- <div
166
- #annotation
167
- ngtsHTMLContent
168
- style="display: none; background: #151520; color: white; padding: 6px 8px; border-radius: 7px; white-space: nowrap;"
169
- [class]="pivotControls.annotationsClass()"
170
- ></div>
171
- </ngts-html>
172
- }
173
- <ngt-mesh #mesh [position]="[0, position(), 0]" [renderOrder]="500" [userData]="pivotControls.userData()">
174
- <ngt-sphere-geometry *args="[radius(), 12, 12]" />
175
- <ngt-mesh-basic-material
176
- [transparent]="true"
177
- [depthTest]="pivotControls.depthTest()"
178
- [color]="color()"
179
- [opacity]="pivotControls.opacity()"
180
- [polygonOffset]="true"
181
- [polygonOffsetFactor]="-10"
182
- />
183
- </ngt-mesh>
184
- </ngt-group>
185
- </ngt-group>
186
- `, isInline: true, dependencies: [{ kind: "component", type: NgtsHTML, selector: "ngts-html", inputs: ["options"] }, { kind: "component", type: NgtsHTMLContent, selector: "[ngtsHTMLContent]", inputs: ["ngtsHTMLContent"], outputs: ["occluded"] }, { kind: "directive", type: NgtArgs, selector: "ng-template[args]", inputs: ["args"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
187
- }
188
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: NgtsScalingSphere, decorators: [{
189
- type: Component,
190
- args: [{
191
- selector: 'ngts-scaling-sphere',
192
- standalone: true,
193
- template: `
194
- <ngt-group #group>
195
- <ngt-group
196
- [matrix]="matrixL()"
197
- [matrixAutoUpdate]="false"
198
- (pointerdown)="onPointerDown($any($event))"
199
- (pointermove)="onPointerMove($any($event))"
200
- (pointerup)="onPointerUp($any($event))"
201
- (pointerout)="onPointerOut($any($event))"
202
- >
203
- @if (pivotControls.annotations()) {
204
- <ngts-html [options]="{ position: [0, position() / 2, 0] }">
205
- <div
206
- #annotation
207
- ngtsHTMLContent
208
- style="display: none; background: #151520; color: white; padding: 6px 8px; border-radius: 7px; white-space: nowrap;"
209
- [class]="pivotControls.annotationsClass()"
210
- ></div>
211
- </ngts-html>
212
- }
213
- <ngt-mesh #mesh [position]="[0, position(), 0]" [renderOrder]="500" [userData]="pivotControls.userData()">
214
- <ngt-sphere-geometry *args="[radius(), 12, 12]" />
215
- <ngt-mesh-basic-material
216
- [transparent]="true"
217
- [depthTest]="pivotControls.depthTest()"
218
- [color]="color()"
219
- [opacity]="pivotControls.opacity()"
220
- [polygonOffset]="true"
221
- [polygonOffsetFactor]="-10"
222
- />
223
- </ngt-mesh>
224
- </ngt-group>
225
- </ngt-group>
226
- `,
227
- schemas: [CUSTOM_ELEMENTS_SCHEMA],
228
- changeDetection: ChangeDetectionStrategy.OnPush,
229
- imports: [NgtsHTML, NgtsHTMLContent, NgtArgs],
230
- }]
231
- }], ctorParameters: () => [] });
232
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NhbGluZy1zcGhlcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3NvYmEvY29udHJvbHMvc3JjL2xpYi9waXZvdC1jb250cm9scy9zY2FsaW5nLXNwaGVyZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ04sdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1Isc0JBQXNCLEVBQ3RCLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixTQUFTLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFpQixNQUFNLGVBQWUsQ0FBQztBQUM1RSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsUUFBUSxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQzFGLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxpQkFBaUIsRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLE9BQU8sRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUNyRyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQzs7QUFFckQsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztBQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO0FBRTNCLE1BQU0sVUFBVSxlQUFlLENBQUMsVUFBbUIsRUFBRSxNQUFlLEVBQUUsUUFBaUIsRUFBRSxNQUFlO0lBQ3ZHLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDOUIsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3pELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxH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QUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDekIsQ0FBQzs4R0F4SlcsaUJBQWlCO2tHQUFqQixpQkFBaUIsOGdCQUt3RCxVQUFVLCtJQTNDckY7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztFQWlDVCw0REFHUyxRQUFRLDJFQUFFLGVBQWUsa0hBQUUsT0FBTzs7MkZBRWhDLGlCQUFpQjtrQkF6QzdCLFNBQVM7bUJBQUM7b0JBQ1YsUUFBUSxFQUFFLHFCQUFxQjtvQkFDL0IsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBaUNUO29CQUNELE9BQU8sRUFBRSxDQUFDLHNCQUFzQixDQUFDO29CQUNqQyxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxPQUFPLENBQUM7aUJBQzdDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcblx0Q2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG5cdENvbXBvbmVudCxcblx0Y29tcHV0ZWQsXG5cdENVU1RPTV9FTEVNRU5UU19TQ0hFTUEsXG5cdEVsZW1lbnRSZWYsXG5cdGluamVjdCxcblx0aW5wdXQsXG5cdHNpZ25hbCxcblx0U2lnbmFsLFxuXHR2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZXh0ZW5kLCBpbmplY3RTdG9yZSwgTmd0QXJncywgTmd0VGhyZWVFdmVudCB9IGZyb20gJ2FuZ3VsYXItdGhyZWUnO1xuaW1wb3J0IHsgY2FsY3VsYXRlU2NhbGVGYWN0b3IsIE5ndHNIVE1MLCBOZ3RzSFRNTENvbnRlbnQgfSBmcm9tICdhbmd1bGFyLXRocmVlLXNvYmEvbWlzYyc7XG5pbXBvcnQgeyBHcm91cCwgTWF0cml4NCwgTWVzaCwgTWVzaEJhc2ljTWF0ZXJpYWwsIFF1YXRlcm5pb24sIFNwaGVyZUdlb21ldHJ5LCBWZWN0b3IzIH0gZnJvbSAndGhyZWUnO1xuaW1wb3J0IHsgTmd0c1Bpdm90Q29udHJvbHMgfSBmcm9tICcuL3Bpdm90LWNvbnRyb2xzJztcblxuY29uc3QgdmVjMSA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCB2ZWMyID0gbmV3IFZlY3RvcjMoKTtcblxuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZU9mZnNldChjbGlja1BvaW50OiBWZWN0b3IzLCBub3JtYWw6IFZlY3RvcjMsIHJheVN0YXJ0OiBWZWN0b3IzLCByYXlEaXI6IFZlY3RvcjMpIHtcblx0Y29uc3QgZTEgPSBub3JtYWwuZG90KG5vcm1hbCk7XG5cdGNvbnN0IGUyID0gbm9ybWFsLmRvdChjbGlja1BvaW50KSAtIG5vcm1hbC5kb3QocmF5U3RhcnQpO1xuXHRjb25zdCBlMyA9IG5vcm1hbC5kb3QocmF5RGlyKTtcblxuXHRpZiAoZTMgPT09IDApIHtcblx0XHRyZXR1cm4gLWUyIC8gZTE7XG5cdH1cblxuXHR2ZWMxXG5cdFx0LmNvcHkocmF5RGlyKVxuXHRcdC5tdWx0aXBseVNjYWxhcihlMSAvIGUzKVxuXHRcdC5zdWIobm9ybWFsKTtcblx0dmVjMlxuXHRcdC5jb3B5KHJheURpcilcblx0XHQubXVsdGlwbHlTY2FsYXIoZTIgLyBlMylcblx0XHQuYWRkKHJheVN0YXJ0KVxuXHRcdC5zdWIoY2xpY2tQb2ludCk7XG5cblx0cmV0dXJuIC12ZWMxLmRvdCh2ZWMyKSAvIHZlYzEuZG90KHZlYzEpO1xufVxuXG5jb25zdCB1cFYgPSBuZXcgVmVjdG9yMygwLCAxLCAwKTtcbmNvbnN0IHNjYWxlViA9IG5ldyBWZWN0b3IzKCk7XG5jb25zdCBzY2FsZU1hdHJpeCA9IG5ldyBNYXRyaXg0KCk7XG5cbkBDb21wb25lbnQoe1xuXHRzZWxlY3RvcjogJ25ndHMtc2NhbGluZy1zcGhlcmUnLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHR0ZW1wbGF0ZTogYFxuXHRcdDxuZ3QtZ3JvdXAgI2dyb3VwPlxuXHRcdFx0PG5ndC1ncm91cFxuXHRcdFx0XHRbbWF0cml4XT1cIm1hdHJpeEwoKVwiXG5cdFx0XHRcdFttYXRyaXhBdXRvVXBkYXRlXT1cImZhbHNlXCJcblx0XHRcdFx0KHBvaW50ZXJkb3duKT1cIm9uUG9pbnRlckRvd24oJGFueSgkZXZlbnQpKVwiXG5cdFx0XHRcdChwb2ludGVybW92ZSk9XCJvblBvaW50ZXJNb3ZlKCRhbnkoJGV2ZW50KSlcIlxuXHRcdFx0XHQocG9pbnRlcnVwKT1cIm9uUG9pbnRlclVwKCRhbnkoJGV2ZW50KSlcIlxuXHRcdFx0XHQocG9pbnRlcm91dCk9XCJvblBvaW50ZXJPdXQoJGFueSgkZXZlbnQpKVwiXG5cdFx0XHQ+XG5cdFx0XHRcdEBpZiAocGl2b3RDb250cm9scy5hbm5vdGF0aW9ucygpKSB7XG5cdFx0XHRcdFx0PG5ndHMtaHRtbCBbb3B0aW9uc109XCJ7IHBvc2l0aW9uOiBbMCwgcG9zaXRpb24oKSAvIDIsIDBdIH1cIj5cblx0XHRcdFx0XHRcdDxkaXZcblx0XHRcdFx0XHRcdFx0I2Fubm90YXRpb25cblx0XHRcdFx0XHRcdFx0bmd0c0hUTUxDb250ZW50XG5cdFx0XHRcdFx0XHRcdHN0eWxlPVwiZGlzcGxheTogbm9uZTsgYmFja2dyb3VuZDogIzE1MTUyMDsgY29sb3I6IHdoaXRlOyBwYWRkaW5nOiA2cHggOHB4OyBib3JkZXItcmFkaXVzOiA3cHg7IHdoaXRlLXNwYWNlOiBub3dyYXA7XCJcblx0XHRcdFx0XHRcdFx0W2NsYXNzXT1cInBpdm90Q29udHJvbHMuYW5ub3RhdGlvbnNDbGFzcygpXCJcblx0XHRcdFx0XHRcdD48L2Rpdj5cblx0XHRcdFx0XHQ8L25ndHMtaHRtbD5cblx0XHRcdFx0fVxuXHRcdFx0XHQ8bmd0LW1lc2ggI21lc2ggW3Bvc2l0aW9uXT1cIlswLCBwb3NpdGlvbigpLCAwXVwiIFtyZW5kZXJPcmRlcl09XCI1MDBcIiBbdXNlckRhdGFdPVwicGl2b3RDb250cm9scy51c2VyRGF0YSgpXCI+XG5cdFx0XHRcdFx0PG5ndC1zcGhlcmUtZ2VvbWV0cnkgKmFyZ3M9XCJbcmFkaXVzKCksIDEyLCAxMl1cIiAvPlxuXHRcdFx0XHRcdDxuZ3QtbWVzaC1iYXNpYy1tYXRlcmlhbFxuXHRcdFx0XHRcdFx0W3RyYW5zcGFyZW50XT1cInRydWVcIlxuXHRcdFx0XHRcdFx0W2RlcHRoVGVzdF09XCJwaXZvdENvbnRyb2xzLmRlcHRoVGVzdCgpXCJcblx0XHRcdFx0XHRcdFtjb2xvcl09XCJjb2xvcigpXCJcblx0XHRcdFx0XHRcdFtvcGFjaXR5XT1cInBpdm90Q29udHJvbHMub3BhY2l0eSgpXCJcblx0XHRcdFx0XHRcdFtwb2x5Z29uT2Zmc2V0XT1cInRydWVcIlxuXHRcdFx0XHRcdFx0W3BvbHlnb25PZmZzZXRGYWN0b3JdPVwiLTEwXCJcblx0XHRcdFx0XHQvPlxuXHRcdFx0XHQ8L25ndC1tZXNoPlxuXHRcdFx0PC9uZ3QtZ3JvdXA+XG5cdFx0PC9uZ3QtZ3JvdXA+XG5cdGAsXG5cdHNjaGVtYXM6IFtDVVNUT01fRUxFTUVOVFNfU0NIRU1BXSxcblx0Y2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG5cdGltcG9ydHM6IFtOZ3RzSFRNTCwgTmd0c0hUTUxDb250ZW50LCBOZ3RBcmdzXSxcbn0pXG5leHBvcnQgY2xhc3MgTmd0c1NjYWxpbmdTcGhlcmUge1xuXHRkaXJlY3Rpb24gPSBpbnB1dC5yZXF1aXJlZDxWZWN0b3IzPigpO1xuXHRheGlzID0gaW5wdXQucmVxdWlyZWQ8MCB8IDEgfCAyPigpO1xuXG5cdGdyb3VwUmVmID0gdmlld0NoaWxkLnJlcXVpcmVkPEVsZW1lbnRSZWY8R3JvdXA+PignZ3JvdXAnKTtcblx0YW5ub3RhdGlvblJlZiA9IHZpZXdDaGlsZDx1bmtub3duLCBFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pj4oJ2Fubm90YXRpb24nLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSk7XG5cdG1lc2hSZWYgPSB2aWV3Q2hpbGQucmVxdWlyZWQ8RWxlbWVudFJlZjxNZXNoPj4oJ21lc2gnKTtcblxuXHRwaXZvdENvbnRyb2xzID0gaW5qZWN0KE5ndHNQaXZvdENvbnRyb2xzKTtcblx0cHJpdmF0ZSBzdG9yZSA9IGluamVjdFN0b3JlKCk7XG5cdHByaXZhdGUgY29udHJvbHMgPSB0aGlzLnN0b3JlLnNlbGVjdCgnY29udHJvbHMnKSBhcyB1bmtub3duIGFzIFNpZ25hbDx7IGVuYWJsZWQ6IGJvb2xlYW4gfT47XG5cdHByaXZhdGUgc2l6ZSA9IHRoaXMuc3RvcmUuc2VsZWN0KCdzaXplJyk7XG5cblx0cHJpdmF0ZSBob3ZlcmVkID0gc2lnbmFsKGZhbHNlKTtcblx0cHJpdmF0ZSBzY2FsZTAgPSAxO1xuXHRwcml2YXRlIHNjYWxlQ3VycmVudCA9IDE7XG5cdHByaXZhdGUgY2xpY2tJbmZvOiB7XG5cdFx0Y2xpY2tQb2ludDogVmVjdG9yMztcblx0XHRkaXI6IFZlY3RvcjM7XG5cdFx0bVBMRzogTWF0cml4NDtcblx0XHRtUExHSW52OiBNYXRyaXg0O1xuXHRcdG9mZnNldE11bHRpcGxpZXI6IG51bWJlcjtcblx0fSB8IG51bGwgPSBudWxsO1xuXG5cdHBvc2l0aW9uID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMucGl2b3RDb250cm9scy5maXhlZCgpID8gMS4yIDogMS4yICogdGhpcy5waXZvdENvbnRyb2xzLnNjYWxlKCkpKTtcblx0cmFkaXVzID0gY29tcHV0ZWQoKCkgPT5cblx0XHR0aGlzLnBpdm90Q29udHJvbHMuZml4ZWQoKVxuXHRcdFx0PyAodGhpcy5waXZvdENvbnRyb2xzLmxpbmVXaWR0aCgpIC8gdGhpcy5waXZvdENvbnRyb2xzLnNjYWxlKCkpICogMS44XG5cdFx0XHQ6IHRoaXMucGl2b3RDb250cm9scy5zY2FsZSgpIC8gMjIuNSxcblx0KTtcblx0bWF0cml4TCA9IGNvbXB1dGVkKCgpID0+IHtcblx0XHRjb25zdCBxdWF0ZXJuaW9uID0gbmV3IFF1YXRlcm5pb24oKS5zZXRGcm9tVW5pdFZlY3RvcnModXBWLCB0aGlzLmRpcmVjdGlvbigpLmNsb25lKCkubm9ybWFsaXplKCkpO1xuXHRcdHJldHVybiBuZXcgTWF0cml4NCgpLm1ha2VSb3RhdGlvbkZyb21RdWF0ZXJuaW9uKHF1YXRlcm5pb24pO1xuXHR9KTtcblx0Y29sb3IgPSBjb21wdXRlZCgoKSA9PlxuXHRcdHRoaXMuaG92ZXJlZCgpID8gdGhpcy5waXZvdENvbnRyb2xzLmhvdmVyZWRDb2xvcigpIDogdGhpcy5waXZvdENvbnRyb2xzLmF4aXNDb2xvcnMoKVt0aGlzLmF4aXMoKV0sXG5cdCk7XG5cblx0Y29uc3RydWN0b3IoKSB7XG5cdFx0ZXh0ZW5kKHsgR3JvdXAsIE1lc2gsIFNwaGVyZUdlb21ldHJ5LCBNZXNoQmFzaWNNYXRlcmlhbCB9KTtcblx0fVxuXG5cdG9uUG9pbnRlckRvd24oZXZlbnQ6IE5ndFRocmVlRXZlbnQ8UG9pbnRlckV2ZW50Pikge1xuXHRcdGNvbnN0IFthbm5vdGF0aW9uLCBjb250cm9scywgZml4ZWQsIHNjYWxlLCBkaXJlY3Rpb24sIGF4aXMsIHNpemUsIGdyb3VwXSA9IFtcblx0XHRcdHRoaXMuYW5ub3RhdGlvblJlZigpPy5uYXRpdmVFbGVtZW50LFxuXHRcdFx0dGhpcy5jb250cm9scygpLFxuXHRcdFx0dGhpcy5waXZvdENvbnRyb2xzLmZpeGVkKCksXG5cdFx0XHR0aGlzLnBpdm90Q29udHJvbHMuc2NhbGUoKSxcblx0XHRcdHRoaXMuZGlyZWN0aW9uKCksXG5cdFx0XHR0aGlzLmF4aXMoKSxcblx0XHRcdHRoaXMuc2l6ZSgpLFxuXHRcdFx0dGhpcy5ncm91cFJlZigpLm5hdGl2ZUVsZW1lbnQsXG5cdFx0XTtcblxuXHRcdGlmIChhbm5vdGF0aW9uKSB7XG5cdFx0XHRhbm5vdGF0aW9uLmlubmVyVGV4dCA9IGAke3NjYWxlLnRvRml4ZWQoMil9YDtcblx0XHRcdGFubm90YXRpb24uc3R5bGUuZGlzcGxheSA9ICdibG9jayc7XG5cdFx0fVxuXG5cdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0Y29uc3Qgcm90YXRpb24gPSBuZXcgTWF0cml4NCgpLmV4dHJhY3RSb3RhdGlvbihncm91cC5tYXRyaXhXb3JsZCk7XG5cdFx0Y29uc3QgY2xpY2tQb2ludCA9IGV2ZW50LnBvaW50LmNsb25lKCk7XG5cdFx0Y29uc3Qgb3JpZ2luID0gbmV3IFZlY3RvcjMoKS5zZXRGcm9tTWF0cml4UG9zaXRpb24oZ3JvdXAubWF0cml4V29ybGQpO1xuXHRcdGNvbnN0IGRpciA9IGRpcmVjdGlvbi5jbG9uZSgpLmFwcGx5TWF0cml4NChyb3RhdGlvbikubm9ybWFsaXplKCk7XG5cdFx0Y29uc3QgbVBMRyA9IGdyb3VwLm1hdHJpeFdvcmxkLmNsb25lKCk7XG5cdFx0Y29uc3QgbVBMR0ludiA9IG1QTEcuY2xvbmUoKS5pbnZlcnQoKTtcblx0XHRjb25zdCBvZmZzZXRNdWx0aXBsaWVyID0gZml4ZWRcblx0XHRcdD8gMSAvIGNhbGN1bGF0ZVNjYWxlRmFjdG9yKGdyb3VwLmdldFdvcmxkUG9zaXRpb24odmVjMSksIHNjYWxlLCBldmVudC5jYW1lcmEsIHNpemUpXG5cdFx0XHQ6IDE7XG5cdFx0dGhpcy5jbGlja0luZm8gPSB7IGNsaWNrUG9pbnQsIGRpciwgbVBMRywgbVBMR0ludiwgb2Zmc2V0TXVsdGlwbGllciB9O1xuXHRcdHRoaXMucGl2b3RDb250cm9scy5vbkRyYWdTdGFydCh7IGNvbXBvbmVudDogJ1NwaGVyZScsIGF4aXMsIG9yaWdpbiwgZGlyZWN0aW9uczogW2Rpcl0gfSk7XG5cblx0XHRpZiAoY29udHJvbHMpIHtcblx0XHRcdGNvbnRyb2xzLmVuYWJsZWQgPSBmYWxzZTtcblx0XHR9XG5cdFx0Ly8gQHRzLWV4cGVjdC1lcnJvciAtIHNldFBvaW50ZXJDYXB0dXJlIGlzIG5vdCBpbiB0aGUgdHlwZSBkZWZpbml0aW9uXG5cdFx0ZXZlbnQudGFyZ2V0LnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cdH1cblxuXHRvblBvaW50ZXJNb3ZlKGV2ZW50OiBOZ3RUaHJlZUV2ZW50PFBvaW50ZXJFdmVudD4pIHtcblx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRpZiAoIXRoaXMuaG92ZXJlZCgpKSB0aGlzLmhvdmVyZWQuc2V0KHRydWUpO1xuXG5cdFx0aWYgKHRoaXMuY2xpY2tJbmZvKSB7XG5cdFx0XHRjb25zdCB7IGNsaWNrUG9pbnQsIGRpciwgbVBMRywgbVBMR0ludiwgb2Zmc2V0TXVsdGlwbGllciB9ID0gdGhpcy5jbGlja0luZm87XG5cdFx0XHRjb25zdCBbc2NhbGVMaW1pdHMsIGF4aXMsIHBvc2l0aW9uLCBhbm5vdGF0aW9uLCBmaXhlZCwgc2NhbGUsIG1lc2hdID0gW1xuXHRcdFx0XHR0aGlzLnBpdm90Q29udHJvbHMuc2NhbGVMaW1pdHMoKSxcblx0XHRcdFx0dGhpcy5heGlzKCksXG5cdFx0XHRcdHRoaXMucG9zaXRpb24oKSxcblx0XHRcdFx0dGhpcy5hbm5vdGF0aW9uUmVmKCk/Lm5hdGl2ZUVsZW1lbnQsXG5cdFx0XHRcdHRoaXMucGl2b3RDb250cm9scy5maXhlZCgpLFxuXHRcdFx0XHR0aGlzLnBpdm90Q29udHJvbHMuc2NhbGUoKSxcblx0XHRcdFx0dGhpcy5tZXNoUmVmKCkubmF0aXZlRWxlbWVudCxcblx0XHRcdF07XG5cblx0XHRcdGNvbnN0IFttaW4sIG1heF0gPSBzY2FsZUxpbWl0cz8uW2F4aXNdIHx8IFsxZS01LCB1bmRlZmluZWRdOyAvLyBhbHdheXMgbGltaXQgdGhlIG1pbmltYWwgdmFsdWUsIHNpbmNlIHNldHRpbmcgaXQgdmVyeSBsb3cgbWlnaHQgYnJlYWsgdGhlIHRyYW5zZm9ybVxuXHRcdFx0Y29uc3Qgb2Zmc2V0VyA9IGNhbGN1bGF0ZU9mZnNldChjbGlja1BvaW50LCBkaXIsIGV2ZW50LnJheS5vcmlnaW4sIGV2ZW50LnJheS5kaXJlY3Rpb24pO1xuXHRcdFx0Y29uc3Qgb2Zmc2V0TCA9IG9mZnNldFcgKiBvZmZzZXRNdWx0aXBsaWVyO1xuXHRcdFx0Y29uc3Qgb2Zmc2V0SCA9IGZpeGVkID8gb2Zmc2V0TCA6IG9mZnNldEwgLyBzY2FsZTtcblx0XHRcdGxldCB1cHNjYWxlID0gTWF0aC5wb3coMiwgb2Zmc2V0SCAqIDAuMik7XG5cblx0XHRcdGlmIChldmVudC5zaGlmdEtleSkge1xuXHRcdFx0XHR1cHNjYWxlID0gTWF0aC5yb3VuZCh1cHNjYWxlICogMTApIC8gMTA7XG5cdFx0XHR9XG5cblx0XHRcdHVwc2NhbGUgPSBNYXRoLm1heCh1cHNjYWxlLCBtaW4gLyB0aGlzLnNjYWxlMCk7XG5cblx0XHRcdGlmIChtYXggIT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHR1cHNjYWxlID0gTWF0aC5taW4odXBzY2FsZSwgbWF4IC8gdGhpcy5zY2FsZTApO1xuXHRcdFx0fVxuXG5cdFx0XHR0aGlzLnNjYWxlQ3VycmVudCA9IHRoaXMuc2NhbGUwICogdXBzY2FsZTtcblx0XHRcdG1lc2gucG9zaXRpb24uc2V0KDAsIHBvc2l0aW9uICsgb2Zmc2V0TCwgMCk7XG5cblx0XHRcdGlmIChhbm5vdGF0aW9uKSB7XG5cdFx0XHRcdGFubm90YXRpb24uaW5uZXJUZXh0ID0gYCR7dGhpcy5zY2FsZUN1cnJlbnQudG9GaXhlZCgyKX1gO1xuXHRcdFx0fVxuXG5cdFx0XHRzY2FsZVYuc2V0KDEsIDEsIDEpO1xuXHRcdFx0c2NhbGVWLnNldENvbXBvbmVudChheGlzLCB1cHNjYWxlKTtcblx0XHRcdHNjYWxlTWF0cml4Lm1ha2VTY2FsZShzY2FsZVYueCwgc2NhbGVWLnksIHNjYWxlVi56KS5wcmVtdWx0aXBseShtUExHKS5tdWx0aXBseShtUExHSW52KTtcblx0XHRcdHRoaXMucGl2b3RDb250cm9scy5vbkRyYWcoc2NhbGVNYXRyaXgpO1xuXHRcdH1cblx0fVxuXG5cdG9uUG9pbnRlclVwKGV2ZW50OiBOZ3RUaHJlZUV2ZW50PFBvaW50ZXJFdmVudD4pIHtcblx0XHRjb25zdCBbYW5ub3RhdGlvbiwgY29udHJvbHMsIHBvc2l0aW9uLCBtZXNoXSA9IFtcblx0XHRcdHRoaXMuYW5ub3RhdGlvblJlZigpPy5uYXRpdmVFbGVtZW50LFxuXHRcdFx0dGhpcy5jb250cm9scygpLFxuXHRcdFx0dGhpcy5wb3NpdGlvbigpLFxuXHRcdFx0dGhpcy5tZXNoUmVmKCkubmF0aXZlRWxlbWVudCxcblx0XHRdO1xuXG5cdFx0aWYgKGFubm90YXRpb24pIHtcblx0XHRcdGFubm90YXRpb24uc3R5bGUuZGlzcGxheSA9ICdub25lJztcblx0XHR9XG5cblx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHR0aGlzLnNjYWxlMCA9IHRoaXMuc2NhbGVDdXJyZW50O1xuXHRcdHRoaXMuY2xpY2tJbmZvID0gbnVsbDtcblx0XHRtZXNoLnBvc2l0aW9uLnNldCgwLCBwb3NpdGlvbiwgMCk7XG5cdFx0dGhpcy5waXZvdENvbnRyb2xzLm9uRHJhZ0VuZCgpO1xuXHRcdGlmIChjb250cm9scykge1xuXHRcdFx0Y29udHJvbHMuZW5hYmxlZCA9IHRydWU7XG5cdFx0fVxuXHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgLSByZWxlYXNlUG9pbnRlckNhcHR1cmUgaXMgbm90IGluIHRoZSB0eXBlIGRlZmluaXRpb25cblx0XHRldmVudC50YXJnZXQucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cdH1cblxuXHRvblBvaW50ZXJPdXQoZXZlbnQ6IE5ndFRocmVlRXZlbnQ8UG9pbnRlckV2ZW50Pikge1xuXHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdHRoaXMuaG92ZXJlZC5zZXQoZmFsc2UpO1xuXHR9XG59XG4iXX0=