@jax-data-science/sci-image-visualizer 0.16.0 → 0.18.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 (127) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +4 -2
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +1 -1
  4. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  5. package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
  9. package/esm2022/lib/geometry/place.mjs +47 -0
  10. package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
  11. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  12. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
  13. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  14. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +86 -18
  15. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
  16. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +343 -18
  17. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +427 -0
  18. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
  20. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
  21. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +35 -8
  22. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
  23. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +136 -28
  24. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +19 -3
  25. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +188 -52
  26. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +35 -11
  27. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
  28. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
  29. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
  30. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
  31. package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
  32. package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
  33. package/esm2022/lib/region-source/region-tiles.mjs +1 -1
  34. package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
  35. package/esm2022/lib/routing-visualizer.service.mjs +404 -7
  36. package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
  37. package/esm2022/lib/spatial/plane-cells.mjs +119 -0
  38. package/esm2022/lib/spatial/spatial-controls.facade.mjs +304 -8
  39. package/esm2022/lib/spatial/spatial-encoding.mjs +52 -3
  40. package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
  41. package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
  42. package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
  43. package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
  44. package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
  45. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
  46. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
  47. package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
  48. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +51 -12
  49. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
  50. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +21 -6
  51. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +94 -13
  52. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  53. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  54. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
  55. package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
  56. package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
  57. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
  58. package/esm2022/lib/store/region-source-scope.mjs +10 -1
  59. package/esm2022/lib/store/region-store.service.mjs +33 -2
  60. package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
  61. package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
  62. package/esm2022/lib/visualizer.component.mjs +40 -4
  63. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs} +4838 -656
  64. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CBiLcnE6.mjs.map +1 -0
  65. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs} +2 -2
  66. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DaZVXq1s.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-BXHjv4PE.mjs.map} +1 -1
  67. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  68. package/fesm2022/region-source.worker.js +84 -2
  69. package/lib/contracts/display-types.d.ts +99 -6
  70. package/lib/contracts/image.contract.d.ts +6 -0
  71. package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
  72. package/lib/contracts/region-editor-api.contract.d.ts +9 -0
  73. package/lib/contracts/region-store.contract.d.ts +6 -0
  74. package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
  75. package/lib/contracts/visualizer.contract.d.ts +43 -1
  76. package/lib/geometry/cell-meshes.d.ts +27 -0
  77. package/lib/geometry/place.d.ts +45 -0
  78. package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
  79. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  80. package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
  81. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
  82. package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
  83. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +89 -0
  84. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +103 -0
  85. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
  86. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
  87. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
  88. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +20 -6
  89. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
  90. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +48 -16
  91. package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
  92. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +54 -1
  93. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
  94. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
  95. package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
  96. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
  97. package/lib/region-editor/region-editor.component.d.ts +4 -0
  98. package/lib/region-source/region-source-ops.d.ts +12 -0
  99. package/lib/region-source/region-tiles.d.ts +8 -0
  100. package/lib/region-source/worker-region-source.d.ts +18 -0
  101. package/lib/routing-visualizer.service.d.ts +140 -1
  102. package/lib/spatial/observations-in-selection.d.ts +43 -0
  103. package/lib/spatial/plane-cells.d.ts +37 -0
  104. package/lib/spatial/spatial-controls.facade.d.ts +59 -0
  105. package/lib/spatial/spatial-encoding.d.ts +24 -1
  106. package/lib/spatial/spatial-hover.d.ts +23 -0
  107. package/lib/spatial/spatial-planes.d.ts +22 -0
  108. package/lib/spatial/spatial-selection.d.ts +2 -1
  109. package/lib/spatial/spatial-tile-merge.d.ts +9 -0
  110. package/lib/spatial/transcripts-in-selection.d.ts +95 -0
  111. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
  112. package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
  113. package/lib/spatial-controls/spatial-controls.component.d.ts +19 -2
  114. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
  115. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +7 -0
  116. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +28 -7
  117. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
  118. package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
  119. package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
  120. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
  121. package/lib/store/region-source-scope.d.ts +4 -0
  122. package/lib/store/region-store.service.d.ts +21 -0
  123. package/lib/toolbar/toolbar.component.d.ts +6 -1
  124. package/lib/visualizer/spatial-region-set.d.ts +55 -0
  125. package/lib/visualizer.component.d.ts +14 -0
  126. package/package.json +2 -2
  127. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-CYsPzX3J.mjs.map +0 -1
@@ -1,40 +1,77 @@
1
+ import { sliceZ, toWorld } from '../../geometry/place';
2
+ export { sliceZ, toWorld };
1
3
  /** Opacity of a region's surface in the volume. */
2
4
  export const REGION_MESH_OPACITY = 0.55;
3
5
  /** While some surfaces are highlighted: theirs (near opaque, so their shape reads) … */
4
6
  export const REGION_MESH_HIGHLIGHT_OPACITY = 0.9;
5
7
  /** … and the others' (ghosted: still there for context, not in the way). */
6
8
  export const REGION_MESH_DIMMED_OPACITY = 0.12;
9
+ /**
10
+ * A selection's surfaces while the others are ghosted: opaque, so they are drawn first and write
11
+ * depth, and the ghosted surfaces in front of them are blended over them rather than hiding them
12
+ * (a translucent surface draws only its own nearest faces, and is drawn after the opaque ones).
13
+ */
14
+ export const REGION_MESH_SELECTED_OPACITY = 1;
7
15
  /**
8
16
  * The region reconstructions shown in a volume view: one translucent surface per region, in its
9
17
  * colour, placed in the volume's world box (pixel x, y and slice z mapped onto it the way the
10
- * volume maps its voxels) and re-placed when the volume's Z is stretched. A surface is updated in
11
- * place (`setData`, `color`) rather than added again, and picked by napari-js (`pickSurface`).
18
+ * volume maps its voxels). The box's Z stretch is the surfaces' `scale3d` (a uniform), so a stretch
19
+ * alone changes no geometry; a new box re-places them. A surface is updated in place (`setData`,
20
+ * `color`, `scale3d`) rather than added again, and picked by napari-js (`pickSurface`), which
21
+ * picks it where it is drawn.
12
22
  *
13
23
  * Highlighting is focus + context: the highlighted surfaces turn near opaque and the others fade
14
24
  * to a ghost, so the selection stands out while staying in place among its neighbours.
15
25
  */
16
26
  export class VolumeRegionMeshes {
17
- constructor(viewer) {
27
+ /**
28
+ * `placer`, when given, places a mesh's vertices in the world off the main thread (a worker, see
29
+ * `placeInWorker`): a class's surface has hundreds of thousands of vertices, and placing every
30
+ * one in a loop here held the UI for seconds. Each surface then comes up as its placement lands,
31
+ * the one it replaces kept until then. Without one, they are placed at once (the tests).
32
+ */
33
+ constructor(viewer, placer) {
18
34
  this.viewer = viewer;
35
+ this.placer = placer;
19
36
  this.layers = new Map();
20
37
  this.highlighted = new Set();
21
38
  this.hidden = new Set();
39
+ /** Surfaces faded: none of what is selected is in them. */
40
+ this.muted = new Set();
22
41
  /** The meshes to show (kept while the volume has no frame yet). */
23
42
  this.wanted = [];
24
43
  this.frame = null;
44
+ /** The placements in flight, by key: the mesh and box each is for. */
45
+ this.placing = new Map();
46
+ this.token = 0;
25
47
  }
26
48
  /** Show exactly `meshes` (adding, keeping or removing surfaces). */
27
49
  set(meshes) {
28
50
  this.wanted = meshes;
29
51
  this.sync();
30
52
  }
31
- /** Follow the volume's frame (it opened, or its Z was stretched): re-place every surface. */
53
+ /**
54
+ * Follow the volume's frame. A new box (it opened, another volume) re-places every surface; a Z
55
+ * stretch of the same box only sets their `scale3d`, so nothing is re-uploaded while dragging.
56
+ */
32
57
  setFrame(frame) {
58
+ const placed = this.frame ? baseFrame(this.frame) : null;
59
+ const next = baseFrame(frame);
60
+ const sameBox = !!placed && sameFrame(placed, next);
33
61
  this.frame = frame;
34
- for (const e of this.layers.values())
35
- e.layer.setData(toWorld(e.mesh.vertices, frame), e.mesh.faces);
62
+ const scale = this.scale3d();
63
+ for (const e of this.layers.values()) {
64
+ if (!sameBox)
65
+ this.place(e.mesh);
66
+ e.layer.scale3d = scale;
67
+ }
36
68
  this.sync();
37
69
  }
70
+ /** The surfaces' GPU scale: the frame's Z stretch. */
71
+ scale3d() {
72
+ const s = this.frame?.zScale;
73
+ return [1, 1, s && s > 0 ? s : 1];
74
+ }
38
75
  /** Highlight the surfaces of these keys (none: every surface as usual). */
39
76
  setHighlight(keys) {
40
77
  this.highlighted = new Set(keys);
@@ -42,6 +79,20 @@ export class VolumeRegionMeshes {
42
79
  e.layer.opacity = this.opacityOf(key);
43
80
  this.viewer.requestRender();
44
81
  }
82
+ /**
83
+ * Fade the surfaces of these keys, as a picked region fades the others (none: each as usual):
84
+ * with a selection, the regions none of it is in fade and those it is in come forward, each
85
+ * keeping its colour.
86
+ */
87
+ setMuted(keys) {
88
+ const next = new Set(keys);
89
+ if (next.size === this.muted.size && [...next].every((k) => this.muted.has(k)))
90
+ return;
91
+ this.muted = next;
92
+ for (const [key, e] of this.layers)
93
+ e.layer.opacity = this.opacityOf(key);
94
+ this.viewer.requestRender();
95
+ }
45
96
  /** Hide the surfaces of these keys (they are kept, so showing them again is instant). */
46
97
  setHidden(keys) {
47
98
  this.hidden = new Set(keys);
@@ -85,24 +136,67 @@ export class VolumeRegionMeshes {
85
136
  continue;
86
137
  }
87
138
  // Rebuilt or recoloured: the same surface, updated in place.
88
- if (want.vertices !== e.mesh.vertices && this.frame) {
89
- e.layer.setData(toWorld(want.vertices, this.frame), want.faces);
90
- }
139
+ const rebuilt = want.vertices !== e.mesh.vertices;
91
140
  if (want.color !== e.mesh.color)
92
141
  e.layer.color = want.color;
93
142
  e.mesh = want;
143
+ if (rebuilt && this.frame)
144
+ this.place(want);
94
145
  }
95
146
  if (this.frame) {
96
147
  for (const mesh of this.wanted)
97
148
  if (!this.layers.has(mesh.key) && mesh.faces.length)
98
- this.add(mesh);
149
+ this.place(mesh);
99
150
  }
100
151
  this.viewer.requestRender();
101
152
  }
102
- add(mesh) {
153
+ /**
154
+ * Place `mesh` in the current box, adding its surface or updating it: at once, or through the
155
+ * placer, its result kept only if the mesh and the box are still the ones wanted. A placement
156
+ * already in flight for the same mesh and box is not asked again.
157
+ */
158
+ place(mesh) {
103
159
  const frame = this.frame;
104
- const layer = this.viewer.addSurface(toWorld(mesh.vertices, frame), mesh.faces, undefined, {
160
+ if (!frame)
161
+ return;
162
+ const base = baseFrame(frame);
163
+ if (!this.placer) {
164
+ this.apply(mesh, toWorld(mesh.vertices, base));
165
+ return;
166
+ }
167
+ const pending = this.placing.get(mesh.key);
168
+ if (pending && pending.mesh === mesh && sameFrame(pending.frame, base))
169
+ return;
170
+ const token = ++this.token;
171
+ this.placing.set(mesh.key, { mesh, frame: base, token });
172
+ this.placer(mesh.vertices, base).then((world) => {
173
+ if (this.placing.get(mesh.key)?.token !== token)
174
+ return;
175
+ this.placing.delete(mesh.key);
176
+ const wanted = this.wanted.find((m) => m.key === mesh.key);
177
+ if (wanted !== mesh || !this.frame || !sameFrame(baseFrame(this.frame), base))
178
+ return;
179
+ this.apply(mesh, world);
180
+ this.viewer.requestRender();
181
+ }, (err) => {
182
+ if (this.placing.get(mesh.key)?.token === token)
183
+ this.placing.delete(mesh.key);
184
+ console.warn(`[napari-js] region ${mesh.key} could not be placed in 3D`, err);
185
+ });
186
+ }
187
+ /** `mesh`'s surface with its vertices placed at `world`: updated in place, or added. */
188
+ apply(mesh, world) {
189
+ const e = this.layers.get(mesh.key);
190
+ if (e) {
191
+ e.layer.setData(world, mesh.faces);
192
+ return;
193
+ }
194
+ this.add(mesh, world);
195
+ }
196
+ add(mesh, world) {
197
+ const layer = this.viewer.addSurface(world, mesh.faces, undefined, {
105
198
  name: `region ${mesh.key}`,
199
+ scale3d: this.scale3d(),
106
200
  color: mesh.color,
107
201
  opacity: this.opacityOf(mesh.key),
108
202
  blending: 'translucent',
@@ -112,28 +206,42 @@ export class VolumeRegionMeshes {
112
206
  this.layers.set(mesh.key, { mesh, layer });
113
207
  }
114
208
  opacityOf(key) {
209
+ if (this.muted.size)
210
+ return this.muted.has(key) ? REGION_MESH_DIMMED_OPACITY : REGION_MESH_SELECTED_OPACITY;
115
211
  if (!this.highlighted.size)
116
212
  return REGION_MESH_OPACITY;
117
- return this.highlighted.has(key) ? REGION_MESH_HIGHLIGHT_OPACITY : REGION_MESH_DIMMED_OPACITY;
213
+ return this.highlighted.has(key) ? REGION_MESH_SELECTED_OPACITY : REGION_MESH_DIMMED_OPACITY;
118
214
  }
119
215
  remove(key, layer) {
120
216
  this.viewer.layers.remove(layer);
121
217
  this.layers.delete(key);
218
+ this.placing.delete(key);
122
219
  }
123
220
  }
124
- /**
125
- * Image px / slice coordinates → the volume's centred world box: pixel x of a `w`-wide image
126
- * spans the box's width, slice k sits at the middle of its share of the box's depth.
127
- */
128
- export function toWorld(vertices, frame) {
129
- const [w, h, d] = frame.size;
130
- const [ww, wh, wd] = frame.world;
131
- const out = new Float32Array(vertices.length);
132
- for (let i = 0; i < vertices.length; i += 3) {
133
- out[i] = (vertices[i] / w - 0.5) * ww;
134
- out[i + 1] = (vertices[i + 1] / h - 0.5) * wh;
135
- out[i + 2] = ((vertices[i + 2] + 0.5) / d - 0.5) * wd;
136
- }
137
- return out;
221
+ /** `frame` without its Z stretch: the box the surfaces' geometry is placed in. */
222
+ function baseFrame(frame) {
223
+ const s = frame.zScale && frame.zScale > 0 ? frame.zScale : 1;
224
+ if (s === 1)
225
+ return frame;
226
+ return {
227
+ size: frame.size,
228
+ world: [frame.world[0], frame.world[1], frame.world[2] / s],
229
+ ...(frame.planes ? { planes: frame.planes } : {}),
230
+ };
231
+ }
232
+ /** Whether two unstretched frames place a surface alike. */
233
+ function sameFrame(a, b) {
234
+ const near = (x, y) => Math.abs(x - y) <= 1e-9 * Math.max(1, Math.abs(x));
235
+ if (a.planes || b.planes) {
236
+ const p = a.planes;
237
+ const q = b.planes;
238
+ return (!!p &&
239
+ !!q &&
240
+ p.z.length === q.z.length &&
241
+ p.z.every((v, i) => near(v, q.z[i])) &&
242
+ p.scale.every((v, i) => near(v, q.scale[i])) &&
243
+ p.offset.every((v, i) => near(v, q.offset[i])));
244
+ }
245
+ return a.size.every((v, i) => v === b.size[i]) && a.world.every((v, i) => near(v, b.world[i]));
138
246
  }
139
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXZvbHVtZS1yZWdpb24tbWVzaGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS12b2x1bWUtcmVnaW9uLW1lc2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFzQkEsbURBQW1EO0FBQ25ELE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUN4Qyx3RkFBd0Y7QUFDeEYsTUFBTSxDQUFDLE1BQU0sNkJBQTZCLEdBQUcsR0FBRyxDQUFDO0FBQ2pELDRFQUE0RTtBQUM1RSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxJQUFJLENBQUM7QUFFL0M7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBUTdCLFlBQTZCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBUDFCLFdBQU0sR0FBRyxJQUFJLEdBQUcsRUFBdUQsQ0FBQztRQUNqRixnQkFBVyxHQUF3QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzdDLFdBQU0sR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUNoRCxtRUFBbUU7UUFDM0QsV0FBTSxHQUE0QixFQUFFLENBQUM7UUFDckMsVUFBSyxHQUF1QixJQUFJLENBQUM7SUFFSyxDQUFDO0lBRS9DLG9FQUFvRTtJQUNwRSxHQUFHLENBQUMsTUFBK0I7UUFDakMsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVELDZGQUE2RjtJQUM3RixRQUFRLENBQUMsS0FBa0I7UUFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsS0FBSyxNQUFNLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRTtZQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE9B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QUFDLENBQUMsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ3hELENBQUM7SUFDRCxPQUFPLEdBQUcsQ0FBQztBQUNiLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IFN1cmZhY2VMYXllciwgVmlld2VyIH0gZnJvbSAnbmFwYXJpLWpzJztcblxuLyoqIEEgcmVnaW9uJ3MgM0QgcmVjb25zdHJ1Y3Rpb24gdG8gc2hvdyBpbiB0aGUgdm9sdW1lOiBhIG1lc2ggaW4gaW1hZ2UgcHggKHgsIHkpIGFuZCBzbGljZXMgKHopLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWdpb25NZXNoM0Qge1xuICAvKiogSWRlbnRpdHkgKGEgY2xhc3MgbmFtZSk6IGEgbWVzaCB3aXRoIHRoZSBzYW1lIGtleSBhbmQgYXJyYXlzIGlzIGtlcHQsIG5vdCByZWJ1aWx0LiAqL1xuICBrZXk6IHN0cmluZztcbiAgLyoqIGAjcnJnZ2JiYC4gKi9cbiAgY29sb3I6IHN0cmluZztcbiAgLyoqIFdoYXQgaG92ZXJpbmcgaXQgc2hvd3MgKFwiSFBGIMK3IEhpcHBvY2FtcGFsIGZvcm1hdGlvblwiKTsgZGVmYXVsdDogdGhlIGtleS4gKi9cbiAgbGFiZWw/OiBzdHJpbmc7XG4gIHZlcnRpY2VzOiBGbG9hdDMyQXJyYXk7XG4gIGZhY2VzOiBVaW50MzJBcnJheTtcbn1cblxuLyoqIFdoZXJlIHRoZSBzdGFjayBzaXRzIGluIHRoZSB2b2x1bWUncyB3b3JsZDogaXRzIGZ1bGwgc2l6ZSwgYW5kIHRoZSBjZW50cmVkIHdvcmxkIGJveCBpdCBmaWxscy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVm9sdW1lRnJhbWUge1xuICAvKiogSW1hZ2Ugd2lkdGgsIGhlaWdodCAocHgpIGFuZCBzbGljZSBjb3VudC4gKi9cbiAgc2l6ZTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAvKiogVGhlIHdvcmxkIGJveCAoY2VudHJlZCBvbiB0aGUgb3JpZ2luKSwgWiBhcyBjdXJyZW50bHkgc3RyZXRjaGVkLiAqL1xuICB3b3JsZDogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xufVxuXG4vKiogT3BhY2l0eSBvZiBhIHJlZ2lvbidzIHN1cmZhY2UgaW4gdGhlIHZvbHVtZS4gKi9cbmV4cG9ydCBjb25zdCBSRUdJT05fTUVTSF9PUEFDSVRZID0gMC41NTtcbi8qKiBXaGlsZSBzb21lIHN1cmZhY2VzIGFyZSBoaWdobGlnaHRlZDogdGhlaXJzIChuZWFyIG9wYXF1ZSwgc28gdGhlaXIgc2hhcGUgcmVhZHMpIOKApiAqL1xuZXhwb3J0IGNvbnN0IFJFR0lPTl9NRVNIX0hJR0hMSUdIVF9PUEFDSVRZID0gMC45O1xuLyoqIOKApiBhbmQgdGhlIG90aGVycycgKGdob3N0ZWQ6IHN0aWxsIHRoZXJlIGZvciBjb250ZXh0LCBub3QgaW4gdGhlIHdheSkuICovXG5leHBvcnQgY29uc3QgUkVHSU9OX01FU0hfRElNTUVEX09QQUNJVFkgPSAwLjEyO1xuXG4vKipcbiAqIFRoZSByZWdpb24gcmVjb25zdHJ1Y3Rpb25zIHNob3duIGluIGEgdm9sdW1lIHZpZXc6IG9uZSB0cmFuc2x1Y2VudCBzdXJmYWNlIHBlciByZWdpb24sIGluIGl0c1xuICogY29sb3VyLCBwbGFjZWQgaW4gdGhlIHZvbHVtZSdzIHdvcmxkIGJveCAocGl4ZWwgeCwgeSBhbmQgc2xpY2UgeiBtYXBwZWQgb250byBpdCB0aGUgd2F5IHRoZVxuICogdm9sdW1lIG1hcHMgaXRzIHZveGVscykgYW5kIHJlLXBsYWNlZCB3aGVuIHRoZSB2b2x1bWUncyBaIGlzIHN0cmV0Y2hlZC4gQSBzdXJmYWNlIGlzIHVwZGF0ZWQgaW5cbiAqIHBsYWNlIChgc2V0RGF0YWAsIGBjb2xvcmApIHJhdGhlciB0aGFuIGFkZGVkIGFnYWluLCBhbmQgcGlja2VkIGJ5IG5hcGFyaS1qcyAoYHBpY2tTdXJmYWNlYCkuXG4gKlxuICogSGlnaGxpZ2h0aW5nIGlzIGZvY3VzICsgY29udGV4dDogdGhlIGhpZ2hsaWdodGVkIHN1cmZhY2VzIHR1cm4gbmVhciBvcGFxdWUgYW5kIHRoZSBvdGhlcnMgZmFkZVxuICogdG8gYSBnaG9zdCwgc28gdGhlIHNlbGVjdGlvbiBzdGFuZHMgb3V0IHdoaWxlIHN0YXlpbmcgaW4gcGxhY2UgYW1vbmcgaXRzIG5laWdoYm91cnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWVSZWdpb25NZXNoZXMge1xuICBwcml2YXRlIHJlYWRvbmx5IGxheWVycyA9IG5ldyBNYXA8c3RyaW5nLCB7IG1lc2g6IFJlZ2lvbk1lc2gzRDsgbGF5ZXI6IFN1cmZhY2VMYXllciB9PigpO1xuICBwcml2YXRlIGhpZ2hsaWdodGVkOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICBwcml2YXRlIGhpZGRlbjogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFRoZSBtZXNoZXMgdG8gc2hvdyAoa2VwdCB3aGlsZSB0aGUgdm9sdW1lIGhhcyBubyBmcmFtZSB5ZXQpLiAqL1xuICBwcml2YXRlIHdhbnRlZDogcmVhZG9ubHkgUmVnaW9uTWVzaDNEW10gPSBbXTtcbiAgcHJpdmF0ZSBmcmFtZTogVm9sdW1lRnJhbWUgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHZpZXdlcjogVmlld2VyKSB7fVxuXG4gIC8qKiBTaG93IGV4YWN0bHkgYG1lc2hlc2AgKGFkZGluZywga2VlcGluZyBvciByZW1vdmluZyBzdXJmYWNlcykuICovXG4gIHNldChtZXNoZXM6IHJlYWRvbmx5IFJlZ2lvbk1lc2gzRFtdKTogdm9pZCB7XG4gICAgdGhpcy53YW50ZWQgPSBtZXNoZXM7XG4gICAgdGhpcy5zeW5jKCk7XG4gIH1cblxuICAvKiogRm9sbG93IHRoZSB2b2x1bWUncyBmcmFtZSAoaXQgb3BlbmVkLCBvciBpdHMgWiB3YXMgc3RyZXRjaGVkKTogcmUtcGxhY2UgZXZlcnkgc3VyZmFjZS4gKi9cbiAgc2V0RnJhbWUoZnJhbWU6IFZvbHVtZUZyYW1lKTogdm9pZCB7XG4gICAgdGhpcy5mcmFtZSA9IGZyYW1lO1xuICAgIGZvciAoY29uc3QgZSBvZiB0aGlzLmxheWVycy52YWx1ZXMoKSkgZS5sYXllci5zZXREYXRhKHRvV29ybGQoZS5tZXNoLnZlcnRpY2VzLCBmcmFtZSksIGUubWVzaC5mYWNlcyk7XG4gICAgdGhpcy5zeW5jKCk7XG4gIH1cblxuICAvKiogSGlnaGxpZ2h0IHRoZSBzdXJmYWNlcyBvZiB0aGVzZSBrZXlzIChub25lOiBldmVyeSBzdXJmYWNlIGFzIHVzdWFsKS4gKi9cbiAgc2V0SGlnaGxpZ2h0KGtleXM6IEl0ZXJhYmxlPHN0cmluZz4pOiB2b2lkIHtcbiAgICB0aGlzLmhpZ2hsaWdodGVkID0gbmV3IFNldChrZXlzKTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIGVdIG9mIHRoaXMubGF5ZXJzKSBlLmxheWVyLm9wYWNpdHkgPSB0aGlzLm9wYWNpdHlPZihrZXkpO1xuICAgIHRoaXMudmlld2VyLnJlcXVlc3RSZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBIaWRlIHRoZSBzdXJmYWNlcyBvZiB0aGVzZSBrZXlzICh0aGV5IGFyZSBrZXB0LCBzbyBzaG93aW5nIHRoZW0gYWdhaW4gaXMgaW5zdGFudCkuICovXG4gIHNldEhpZGRlbihrZXlzOiBJdGVyYWJsZTxzdHJpbmc+KTogdm9pZCB7XG4gICAgdGhpcy5oaWRkZW4gPSBuZXcgU2V0KGtleXMpO1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgdGhpcy5sYXllcnMpIGUubGF5ZXIudmlzaWJsZSA9ICF0aGlzLmhpZGRlbi5oYXMoa2V5KTtcbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICAvKiogVGhlIGZyb250LW1vc3Qgc3VyZmFjZSB1bmRlciBzY3JlZW4gcG9pbnQgKGB4YCwgYHlgKSAoY2FudmFzIENTUyBweCksIG9yIG51bGwuICovXG4gIHBpY2tBdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IFJlZ2lvbk1lc2gzRCB8IG51bGwge1xuICAgIGlmICghdGhpcy5sYXllcnMuc2l6ZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgb3VycyA9IG5ldyBNYXAoWy4uLnRoaXMubGF5ZXJzLnZhbHVlcygpXS5tYXAoKGUpID0+IFtlLmxheWVyLCBlLm1lc2hdKSk7XG4gICAgY29uc3QgaGl0ID0gdGhpcy52aWV3ZXIucGlja1N1cmZhY2UoeCwgeSwgeyBwaWNrYWJsZTogKGxheWVyKSA9PiBvdXJzLmhhcyhsYXllcikgfSk7XG4gICAgcmV0dXJuIGhpdCA/IChvdXJzLmdldChoaXQubGF5ZXIpID8/IG51bGwpIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBUaGUgbWVzaGVzIHNob3duLiAqL1xuICBnZXQgc2hvd24oKTogUmVnaW9uTWVzaDNEW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5sYXllcnMudmFsdWVzKCldLm1hcCgoZSkgPT4gZS5tZXNoKTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgWy4uLnRoaXMubGF5ZXJzXSkgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICB0aGlzLndhbnRlZCA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2b2x1bWUgdGhlIHN1cmZhY2VzIHNhdCBpbiBpcyBnb25lIChvciBubyBsb25nZXIgdGhlaXJzKTogdGFrZSBldmVyeSBzdXJmYWNlIGRvd24sIGtlZXBpbmdcbiAgICogdGhlIG1lc2hlcyB3YW50ZWQsIHNvIHRoZXkgY29tZSBiYWNrIHdoZW4gYSBmcmFtZSBpcyBzZXQgYWdhaW4uXG4gICAqL1xuICBjbGVhckZyYW1lKCk6IHZvaWQge1xuICAgIHRoaXMuZnJhbWUgPSBudWxsO1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgWy4uLnRoaXMubGF5ZXJzXSkgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIHN5bmMoKTogdm9pZCB7XG4gICAgY29uc3Qga2VlcCA9IG5ldyBNYXAodGhpcy53YW50ZWQubWFwKChtKSA9PiBbbS5rZXksIG1dKSk7XG4gICAgZm9yIChjb25zdCBba2V5LCBlXSBvZiBbLi4udGhpcy5sYXllcnNdKSB7XG4gICAgICBjb25zdCB3YW50ID0ga2VlcC5nZXQoa2V5KTtcbiAgICAgIGlmICghd2FudCB8fCAhd2FudC5mYWNlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBSZWJ1aWx0IG9yIHJlY29sb3VyZWQ6IHRoZSBzYW1lIHN1cmZhY2UsIHVwZGF0ZWQgaW4gcGxhY2UuXG4gICAgICBpZiAod2FudC52ZXJ0aWNlcyAhPT0gZS5tZXNoLnZlcnRpY2VzICYmIHRoaXMuZnJhbWUpIHtcbiAgICAgICAgZS5sYXllci5zZXREYXRhKHRvV29ybGQod2FudC52ZXJ0aWNlcywgdGhpcy5mcmFtZSksIHdhbnQuZmFjZXMpO1xuICAgICAgfVxuICAgICAgaWYgKHdhbnQuY29sb3IgIT09IGUubWVzaC5jb2xvcikgZS5sYXllci5jb2xvciA9IHdhbnQuY29sb3I7XG4gICAgICBlLm1lc2ggPSB3YW50O1xuICAgIH1cbiAgICBpZiAodGhpcy5mcmFtZSkge1xuICAgICAgZm9yIChjb25zdCBtZXNoIG9mIHRoaXMud2FudGVkKSBpZiAoIXRoaXMubGF5ZXJzLmhhcyhtZXNoLmtleSkgJiYgbWVzaC5mYWNlcy5sZW5ndGgpIHRoaXMuYWRkKG1lc2gpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZChtZXNoOiBSZWdpb25NZXNoM0QpOiB2b2lkIHtcbiAgICBjb25zdCBmcmFtZSA9IHRoaXMuZnJhbWUgYXMgVm9sdW1lRnJhbWU7XG4gICAgY29uc3QgbGF5ZXIgPSB0aGlzLnZpZXdlci5hZGRTdXJmYWNlKHRvV29ybGQobWVzaC52ZXJ0aWNlcywgZnJhbWUpLCBtZXNoLmZhY2VzLCB1bmRlZmluZWQsIHtcbiAgICAgIG5hbWU6IGByZWdpb24gJHttZXNoLmtleX1gLFxuICAgICAgY29sb3I6IG1lc2guY29sb3IsXG4gICAgICBvcGFjaXR5OiB0aGlzLm9wYWNpdHlPZihtZXNoLmtleSksXG4gICAgICBibGVuZGluZzogJ3RyYW5zbHVjZW50JyxcbiAgICAgIGZpdDogJ25ldmVyJyxcbiAgICB9KTtcbiAgICBsYXllci52aXNpYmxlID0gIXRoaXMuaGlkZGVuLmhhcyhtZXNoLmtleSk7XG4gICAgdGhpcy5sYXllcnMuc2V0KG1lc2gua2V5LCB7IG1lc2gsIGxheWVyIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGFjaXR5T2Yoa2V5OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmICghdGhpcy5oaWdobGlnaHRlZC5zaXplKSByZXR1cm4gUkVHSU9OX01FU0hfT1BBQ0lUWTtcbiAgICByZXR1cm4gdGhpcy5oaWdobGlnaHRlZC5oYXMoa2V5KSA/IFJFR0lPTl9NRVNIX0hJR0hMSUdIVF9PUEFDSVRZIDogUkVHSU9OX01FU0hfRElNTUVEX09QQUNJVFk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZShrZXk6IHN0cmluZywgbGF5ZXI6IFN1cmZhY2VMYXllcik6IHZvaWQge1xuICAgIHRoaXMudmlld2VyLmxheWVycy5yZW1vdmUobGF5ZXIpO1xuICAgIHRoaXMubGF5ZXJzLmRlbGV0ZShrZXkpO1xuICB9XG59XG5cbi8qKlxuICogSW1hZ2UgcHggLyBzbGljZSBjb29yZGluYXRlcyDihpIgdGhlIHZvbHVtZSdzIGNlbnRyZWQgd29ybGQgYm94OiBwaXhlbCB4IG9mIGEgYHdgLXdpZGUgaW1hZ2VcbiAqIHNwYW5zIHRoZSBib3gncyB3aWR0aCwgc2xpY2UgayBzaXRzIGF0IHRoZSBtaWRkbGUgb2YgaXRzIHNoYXJlIG9mIHRoZSBib3gncyBkZXB0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvV29ybGQodmVydGljZXM6IEZsb2F0MzJBcnJheSwgZnJhbWU6IFZvbHVtZUZyYW1lKTogRmxvYXQzMkFycmF5IHtcbiAgY29uc3QgW3csIGgsIGRdID0gZnJhbWUuc2l6ZTtcbiAgY29uc3QgW3d3LCB3aCwgd2RdID0gZnJhbWUud29ybGQ7XG4gIGNvbnN0IG91dCA9IG5ldyBGbG9hdDMyQXJyYXkodmVydGljZXMubGVuZ3RoKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2ZXJ0aWNlcy5sZW5ndGg7IGkgKz0gMykge1xuICAgIG91dFtpXSA9ICh2ZXJ0aWNlc1tpXSAvIHcgLSAwLjUpICogd3c7XG4gICAgb3V0W2kgKyAxXSA9ICh2ZXJ0aWNlc1tpICsgMV0gLyBoIC0gMC41KSAqIHdoO1xuICAgIG91dFtpICsgMl0gPSAoKHZlcnRpY2VzW2kgKyAyXSArIDAuNSkgLyBkIC0gMC41KSAqIHdkO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG4iXX0=
247
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXZvbHVtZS1yZWdpb24tbWVzaGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS12b2x1bWUtcmVnaW9uLW1lc2hlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQStCLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUdwRixPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBaUIzQixtREFBbUQ7QUFDbkQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDO0FBQ3hDLHdGQUF3RjtBQUN4RixNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxHQUFHLENBQUM7QUFDakQsNEVBQTRFO0FBQzVFLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLElBQUksQ0FBQztBQUMvQzs7OztHQUlHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sNEJBQTRCLEdBQUcsQ0FBQyxDQUFDO0FBRTlDOzs7Ozs7Ozs7O0dBVUc7QUFDSCxNQUFNLE9BQU8sa0JBQWtCO0lBYzdCOzs7OztPQUtHO0lBQ0gsWUFDbUIsTUFBYyxFQUNkLE1BQXFCO1FBRHJCLFdBQU0sR0FBTixNQUFNLENBQVE7UUFDZCxXQUFNLEdBQU4sTUFBTSxDQUFlO1FBckJ2QixXQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXVELENBQUM7UUFDakYsZ0JBQVcsR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUM3QyxXQUFNLEdBQXdCLElBQUksR0FBRyxFQUFFLENBQUM7UUFDaEQsMkRBQTJEO1FBQ25ELFVBQUssR0FBd0IsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQUMvQyxtRUFBbUU7UUFDM0QsV0FBTSxHQUE0QixFQUFFLENBQUM7UUFDckMsVUFBSyxHQUF1QixJQUFJLENBQUM7UUFFekMsc0VBQXNFO1FBQ3JELFlBQU8sR0FBRyxJ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RSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3BDLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUMvQyxDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBTdXJmYWNlTGF5ZXIsIFZpZXdlciB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbmltcG9ydCB7IFBsYW5lUGxhY2VtZW50LCBWb2x1bWVGcmFtZSwgc2xpY2VaLCB0b1dvcmxkIH0gZnJvbSAnLi4vLi4vZ2VvbWV0cnkvcGxhY2UnO1xuXG5leHBvcnQgdHlwZSB7IFBsYW5lUGxhY2VtZW50LCBWb2x1bWVGcmFtZSB9O1xuZXhwb3J0IHsgc2xpY2VaLCB0b1dvcmxkIH07XG5cbi8qKiBBIHJlZ2lvbidzIDNEIHJlY29uc3RydWN0aW9uIHRvIHNob3cgaW4gdGhlIHZvbHVtZTogYSBtZXNoIGluIGltYWdlIHB4ICh4LCB5KSBhbmQgc2xpY2VzICh6KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVnaW9uTWVzaDNEIHtcbiAgLyoqIElkZW50aXR5IChhIGNsYXNzIG5hbWUpOiBhIG1lc2ggd2l0aCB0aGUgc2FtZSBrZXkgYW5kIGFycmF5cyBpcyBrZXB0LCBub3QgcmVidWlsdC4gKi9cbiAga2V5OiBzdHJpbmc7XG4gIC8qKiBgI3JyZ2diYmAuICovXG4gIGNvbG9yOiBzdHJpbmc7XG4gIC8qKiBXaGF0IGhvdmVyaW5nIGl0IHNob3dzIChcIkhQRiDCtyBIaXBwb2NhbXBhbCBmb3JtYXRpb25cIik7IGRlZmF1bHQ6IHRoZSBrZXkuICovXG4gIGxhYmVsPzogc3RyaW5nO1xuICB2ZXJ0aWNlczogRmxvYXQzMkFycmF5O1xuICBmYWNlczogVWludDMyQXJyYXk7XG59XG5cbi8qKiBQbGFjZXMgYSBtZXNoJ3MgdmVydGljZXMgKGltYWdlIHB4LCBzbGljZXMpIGluIGEgM0QgdmlldydzIHdvcmxkLCBvZmYgdGhlIG1haW4gdGhyZWFkLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uUGxhY2VyID0gKHZlcnRpY2VzOiBGbG9hdDMyQXJyYXksIGZyYW1lOiBWb2x1bWVGcmFtZSkgPT4gUHJvbWlzZTxGbG9hdDMyQXJyYXk+O1xuXG4vKiogT3BhY2l0eSBvZiBhIHJlZ2lvbidzIHN1cmZhY2UgaW4gdGhlIHZvbHVtZS4gKi9cbmV4cG9ydCBjb25zdCBSRUdJT05fTUVTSF9PUEFDSVRZID0gMC41NTtcbi8qKiBXaGlsZSBzb21lIHN1cmZhY2VzIGFyZSBoaWdobGlnaHRlZDogdGhlaXJzIChuZWFyIG9wYXF1ZSwgc28gdGhlaXIgc2hhcGUgcmVhZHMpIOKApiAqL1xuZXhwb3J0IGNvbnN0IFJFR0lPTl9NRVNIX0hJR0hMSUdIVF9PUEFDSVRZID0gMC45O1xuLyoqIOKApiBhbmQgdGhlIG90aGVycycgKGdob3N0ZWQ6IHN0aWxsIHRoZXJlIGZvciBjb250ZXh0LCBub3QgaW4gdGhlIHdheSkuICovXG5leHBvcnQgY29uc3QgUkVHSU9OX01FU0hfRElNTUVEX09QQUNJVFkgPSAwLjEyO1xuLyoqXG4gKiBBIHNlbGVjdGlvbidzIHN1cmZhY2VzIHdoaWxlIHRoZSBvdGhlcnMgYXJlIGdob3N0ZWQ6IG9wYXF1ZSwgc28gdGhleSBhcmUgZHJhd24gZmlyc3QgYW5kIHdyaXRlXG4gKiBkZXB0aCwgYW5kIHRoZSBnaG9zdGVkIHN1cmZhY2VzIGluIGZyb250IG9mIHRoZW0gYXJlIGJsZW5kZWQgb3ZlciB0aGVtIHJhdGhlciB0aGFuIGhpZGluZyB0aGVtXG4gKiAoYSB0cmFuc2x1Y2VudCBzdXJmYWNlIGRyYXdzIG9ubHkgaXRzIG93biBuZWFyZXN0IGZhY2VzLCBhbmQgaXMgZHJhd24gYWZ0ZXIgdGhlIG9wYXF1ZSBvbmVzKS5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFR0lPTl9NRVNIX1NFTEVDVEVEX09QQUNJVFkgPSAxO1xuXG4vKipcbiAqIFRoZSByZWdpb24gcmVjb25zdHJ1Y3Rpb25zIHNob3duIGluIGEgdm9sdW1lIHZpZXc6IG9uZSB0cmFuc2x1Y2VudCBzdXJmYWNlIHBlciByZWdpb24sIGluIGl0c1xuICogY29sb3VyLCBwbGFjZWQgaW4gdGhlIHZvbHVtZSdzIHdvcmxkIGJveCAocGl4ZWwgeCwgeSBhbmQgc2xpY2UgeiBtYXBwZWQgb250byBpdCB0aGUgd2F5IHRoZVxuICogdm9sdW1lIG1hcHMgaXRzIHZveGVscykuIFRoZSBib3gncyBaIHN0cmV0Y2ggaXMgdGhlIHN1cmZhY2VzJyBgc2NhbGUzZGAgKGEgdW5pZm9ybSksIHNvIGEgc3RyZXRjaFxuICogYWxvbmUgY2hhbmdlcyBubyBnZW9tZXRyeTsgYSBuZXcgYm94IHJlLXBsYWNlcyB0aGVtLiBBIHN1cmZhY2UgaXMgdXBkYXRlZCBpbiBwbGFjZSAoYHNldERhdGFgLFxuICogYGNvbG9yYCwgYHNjYWxlM2RgKSByYXRoZXIgdGhhbiBhZGRlZCBhZ2FpbiwgYW5kIHBpY2tlZCBieSBuYXBhcmktanMgKGBwaWNrU3VyZmFjZWApLCB3aGljaFxuICogcGlja3MgaXQgd2hlcmUgaXQgaXMgZHJhd24uXG4gKlxuICogSGlnaGxpZ2h0aW5nIGlzIGZvY3VzICsgY29udGV4dDogdGhlIGhpZ2hsaWdodGVkIHN1cmZhY2VzIHR1cm4gbmVhciBvcGFxdWUgYW5kIHRoZSBvdGhlcnMgZmFkZVxuICogdG8gYSBnaG9zdCwgc28gdGhlIHNlbGVjdGlvbiBzdGFuZHMgb3V0IHdoaWxlIHN0YXlpbmcgaW4gcGxhY2UgYW1vbmcgaXRzIG5laWdoYm91cnMuXG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWVSZWdpb25NZXNoZXMge1xuICBwcml2YXRlIHJlYWRvbmx5IGxheWVycyA9IG5ldyBNYXA8c3RyaW5nLCB7IG1lc2g6IFJlZ2lvbk1lc2gzRDsgbGF5ZXI6IFN1cmZhY2VMYXllciB9PigpO1xuICBwcml2YXRlIGhpZ2hsaWdodGVkOiBSZWFkb25seVNldDxzdHJpbmc+ID0gbmV3IFNldCgpO1xuICBwcml2YXRlIGhpZGRlbjogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFN1cmZhY2VzIGZhZGVkOiBub25lIG9mIHdoYXQgaXMgc2VsZWN0ZWQgaXMgaW4gdGhlbS4gKi9cbiAgcHJpdmF0ZSBtdXRlZDogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoKTtcbiAgLyoqIFRoZSBtZXNoZXMgdG8gc2hvdyAoa2VwdCB3aGlsZSB0aGUgdm9sdW1lIGhhcyBubyBmcmFtZSB5ZXQpLiAqL1xuICBwcml2YXRlIHdhbnRlZDogcmVhZG9ubHkgUmVnaW9uTWVzaDNEW10gPSBbXTtcbiAgcHJpdmF0ZSBmcmFtZTogVm9sdW1lRnJhbWUgfCBudWxsID0gbnVsbDtcblxuICAvKiogVGhlIHBsYWNlbWVudHMgaW4gZmxpZ2h0LCBieSBrZXk6IHRoZSBtZXNoIGFuZCBib3ggZWFjaCBpcyBmb3IuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcGxhY2luZyA9IG5ldyBNYXA8c3RyaW5nLCB7IG1lc2g6IFJlZ2lvbk1lc2gzRDsgZnJhbWU6IFZvbHVtZUZyYW1lOyB0b2tlbjogbnVtYmVyIH0+KCk7XG4gIHByaXZhdGUgdG9rZW4gPSAwO1xuXG4gIC8qKlxuICAgKiBgcGxhY2VyYCwgd2hlbiBnaXZlbiwgcGxhY2VzIGEgbWVzaCdzIHZlcnRpY2VzIGluIHRoZSB3b3JsZCBvZmYgdGhlIG1haW4gdGhyZWFkIChhIHdvcmtlciwgc2VlXG4gICAqIGBwbGFjZUluV29ya2VyYCk6IGEgY2xhc3MncyBzdXJmYWNlIGhhcyBodW5kcmVkcyBvZiB0aG91c2FuZHMgb2YgdmVydGljZXMsIGFuZCBwbGFjaW5nIGV2ZXJ5XG4gICAqIG9uZSBpbiBhIGxvb3AgaGVyZSBoZWxkIHRoZSBVSSBmb3Igc2Vjb25kcy4gRWFjaCBzdXJmYWNlIHRoZW4gY29tZXMgdXAgYXMgaXRzIHBsYWNlbWVudCBsYW5kcyxcbiAgICogdGhlIG9uZSBpdCByZXBsYWNlcyBrZXB0IHVudGlsIHRoZW4uIFdpdGhvdXQgb25lLCB0aGV5IGFyZSBwbGFjZWQgYXQgb25jZSAodGhlIHRlc3RzKS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdmlld2VyOiBWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwbGFjZXI/OiBSZWdpb25QbGFjZXIsXG4gICkge31cblxuICAvKiogU2hvdyBleGFjdGx5IGBtZXNoZXNgIChhZGRpbmcsIGtlZXBpbmcgb3IgcmVtb3Zpbmcgc3VyZmFjZXMpLiAqL1xuICBzZXQobWVzaGVzOiByZWFkb25seSBSZWdpb25NZXNoM0RbXSk6IHZvaWQge1xuICAgIHRoaXMud2FudGVkID0gbWVzaGVzO1xuICAgIHRoaXMuc3luYygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvbGxvdyB0aGUgdm9sdW1lJ3MgZnJhbWUuIEEgbmV3IGJveCAoaXQgb3BlbmVkLCBhbm90aGVyIHZvbHVtZSkgcmUtcGxhY2VzIGV2ZXJ5IHN1cmZhY2U7IGEgWlxuICAgKiBzdHJldGNoIG9mIHRoZSBzYW1lIGJveCBvbmx5IHNldHMgdGhlaXIgYHNjYWxlM2RgLCBzbyBub3RoaW5nIGlzIHJlLXVwbG9hZGVkIHdoaWxlIGRyYWdnaW5nLlxuICAgKi9cbiAgc2V0RnJhbWUoZnJhbWU6IFZvbHVtZUZyYW1lKTogdm9pZCB7XG4gICAgY29uc3QgcGxhY2VkID0gdGhpcy5mcmFtZSA/IGJhc2VGcmFtZSh0aGlzLmZyYW1lKSA6IG51bGw7XG4gICAgY29uc3QgbmV4dCA9IGJhc2VGcmFtZShmcmFtZSk7XG4gICAgY29uc3Qgc2FtZUJveCA9ICEhcGxhY2VkICYmIHNhbWVGcmFtZShwbGFjZWQsIG5leHQpO1xuICAgIHRoaXMuZnJhbWUgPSBmcmFtZTtcbiAgICBjb25zdCBzY2FsZSA9IHRoaXMuc2NhbGUzZCgpO1xuICAgIGZvciAoY29uc3QgZSBvZiB0aGlzLmxheWVycy52YWx1ZXMoKSkge1xuICAgICAgaWYgKCFzYW1lQm94KSB0aGlzLnBsYWNlKGUubWVzaCk7XG4gICAgICBlLmxheWVyLnNjYWxlM2QgPSBzY2FsZTtcbiAgICB9XG4gICAgdGhpcy5zeW5jKCk7XG4gIH1cblxuICAvKiogVGhlIHN1cmZhY2VzJyBHUFUgc2NhbGU6IHRoZSBmcmFtZSdzIFogc3RyZXRjaC4gKi9cbiAgcHJpdmF0ZSBzY2FsZTNkKCk6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSB7XG4gICAgY29uc3QgcyA9IHRoaXMuZnJhbWU/LnpTY2FsZTtcbiAgICByZXR1cm4gWzEsIDEsIHMgJiYgcyA+IDAgPyBzIDogMV07XG4gIH1cblxuICAvKiogSGlnaGxpZ2h0IHRoZSBzdXJmYWNlcyBvZiB0aGVzZSBrZXlzIChub25lOiBldmVyeSBzdXJmYWNlIGFzIHVzdWFsKS4gKi9cbiAgc2V0SGlnaGxpZ2h0KGtleXM6IEl0ZXJhYmxlPHN0cmluZz4pOiB2b2lkIHtcbiAgICB0aGlzLmhpZ2hsaWdodGVkID0gbmV3IFNldChrZXlzKTtcbiAgICBmb3IgKGNvbnN0IFtrZXksIGVdIG9mIHRoaXMubGF5ZXJzKSBlLmxheWVyLm9wYWNpdHkgPSB0aGlzLm9wYWNpdHlPZihrZXkpO1xuICAgIHRoaXMudmlld2VyLnJlcXVlc3RSZW5kZXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGYWRlIHRoZSBzdXJmYWNlcyBvZiB0aGVzZSBrZXlzLCBhcyBhIHBpY2tlZCByZWdpb24gZmFkZXMgdGhlIG90aGVycyAobm9uZTogZWFjaCBhcyB1c3VhbCk6XG4gICAqIHdpdGggYSBzZWxlY3Rpb24sIHRoZSByZWdpb25zIG5vbmUgb2YgaXQgaXMgaW4gZmFkZSBhbmQgdGhvc2UgaXQgaXMgaW4gY29tZSBmb3J3YXJkLCBlYWNoXG4gICAqIGtlZXBpbmcgaXRzIGNvbG91ci5cbiAgICovXG4gIHNldE11dGVkKGtleXM6IEl0ZXJhYmxlPHN0cmluZz4pOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gbmV3IFNldChrZXlzKTtcbiAgICBpZiAobmV4dC5zaXplID09PSB0aGlzLm11dGVkLnNpemUgJiYgWy4uLm5leHRdLmV2ZXJ5KChrKSA9PiB0aGlzLm11dGVkLmhhcyhrKSkpIHJldHVybjtcbiAgICB0aGlzLm11dGVkID0gbmV4dDtcbiAgICBmb3IgKGNvbnN0IFtrZXksIGVdIG9mIHRoaXMubGF5ZXJzKSBlLmxheWVyLm9wYWNpdHkgPSB0aGlzLm9wYWNpdHlPZihrZXkpO1xuICAgIHRoaXMudmlld2VyLnJlcXVlc3RSZW5kZXIoKTtcbiAgfVxuXG4gIC8qKiBIaWRlIHRoZSBzdXJmYWNlcyBvZiB0aGVzZSBrZXlzICh0aGV5IGFyZSBrZXB0LCBzbyBzaG93aW5nIHRoZW0gYWdhaW4gaXMgaW5zdGFudCkuICovXG4gIHNldEhpZGRlbihrZXlzOiBJdGVyYWJsZTxzdHJpbmc+KTogdm9pZCB7XG4gICAgdGhpcy5oaWRkZW4gPSBuZXcgU2V0KGtleXMpO1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgdGhpcy5sYXllcnMpIGUubGF5ZXIudmlzaWJsZSA9ICF0aGlzLmhpZGRlbi5oYXMoa2V5KTtcbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICAvKiogVGhlIGZyb250LW1vc3Qgc3VyZmFjZSB1bmRlciBzY3JlZW4gcG9pbnQgKGB4YCwgYHlgKSAoY2FudmFzIENTUyBweCksIG9yIG51bGwuICovXG4gIHBpY2tBdCh4OiBudW1iZXIsIHk6IG51bWJlcik6IFJlZ2lvbk1lc2gzRCB8IG51bGwge1xuICAgIGlmICghdGhpcy5sYXllcnMuc2l6ZSkgcmV0dXJuIG51bGw7XG4gICAgY29uc3Qgb3VycyA9IG5ldyBNYXAoWy4uLnRoaXMubGF5ZXJzLnZhbHVlcygpXS5tYXAoKGUpID0+IFtlLmxheWVyLCBlLm1lc2hdKSk7XG4gICAgY29uc3QgaGl0ID0gdGhpcy52aWV3ZXIucGlja1N1cmZhY2UoeCwgeSwgeyBwaWNrYWJsZTogKGxheWVyKSA9PiBvdXJzLmhhcyhsYXllcikgfSk7XG4gICAgcmV0dXJuIGhpdCA/IChvdXJzLmdldChoaXQubGF5ZXIpID8/IG51bGwpIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBUaGUgbWVzaGVzIHNob3duLiAqL1xuICBnZXQgc2hvd24oKTogUmVnaW9uTWVzaDNEW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5sYXllcnMudmFsdWVzKCldLm1hcCgoZSkgPT4gZS5tZXNoKTtcbiAgfVxuXG4gIGNsZWFyKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgWy4uLnRoaXMubGF5ZXJzXSkgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICB0aGlzLndhbnRlZCA9IFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB2b2x1bWUgdGhlIHN1cmZhY2VzIHNhdCBpbiBpcyBnb25lIChvciBubyBsb25nZXIgdGhlaXJzKTogdGFrZSBldmVyeSBzdXJmYWNlIGRvd24sIGtlZXBpbmdcbiAgICogdGhlIG1lc2hlcyB3YW50ZWQsIHNvIHRoZXkgY29tZSBiYWNrIHdoZW4gYSBmcmFtZSBpcyBzZXQgYWdhaW4uXG4gICAqL1xuICBjbGVhckZyYW1lKCk6IHZvaWQge1xuICAgIHRoaXMuZnJhbWUgPSBudWxsO1xuICAgIGZvciAoY29uc3QgW2tleSwgZV0gb2YgWy4uLnRoaXMubGF5ZXJzXSkgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIHN5bmMoKTogdm9pZCB7XG4gICAgY29uc3Qga2VlcCA9IG5ldyBNYXAodGhpcy53YW50ZWQubWFwKChtKSA9PiBbbS5rZXksIG1dKSk7XG4gICAgZm9yIChjb25zdCBba2V5LCBlXSBvZiBbLi4udGhpcy5sYXllcnNdKSB7XG4gICAgICBjb25zdCB3YW50ID0ga2VlcC5nZXQoa2V5KTtcbiAgICAgIGlmICghd2FudCB8fCAhd2FudC5mYWNlcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5yZW1vdmUoa2V5LCBlLmxheWVyKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICAvLyBSZWJ1aWx0IG9yIHJlY29sb3VyZWQ6IHRoZSBzYW1lIHN1cmZhY2UsIHVwZGF0ZWQgaW4gcGxhY2UuXG4gICAgICBjb25zdCByZWJ1aWx0ID0gd2FudC52ZXJ0aWNlcyAhPT0gZS5tZXNoLnZlcnRpY2VzO1xuICAgICAgaWYgKHdhbnQuY29sb3IgIT09IGUubWVzaC5jb2xvcikgZS5sYXllci5jb2xvciA9IHdhbnQuY29sb3I7XG4gICAgICBlLm1lc2ggPSB3YW50O1xuICAgICAgaWYgKHJlYnVpbHQgJiYgdGhpcy5mcmFtZSkgdGhpcy5wbGFjZSh3YW50KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuZnJhbWUpIHtcbiAgICAgIGZvciAoY29uc3QgbWVzaCBvZiB0aGlzLndhbnRlZCkgaWYgKCF0aGlzLmxheWVycy5oYXMobWVzaC5rZXkpICYmIG1lc2guZmFjZXMubGVuZ3RoKSB0aGlzLnBsYWNlKG1lc2gpO1xuICAgIH1cbiAgICB0aGlzLnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogUGxhY2UgYG1lc2hgIGluIHRoZSBjdXJyZW50IGJveCwgYWRkaW5nIGl0cyBzdXJmYWNlIG9yIHVwZGF0aW5nIGl0OiBhdCBvbmNlLCBvciB0aHJvdWdoIHRoZVxuICAgKiBwbGFjZXIsIGl0cyByZXN1bHQga2VwdCBvbmx5IGlmIHRoZSBtZXNoIGFuZCB0aGUgYm94IGFyZSBzdGlsbCB0aGUgb25lcyB3YW50ZWQuIEEgcGxhY2VtZW50XG4gICAqIGFscmVhZHkgaW4gZmxpZ2h0IGZvciB0aGUgc2FtZSBtZXNoIGFuZCBib3ggaXMgbm90IGFza2VkIGFnYWluLlxuICAgKi9cbiAgcHJpdmF0ZSBwbGFjZShtZXNoOiBSZWdpb25NZXNoM0QpOiB2b2lkIHtcbiAgICBjb25zdCBmcmFtZSA9IHRoaXMuZnJhbWU7XG4gICAgaWYgKCFmcmFtZSkgcmV0dXJuO1xuICAgIGNvbnN0IGJhc2UgPSBiYXNlRnJhbWUoZnJhbWUpO1xuICAgIGlmICghdGhpcy5wbGFjZXIpIHtcbiAgICAgIHRoaXMuYXBwbHkobWVzaCwgdG9Xb3JsZChtZXNoLnZlcnRpY2VzLCBiYXNlKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBsYWNpbmcuZ2V0KG1lc2gua2V5KTtcbiAgICBpZiAocGVuZGluZyAmJiBwZW5kaW5nLm1lc2ggPT09IG1lc2ggJiYgc2FtZUZyYW1lKHBlbmRpbmcuZnJhbWUsIGJhc2UpKSByZXR1cm47XG4gICAgY29uc3QgdG9rZW4gPSArK3RoaXMudG9rZW47XG4gICAgdGhpcy5wbGFjaW5nLnNldChtZXNoLmtleSwgeyBtZXNoLCBmcmFtZTogYmFzZSwgdG9rZW4gfSk7XG4gICAgdGhpcy5wbGFjZXIobWVzaC52ZXJ0aWNlcywgYmFzZSkudGhlbihcbiAgICAgICh3b3JsZCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5wbGFjaW5nLmdldChtZXNoLmtleSk/LnRva2VuICE9PSB0b2tlbikgcmV0dXJuO1xuICAgICAgICB0aGlzLnBsYWNpbmcuZGVsZXRlKG1lc2gua2V5KTtcbiAgICAgICAgY29uc3Qgd2FudGVkID0gdGhpcy53YW50ZWQuZmluZCgobSkgPT4gbS5rZXkgPT09IG1lc2gua2V5KTtcbiAgICAgICAgaWYgKHdhbnRlZCAhPT0gbWVzaCB8fCAhdGhpcy5mcmFtZSB8fCAhc2FtZUZyYW1lKGJhc2VGcmFtZSh0aGlzLmZyYW1lKSwgYmFzZSkpIHJldHVybjtcbiAgICAgICAgdGhpcy5hcHBseShtZXNoLCB3b3JsZCk7XG4gICAgICAgIHRoaXMudmlld2VyLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgIH0sXG4gICAgICAoZXJyKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnBsYWNpbmcuZ2V0KG1lc2gua2V5KT8udG9rZW4gPT09IHRva2VuKSB0aGlzLnBsYWNpbmcuZGVsZXRlKG1lc2gua2V5KTtcbiAgICAgICAgY29uc29sZS53YXJuKGBbbmFwYXJpLWpzXSByZWdpb24gJHttZXNoLmtleX0gY291bGQgbm90IGJlIHBsYWNlZCBpbiAzRGAsIGVycik7XG4gICAgICB9LFxuICAgICk7XG4gIH1cblxuICAvKiogYG1lc2hgJ3Mgc3VyZmFjZSB3aXRoIGl0cyB2ZXJ0aWNlcyBwbGFjZWQgYXQgYHdvcmxkYDogdXBkYXRlZCBpbiBwbGFjZSwgb3IgYWRkZWQuICovXG4gIHByaXZhdGUgYXBwbHkobWVzaDogUmVnaW9uTWVzaDNELCB3b3JsZDogRmxvYXQzMkFycmF5KTogdm9pZCB7XG4gICAgY29uc3QgZSA9IHRoaXMubGF5ZXJzLmdldChtZXNoLmtleSk7XG4gICAgaWYgKGUpIHtcbiAgICAgIGUubGF5ZXIuc2V0RGF0YSh3b3JsZCwgbWVzaC5mYWNlcyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYWRkKG1lc2gsIHdvcmxkKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkKG1lc2g6IFJlZ2lvbk1lc2gzRCwgd29ybGQ6IEZsb2F0MzJBcnJheSk6IHZvaWQge1xuICAgIGNvbnN0IGxheWVyID0gdGhpcy52aWV3ZXIuYWRkU3VyZmFjZSh3b3JsZCwgbWVzaC5mYWNlcywgdW5kZWZpbmVkLCB7XG4gICAgICBuYW1lOiBgcmVnaW9uICR7bWVzaC5rZXl9YCxcbiAgICAgIHNjYWxlM2Q6IHRoaXMuc2NhbGUzZCgpLFxuICAgICAgY29sb3I6IG1lc2guY29sb3IsXG4gICAgICBvcGFjaXR5OiB0aGlzLm9wYWNpdHlPZihtZXNoLmtleSksXG4gICAgICBibGVuZGluZzogJ3RyYW5zbHVjZW50JyxcbiAgICAgIGZpdDogJ25ldmVyJyxcbiAgICB9KTtcbiAgICBsYXllci52aXNpYmxlID0gIXRoaXMuaGlkZGVuLmhhcyhtZXNoLmtleSk7XG4gICAgdGhpcy5sYXllcnMuc2V0KG1lc2gua2V5LCB7IG1lc2gsIGxheWVyIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvcGFjaXR5T2Yoa2V5OiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLm11dGVkLnNpemUpIHJldHVybiB0aGlzLm11dGVkLmhhcyhrZXkpID8gUkVHSU9OX01FU0hfRElNTUVEX09QQUNJVFkgOiBSRUdJT05fTUVTSF9TRUxFQ1RFRF9PUEFDSVRZO1xuICAgIGlmICghdGhpcy5oaWdobGlnaHRlZC5zaXplKSByZXR1cm4gUkVHSU9OX01FU0hfT1BBQ0lUWTtcbiAgICByZXR1cm4gdGhpcy5oaWdobGlnaHRlZC5oYXMoa2V5KSA/IFJFR0lPTl9NRVNIX1NFTEVDVEVEX09QQUNJVFkgOiBSRUdJT05fTUVTSF9ESU1NRURfT1BBQ0lUWTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlKGtleTogc3RyaW5nLCBsYXllcjogU3VyZmFjZUxheWVyKTogdm9pZCB7XG4gICAgdGhpcy52aWV3ZXIubGF5ZXJzLnJlbW92ZShsYXllcik7XG4gICAgdGhpcy5sYXllcnMuZGVsZXRlKGtleSk7XG4gICAgdGhpcy5wbGFjaW5nLmRlbGV0ZShrZXkpO1xuICB9XG59XG5cbi8qKiBgZnJhbWVgIHdpdGhvdXQgaXRzIFogc3RyZXRjaDogdGhlIGJveCB0aGUgc3VyZmFjZXMnIGdlb21ldHJ5IGlzIHBsYWNlZCBpbi4gKi9cbmZ1bmN0aW9uIGJhc2VGcmFtZShmcmFtZTogVm9sdW1lRnJhbWUpOiBWb2x1bWVGcmFtZSB7XG4gIGNvbnN0IHMgPSBmcmFtZS56U2NhbGUgJiYgZnJhbWUuelNjYWxlID4gMCA/IGZyYW1lLnpTY2FsZSA6IDE7XG4gIGlmIChzID09PSAxKSByZXR1cm4gZnJhbWU7XG4gIHJldHVybiB7XG4gICAgc2l6ZTogZnJhbWUuc2l6ZSxcbiAgICB3b3JsZDogW2ZyYW1lLndvcmxkWzBdLCBmcmFtZS53b3JsZFsxXSwgZnJhbWUud29ybGRbMl0gLyBzXSxcbiAgICAuLi4oZnJhbWUucGxhbmVzID8geyBwbGFuZXM6IGZyYW1lLnBsYW5lcyB9IDoge30pLFxuICB9O1xufVxuXG4vKiogV2hldGhlciB0d28gdW5zdHJldGNoZWQgZnJhbWVzIHBsYWNlIGEgc3VyZmFjZSBhbGlrZS4gKi9cbmZ1bmN0aW9uIHNhbWVGcmFtZShhOiBWb2x1bWVGcmFtZSwgYjogVm9sdW1lRnJhbWUpOiBib29sZWFuIHtcbiAgY29uc3QgbmVhciA9ICh4OiBudW1iZXIsIHk6IG51bWJlcikgPT4gTWF0aC5hYnMoeCAtIHkpIDw9IDFlLTkgKiBNYXRoLm1heCgxLCBNYXRoLmFicyh4KSk7XG4gIGlmIChhLnBsYW5lcyB8fCBiLnBsYW5lcykge1xuICAgIGNvbnN0IHAgPSBhLnBsYW5lcztcbiAgICBjb25zdCBxID0gYi5wbGFuZXM7XG4gICAgcmV0dXJuIChcbiAgICAgICEhcCAmJlxuICAgICAgISFxICYmXG4gICAgICBwLnoubGVuZ3RoID09PSBxLnoubGVuZ3RoICYmXG4gICAgICBwLnouZXZlcnkoKHYsIGkpID0+IG5lYXIodiwgcS56W2ldKSkgJiZcbiAgICAgIHAuc2NhbGUuZXZlcnkoKHYsIGkpID0+IG5lYXIodiwgcS5zY2FsZVtpXSkpICYmXG4gICAgICBwLm9mZnNldC5ldmVyeSgodiwgaSkgPT4gbmVhcih2LCBxLm9mZnNldFtpXSkpXG4gICAgKTtcbiAgfVxuICByZXR1cm4gYS5zaXplLmV2ZXJ5KCh2LCBpKSA9PiB2ID09PSBiLnNpemVbaV0pICYmIGEud29ybGQuZXZlcnkoKHYsIGkpID0+IG5lYXIodiwgYi53b3JsZFtpXSkpO1xufVxuIl19