@jax-data-science/sci-image-visualizer 0.9.0 → 0.11.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 (149) hide show
  1. package/esm2022/index.mjs +10 -1
  2. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  3. package/esm2022/lib/contracts/ports/region-io.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/section-view.contract.mjs +2 -0
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/contracts/viz-config.mjs +1 -1
  9. package/esm2022/lib/geometry/loft.mjs +128 -0
  10. package/esm2022/lib/geometry/polylabel.mjs +156 -0
  11. package/esm2022/lib/geometry/reconstruct.mjs +315 -0
  12. package/esm2022/lib/geometry/reslice-image.mjs +57 -0
  13. package/esm2022/lib/geometry/section.mjs +215 -0
  14. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
  15. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
  16. package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
  17. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
  18. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  19. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
  20. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
  21. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
  22. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
  23. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
  24. package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
  25. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
  26. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +18 -2
  27. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +9 -1
  28. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
  29. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
  30. package/esm2022/lib/implementations/osd/osd-tile-loading.mjs +71 -0
  31. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +1 -1
  32. package/esm2022/lib/implementations/osd/slice-cache.mjs +35 -6
  33. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
  34. package/esm2022/lib/models/class-preset.mjs +1 -1
  35. package/esm2022/lib/models/polygon-factory.mjs +17 -1
  36. package/esm2022/lib/models/region-geojson.mjs +44 -6
  37. package/esm2022/lib/models/region.mjs +1 -1
  38. package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
  39. package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
  40. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
  41. package/esm2022/lib/region-editor/region-editor.component.mjs +670 -42
  42. package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
  43. package/esm2022/lib/region-editor/region-persistence.service.mjs +44 -10
  44. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
  45. package/esm2022/lib/region-import/label-classes.mjs +149 -0
  46. package/esm2022/lib/region-import/label-volume.mjs +194 -0
  47. package/esm2022/lib/region-import/region-import.mjs +71 -0
  48. package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
  49. package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
  50. package/esm2022/lib/region-overlay/region-style.mjs +97 -0
  51. package/esm2022/lib/region-source/http-region-source.mjs +104 -0
  52. package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
  53. package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
  54. package/esm2022/lib/region-source/region-source.mjs +67 -0
  55. package/esm2022/lib/region-source/region-tiles.mjs +708 -0
  56. package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
  57. package/esm2022/lib/routing-visualizer.service.mjs +510 -22
  58. package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
  59. package/esm2022/lib/store/class-color.util.mjs +10 -5
  60. package/esm2022/lib/store/class-signatures.mjs +63 -0
  61. package/esm2022/lib/store/region-scope-cache.mjs +5 -1
  62. package/esm2022/lib/store/region-source-scope.mjs +186 -0
  63. package/esm2022/lib/store/region-store.service.mjs +774 -12
  64. package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
  65. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
  66. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
  67. package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
  68. package/esm2022/lib/visualizer/region-load.mjs +67 -4
  69. package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
  70. package/esm2022/lib/visualizer.component.mjs +155 -7
  71. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs} +9851 -2904
  72. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs.map +1 -0
  73. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs} +4 -4
  74. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs.map} +1 -1
  75. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
  76. package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
  77. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
  78. package/fesm2022/region-source.worker.js +1067 -0
  79. package/index.d.ts +12 -0
  80. package/lib/contracts/image.contract.d.ts +4 -0
  81. package/lib/contracts/ports/region-io.port.d.ts +24 -0
  82. package/lib/contracts/region-editor-api.contract.d.ts +102 -0
  83. package/lib/contracts/region-store.contract.d.ts +22 -0
  84. package/lib/contracts/section-view.contract.d.ts +44 -0
  85. package/lib/contracts/visualizer.contract.d.ts +10 -0
  86. package/lib/contracts/viz-config.d.ts +8 -0
  87. package/lib/geometry/loft.d.ts +22 -0
  88. package/lib/geometry/polylabel.d.ts +23 -0
  89. package/lib/geometry/reconstruct.d.ts +54 -0
  90. package/lib/geometry/reslice-image.d.ts +33 -0
  91. package/lib/geometry/section.d.ts +52 -0
  92. package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
  93. package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
  94. package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
  95. package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
  96. package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
  97. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
  98. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
  99. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
  100. package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
  101. package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
  102. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +2 -0
  103. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +2 -0
  104. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
  105. package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
  106. package/lib/implementations/osd/osd-tile-loading.d.ts +43 -0
  107. package/lib/implementations/osd/osd-viewer-like.d.ts +14 -0
  108. package/lib/implementations/osd/slice-cache.d.ts +13 -3
  109. package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
  110. package/lib/models/class-preset.d.ts +7 -0
  111. package/lib/models/polygon-factory.d.ts +5 -0
  112. package/lib/models/region-geojson.d.ts +40 -0
  113. package/lib/models/region.d.ts +19 -0
  114. package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
  115. package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
  116. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
  117. package/lib/region-editor/region-editor.component.d.ts +159 -17
  118. package/lib/region-editor/region-metrics.d.ts +8 -0
  119. package/lib/region-editor/region-persistence.service.d.ts +17 -5
  120. package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
  121. package/lib/region-import/label-classes.d.ts +39 -0
  122. package/lib/region-import/label-volume.d.ts +31 -0
  123. package/lib/region-import/region-import.d.ts +46 -0
  124. package/lib/region-overlay/region-geometry.d.ts +4 -3
  125. package/lib/region-overlay/region-source-layer.d.ts +96 -0
  126. package/lib/region-overlay/region-style.d.ts +52 -0
  127. package/lib/region-source/http-region-source.d.ts +45 -0
  128. package/lib/region-source/region-source-ops.d.ts +89 -0
  129. package/lib/region-source/region-source-worker.d.ts +7 -0
  130. package/lib/region-source/region-source.d.ts +82 -0
  131. package/lib/region-source/region-tiles.d.ts +289 -0
  132. package/lib/region-source/worker-region-source.d.ts +65 -0
  133. package/lib/routing-visualizer.service.d.ts +168 -1
  134. package/lib/section-pane/section-pane.component.d.ts +47 -0
  135. package/lib/store/class-color.util.d.ts +6 -3
  136. package/lib/store/class-signatures.d.ts +11 -0
  137. package/lib/store/region-scope-cache.d.ts +2 -0
  138. package/lib/store/region-source-scope.d.ts +74 -0
  139. package/lib/store/region-store.service.d.ts +216 -2
  140. package/lib/store/visualizer-store.service.d.ts +10 -0
  141. package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
  142. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
  143. package/lib/toolbar/toolbar.component.d.ts +9 -2
  144. package/lib/visualizer/region-load.d.ts +23 -4
  145. package/lib/visualizer/volume-sections.d.ts +64 -0
  146. package/lib/visualizer.component.d.ts +40 -0
  147. package/package.json +2 -2
  148. package/src/lib/assets/slice.svg +23 -0
  149. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
@@ -0,0 +1,186 @@
1
+ /** Sources held open, past which the least recently used one is closed (never the one shown). */
2
+ export const OPEN_REGION_SOURCES = 6;
3
+ const NONE = new Set();
4
+ /**
5
+ * The region sources of every image the store has seen, per slice, and per slice the ids of
6
+ * the source features taken out of the source (into the working set, or deleted) — those the
7
+ * source no longer draws and an export leaves out.
8
+ *
9
+ * Sources open lazily, the first time their slice is shown or read, and at most
10
+ * {@link OPEN_REGION_SOURCES} stay open: the least recently used are closed and re-opened from
11
+ * their opener when used again (a source's ids are stable, so what was taken stays taken). The
12
+ * source of the slice on screen ({@link show}) is never closed for another: a read across every
13
+ * slice must not close the source the viewer draws and takes from.
14
+ */
15
+ export class RegionSourceScope {
16
+ constructor() {
17
+ this.images = new Map();
18
+ /** Open entries, least recently used first. */
19
+ this.openOrder = [];
20
+ /** The entry of the slice on screen: kept open. */
21
+ this.shown = null;
22
+ }
23
+ /**
24
+ * Attach `open` to `image` for `slices`, replacing (and closing) what was there. `imported` names
25
+ * the slices it brings that a save must write (see {@link importedSlices}): for a source of one
26
+ * slice, that slice when non-empty; for a `'planes'` source, the slices its planes cover.
27
+ */
28
+ attach(image, open, slices, imported = []) {
29
+ const sources = this.imageSources(image);
30
+ const entry = { open, source: null, ready: null };
31
+ if (slices === 'planes') {
32
+ if (sources.planes)
33
+ this.close(sources.planes);
34
+ sources.planes = entry;
35
+ sources.perSlice.forEach((e) => this.close(e));
36
+ sources.perSlice.clear();
37
+ sources.taken.clear();
38
+ sources.imported = new Set(imported);
39
+ }
40
+ else {
41
+ const old = sources.perSlice.get(slices.slice);
42
+ if (old)
43
+ this.close(old);
44
+ entry.plane = slices.plane ?? 0;
45
+ sources.perSlice.set(slices.slice, entry);
46
+ sources.taken.delete(slices.slice);
47
+ if (imported.length)
48
+ sources.imported.add(slices.slice);
49
+ else
50
+ sources.imported.delete(slices.slice);
51
+ }
52
+ }
53
+ /** Drop every source of `image` (closing the open ones) and what was taken from them. */
54
+ detachImage(image) {
55
+ const sources = this.images.get(image);
56
+ if (!sources)
57
+ return;
58
+ if (sources.planes)
59
+ this.close(sources.planes);
60
+ sources.perSlice.forEach((e) => this.close(e));
61
+ this.images.delete(image);
62
+ }
63
+ /** Drop the source of one slice of `image`. */
64
+ detachSlice(image, slice) {
65
+ const sources = this.images.get(image);
66
+ const entry = sources?.perSlice.get(slice);
67
+ if (!sources || !entry)
68
+ return;
69
+ this.close(entry);
70
+ sources.perSlice.delete(slice);
71
+ sources.taken.delete(slice);
72
+ sources.imported.delete(slice);
73
+ }
74
+ /** The slice on screen (null: none): its source stays open while others are read. */
75
+ show(image, slice) {
76
+ this.shown = image && slice !== null ? this.entry(image, slice) : null;
77
+ }
78
+ /** Whether `image` has a source for `slice`. */
79
+ has(image, slice) {
80
+ return !!image && !!this.entry(image, slice);
81
+ }
82
+ /** Whether `slice` of `image` has a source of its own (not a `'planes'` source's plane). */
83
+ hasOwnSource(image, slice) {
84
+ return !!image && !!this.images.get(image)?.perSlice.has(slice);
85
+ }
86
+ /** Every slice of `image` with a source of its own (not counting a `'planes'` source). */
87
+ slicesWithSource(image) {
88
+ if (!image)
89
+ return [];
90
+ return Array.from(this.images.get(image)?.perSlice.keys() ?? []).sort((a, b) => a - b);
91
+ }
92
+ /** Whether `image` has one source over all its slices. */
93
+ hasPlanesSource(image) {
94
+ return !!image && !!this.images.get(image)?.planes;
95
+ }
96
+ /**
97
+ * The source behind `slice` of `image`, opening it if needed. Resolves null when there is
98
+ * none, and rejects when it cannot be opened.
99
+ */
100
+ async binding(image, slice) {
101
+ const entry = image ? this.entry(image, slice) : null;
102
+ if (!entry)
103
+ return null;
104
+ const source = await this.openEntry(entry);
105
+ return { source, plane: entry.plane ?? slice };
106
+ }
107
+ /** The ids taken from `slice`'s source. */
108
+ taken(image, slice) {
109
+ return (image && this.images.get(image)?.taken.get(slice)) || NONE;
110
+ }
111
+ /** Every id taken from any slice of `image` (a `'planes'` source's ids are unique across them). */
112
+ allTaken(image) {
113
+ const taken = image ? this.images.get(image)?.taken : undefined;
114
+ return taken ? Array.from(taken.values()).flatMap((ids) => Array.from(ids)) : [];
115
+ }
116
+ /** The slices of `image` whose source was imported (see {@link attach}), in order. */
117
+ importedSlices(image) {
118
+ const imported = image ? this.images.get(image)?.imported : undefined;
119
+ return imported ? Array.from(imported).sort((a, b) => a - b) : [];
120
+ }
121
+ /** The slices of `image` with anything taken from their source. */
122
+ slicesWithTaken(image) {
123
+ const taken = image ? this.images.get(image)?.taken : undefined;
124
+ return taken ? Array.from(taken.keys()) : [];
125
+ }
126
+ /** Replace the ids taken from `slice`'s source (copy-on-write: `ids` is kept as given). */
127
+ setTaken(image, slice, ids) {
128
+ if (!image)
129
+ return;
130
+ const sources = this.images.get(image);
131
+ if (!sources)
132
+ return;
133
+ if (ids.size)
134
+ sources.taken.set(slice, ids);
135
+ else
136
+ sources.taken.delete(slice);
137
+ }
138
+ entry(image, slice) {
139
+ const sources = this.images.get(image);
140
+ return sources?.perSlice.get(slice) ?? sources?.planes ?? null;
141
+ }
142
+ imageSources(image) {
143
+ let sources = this.images.get(image);
144
+ if (!sources) {
145
+ sources = { planes: null, perSlice: new Map(), taken: new Map(), imported: new Set() };
146
+ this.images.set(image, sources);
147
+ }
148
+ return sources;
149
+ }
150
+ openEntry(entry) {
151
+ const at = this.openOrder.indexOf(entry);
152
+ if (at >= 0)
153
+ this.openOrder.splice(at, 1);
154
+ this.openOrder.push(entry);
155
+ if (!entry.source) {
156
+ const opening = entry.open();
157
+ entry.source = opening;
158
+ opening.then((source) => {
159
+ if (entry.source === opening)
160
+ entry.ready = source;
161
+ else
162
+ source.dispose(); // closed while it opened
163
+ }, () => {
164
+ if (entry.source === opening)
165
+ entry.source = null; // try again next time
166
+ });
167
+ }
168
+ while (this.openOrder.length > OPEN_REGION_SOURCES) {
169
+ const [oldest] = this.openOrder.splice(this.openOrder.findIndex((e) => e !== this.shown), 1);
170
+ this.closeSource(oldest);
171
+ }
172
+ return entry.source;
173
+ }
174
+ close(entry) {
175
+ const at = this.openOrder.indexOf(entry);
176
+ if (at >= 0)
177
+ this.openOrder.splice(at, 1);
178
+ this.closeSource(entry);
179
+ }
180
+ closeSource(entry) {
181
+ entry.ready?.dispose();
182
+ entry.ready = null;
183
+ entry.source = null;
184
+ }
185
+ }
186
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLXNvdXJjZS1zY29wZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvc3RvcmUvcmVnaW9uLXNvdXJjZS1zY29wZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFlQSxpR0FBaUc7QUFDakcsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBc0JyQyxNQUFNLElBQUksR0FBd0IsSUFBSSxHQUFHLEVBQVUsQ0FBQztBQUVwRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUE5QjtRQUNtQixXQUFNLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUM7UUFDMUQsK0NBQStDO1FBQzlCLGNBQVMsR0FBWSxFQUFFLENBQUM7UUFDekMsbURBQW1EO1FBQzNDLFVBQUssR0FBaUIsSUFBSSxDQUFDO0lBOEtyQyxDQUFDO0lBNUtDOzs7O09BSUc7SUFDSCxNQUFNLENBQ0osS0FBYSxFQUNiLElBQXdCLEVBQ3hCLE1BQTBCLEVBQzFCLFdBQThCLEVBQUU7UUFFaEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxNQUFNLEtBQUssR0FBVSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUN6RCxJQUFJLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN4QixJQUFJLE9BQU8sQ0FBQyxNQUFNO2dCQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQy9DLE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ3ZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDL0MsT0FBTyxDQUFDLFFB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QUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FDcEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQ2pELENBQUMsQ0FDRixDQUFDO1lBQ0YsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDO0lBQ3RCLENBQUM7SUFFTyxLQUFLLENBQUMsS0FBWTtRQUN4QixNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QyxJQUFJLEVBQUUsSUFBSSxDQUFDO1lBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVPLFdBQVcsQ0FBQyxLQUFZO1FBQzlCLEtBQUssQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDdkIsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbkIsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDdEIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBSZWdpb25Tb3VyY2UgfSBmcm9tICcuLi9yZWdpb24tc291cmNlL3JlZ2lvbi1zb3VyY2UnO1xuXG4vKiogT3BlbnMgYSByZWdpb24gc291cmNlIG9uIGRlbWFuZCAoYW5kIGFnYWluIGFmdGVyIGl0IHdhcyBjbG9zZWQgdG8gc2F2ZSBtZW1vcnkpLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uU291cmNlT3BlbmVyID0gKCkgPT4gUHJvbWlzZTxSZWdpb25Tb3VyY2U+O1xuXG4vKiogV2hpY2ggc2xpY2VzIGEgc291cmNlIHNlcnZlczogb25lIHNsaWNlIChwbGFuZSBgcGxhbmVgIG9mIHRoZSBzb3VyY2UpLCBvciBldmVyeSBzbGljZSB6XG4gKiAgZnJvbSB0aGUgc291cmNlJ3MgcGxhbmUgeiAoYSB6LWluZGV4ZWQgR2VvSlNPTiBvdmVyIGEgd2hvbGUgc3RhY2spLiAqL1xuZXhwb3J0IHR5cGUgUmVnaW9uU291cmNlU2xpY2VzID0geyBzbGljZTogbnVtYmVyOyBwbGFuZT86IG51bWJlciB9IHwgJ3BsYW5lcyc7XG5cbi8qKiBUaGUgcmVnaW9uIHNvdXJjZSBiZWhpbmQgb25lIHNsaWNlOiB0aGUgc291cmNlIGFuZCB3aGljaCBvZiBpdHMgcGxhbmVzIHRoZSBzbGljZSBzaG93cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVnaW9uU291cmNlQmluZGluZyB7XG4gIHNvdXJjZTogUmVnaW9uU291cmNlO1xuICBwbGFuZTogbnVtYmVyO1xufVxuXG4vKiogU291cmNlcyBoZWxkIG9wZW4sIHBhc3Qgd2hpY2ggdGhlIGxlYXN0IHJlY2VudGx5IHVzZWQgb25lIGlzIGNsb3NlZCAobmV2ZXIgdGhlIG9uZSBzaG93bikuICovXG5leHBvcnQgY29uc3QgT1BFTl9SRUdJT05fU09VUkNFUyA9IDY7XG5cbmludGVyZmFjZSBFbnRyeSB7XG4gIG9wZW46IFJlZ2lvblNvdXJjZU9wZW5lcjtcbiAgLyoqIFRoZSBwbGFuZSBlYWNoIHNsaWNlIHNob3dzOyB1bmRlZmluZWQgPSB0aGUgc2xpY2UncyBvd24gaW5kZXguICovXG4gIHBsYW5lPzogbnVtYmVyO1xuICBzb3VyY2U6IFByb21pc2U8UmVnaW9uU291cmNlPiB8IG51bGw7XG4gIC8qKiBUaGUgcmVzb2x2ZWQgc291cmNlLCBvbmNlIG9wZW4uICovXG4gIHJlYWR5OiBSZWdpb25Tb3VyY2UgfCBudWxsO1xufVxuXG5pbnRlcmZhY2UgSW1hZ2VTb3VyY2VzIHtcbiAgLyoqIFRoZSBzb3VyY2Ugb3ZlciBldmVyeSBzbGljZSAoYCdwbGFuZXMnYCksIGlmIGFueS4gKi9cbiAgcGxhbmVzOiBFbnRyeSB8IG51bGw7XG4gIHBlclNsaWNlOiBNYXA8bnVtYmVyLCBFbnRyeT47XG4gIC8qKiBTb3VyY2UgZmVhdHVyZSBpZHMgdGFrZW4gaW50byB0aGUgd29ya2luZyBzZXQgKG9yIGRlbGV0ZWQpLCBwZXIgc2xpY2UuICovXG4gIHRha2VuOiBNYXA8bnVtYmVyLCBSZWFkb25seVNldDxzdHJpbmc+PjtcbiAgLyoqIFNsaWNlcyB3aG9zZSBzb3VyY2Ugd2FzIGltcG9ydGVkIChub3QgdGhlIGltYWdlJ3Mgb3duIHJlZ2lvbnMpOiBhIHNhdmUgd3JpdGVzIHRoZW0sIHRob3VnaFxuICAgKiAgbm90aGluZyB3YXMgdGFrZW4sIHNpbmNlIHRoZXkgYXJlIG9uIG5vIGZpbGUgeWV0LiAqL1xuICBpbXBvcnRlZDogU2V0PG51bWJlcj47XG59XG5cbmNvbnN0IE5PTkU6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuLyoqXG4gKiBUaGUgcmVnaW9uIHNvdXJjZXMgb2YgZXZlcnkgaW1hZ2UgdGhlIHN0b3JlIGhhcyBzZWVuLCBwZXIgc2xpY2UsIGFuZCBwZXIgc2xpY2UgdGhlIGlkcyBvZlxuICogdGhlIHNvdXJjZSBmZWF0dXJlcyB0YWtlbiBvdXQgb2YgdGhlIHNvdXJjZSAoaW50byB0aGUgd29ya2luZyBzZXQsIG9yIGRlbGV0ZWQpIOKAlCB0aG9zZSB0aGVcbiAqIHNvdXJjZSBubyBsb25nZXIgZHJhd3MgYW5kIGFuIGV4cG9ydCBsZWF2ZXMgb3V0LlxuICpcbiAqIFNvdXJjZXMgb3BlbiBsYXppbHksIHRoZSBmaXJzdCB0aW1lIHRoZWlyIHNsaWNlIGlzIHNob3duIG9yIHJlYWQsIGFuZCBhdCBtb3N0XG4gKiB7QGxpbmsgT1BFTl9SRUdJT05fU09VUkNFU30gc3RheSBvcGVuOiB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBhcmUgY2xvc2VkIGFuZCByZS1vcGVuZWQgZnJvbVxuICogdGhlaXIgb3BlbmVyIHdoZW4gdXNlZCBhZ2FpbiAoYSBzb3VyY2UncyBpZHMgYXJlIHN0YWJsZSwgc28gd2hhdCB3YXMgdGFrZW4gc3RheXMgdGFrZW4pLiBUaGVcbiAqIHNvdXJjZSBvZiB0aGUgc2xpY2Ugb24gc2NyZWVuICh7QGxpbmsgc2hvd30pIGlzIG5ldmVyIGNsb3NlZCBmb3IgYW5vdGhlcjogYSByZWFkIGFjcm9zcyBldmVyeVxuICogc2xpY2UgbXVzdCBub3QgY2xvc2UgdGhlIHNvdXJjZSB0aGUgdmlld2VyIGRyYXdzIGFuZCB0YWtlcyBmcm9tLlxuICovXG5leHBvcnQgY2xhc3MgUmVnaW9uU291cmNlU2NvcGUge1xuICBwcml2YXRlIHJlYWRvbmx5IGltYWdlcyA9IG5ldyBNYXA8c3RyaW5nLCBJbWFnZVNvdXJjZXM+KCk7XG4gIC8qKiBPcGVuIGVudHJpZXMsIGxlYXN0IHJlY2VudGx5IHVzZWQgZmlyc3QuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb3Blbk9yZGVyOiBFbnRyeVtdID0gW107XG4gIC8qKiBUaGUgZW50cnkgb2YgdGhlIHNsaWNlIG9uIHNjcmVlbjoga2VwdCBvcGVuLiAqL1xuICBwcml2YXRlIHNob3duOiBFbnRyeSB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBBdHRhY2ggYG9wZW5gIHRvIGBpbWFnZWAgZm9yIGBzbGljZXNgLCByZXBsYWNpbmcgKGFuZCBjbG9zaW5nKSB3aGF0IHdhcyB0aGVyZS4gYGltcG9ydGVkYCBuYW1lc1xuICAgKiB0aGUgc2xpY2VzIGl0IGJyaW5ncyB0aGF0IGEgc2F2ZSBtdXN0IHdyaXRlIChzZWUge0BsaW5rIGltcG9ydGVkU2xpY2VzfSk6IGZvciBhIHNvdXJjZSBvZiBvbmVcbiAgICogc2xpY2UsIHRoYXQgc2xpY2Ugd2hlbiBub24tZW1wdHk7IGZvciBhIGAncGxhbmVzJ2Agc291cmNlLCB0aGUgc2xpY2VzIGl0cyBwbGFuZXMgY292ZXIuXG4gICAqL1xuICBhdHRhY2goXG4gICAgaW1hZ2U6IHN0cmluZyxcbiAgICBvcGVuOiBSZWdpb25Tb3VyY2VPcGVuZXIsXG4gICAgc2xpY2VzOiBSZWdpb25Tb3VyY2VTbGljZXMsXG4gICAgaW1wb3J0ZWQ6IHJlYWRvbmx5IG51bWJlcltdID0gW10sXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlU291cmNlcyhpbWFnZSk7XG4gICAgY29uc3QgZW50cnk6IEVudHJ5ID0geyBvcGVuLCBzb3VyY2U6IG51bGwsIHJlYWR5OiBudWxsIH07XG4gICAgaWYgKHNsaWNlcyA9PT0gJ3BsYW5lcycpIHtcbiAgICAgIGlmIChzb3VyY2VzLnBsYW5lcykgdGhpcy5jbG9zZShzb3VyY2VzLnBsYW5lcyk7XG4gICAgICBzb3VyY2VzLnBsYW5lcyA9IGVudHJ5O1xuICAgICAgc291cmNlcy5wZXJTbGljZS5mb3JFYWNoKChlKSA9PiB0aGlzLmNsb3NlKGUpKTtcbiAgICAgIHNvdXJjZXMucGVyU2xpY2UuY2xlYXIoKTtcbiAgICAgIHNvdXJjZXMudGFrZW4uY2xlYXIoKTtcbiAgICAgIHNvdXJjZXMuaW1wb3J0ZWQgPSBuZXcgU2V0KGltcG9ydGVkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgb2xkID0gc291cmNlcy5wZXJTbGljZS5nZXQoc2xpY2VzLnNsaWNlKTtcbiAgICAgIGlmIChvbGQpIHRoaXMuY2xvc2Uob2xkKTtcbiAgICAgIGVudHJ5LnBsYW5lID0gc2xpY2VzLnBsYW5lID8/IDA7XG4gICAgICBzb3VyY2VzLnBlclNsaWNlLnNldChzbGljZXMuc2xpY2UsIGVudHJ5KTtcbiAgICAgIHNvdXJjZXMudGFrZW4uZGVsZXRlKHNsaWNlcy5zbGljZSk7XG4gICAgICBpZiAoaW1wb3J0ZWQubGVuZ3RoKSBzb3VyY2VzLmltcG9ydGVkLmFkZChzbGljZXMuc2xpY2UpO1xuICAgICAgZWxzZSBzb3VyY2VzLmltcG9ydGVkLmRlbGV0ZShzbGljZXMuc2xpY2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBEcm9wIGV2ZXJ5IHNvdXJjZSBvZiBgaW1hZ2VgIChjbG9zaW5nIHRoZSBvcGVuIG9uZXMpIGFuZCB3aGF0IHdhcyB0YWtlbiBmcm9tIHRoZW0uICovXG4gIGRldGFjaEltYWdlKGltYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKTtcbiAgICBpZiAoIXNvdXJjZXMpIHJldHVybjtcbiAgICBpZiAoc291cmNlcy5wbGFuZXMpIHRoaXMuY2xvc2Uoc291cmNlcy5wbGFuZXMpO1xuICAgIHNvdXJjZXMucGVyU2xpY2UuZm9yRWFjaCgoZSkgPT4gdGhpcy5jbG9zZShlKSk7XG4gICAgdGhpcy5pbWFnZXMuZGVsZXRlKGltYWdlKTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBzb3VyY2Ugb2Ygb25lIHNsaWNlIG9mIGBpbWFnZWAuICovXG4gIGRldGFjaFNsaWNlKGltYWdlOiBzdHJpbmcsIHNsaWNlOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzb3VyY2VzID0gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKTtcbiAgICBjb25zdCBlbnRyeSA9IHNvdXJjZXM/LnBlclNsaWNlLmdldChzbGljZSk7XG4gICAgaWYgKCFzb3VyY2VzIHx8ICFlbnRyeSkgcmV0dXJuO1xuICAgIHRoaXMuY2xvc2UoZW50cnkpO1xuICAgIHNvdXJjZXMucGVyU2xpY2UuZGVsZXRlKHNsaWNlKTtcbiAgICBzb3VyY2VzLnRha2VuLmRlbGV0ZShzbGljZSk7XG4gICAgc291cmNlcy5pbXBvcnRlZC5kZWxldGUoc2xpY2UpO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZSBvbiBzY3JlZW4gKG51bGw6IG5vbmUpOiBpdHMgc291cmNlIHN0YXlzIG9wZW4gd2hpbGUgb3RoZXJzIGFyZSByZWFkLiAqL1xuICBzaG93KGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHNsaWNlOiBudW1iZXIgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5zaG93biA9IGltYWdlICYmIHNsaWNlICE9PSBudWxsID8gdGhpcy5lbnRyeShpbWFnZSwgc2xpY2UpIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBpbWFnZWAgaGFzIGEgc291cmNlIGZvciBgc2xpY2VgLiAqL1xuICBoYXMoaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2xpY2U6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIWltYWdlICYmICEhdGhpcy5lbnRyeShpbWFnZSwgc2xpY2UpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgYHNsaWNlYCBvZiBgaW1hZ2VgIGhhcyBhIHNvdXJjZSBvZiBpdHMgb3duIChub3QgYSBgJ3BsYW5lcydgIHNvdXJjZSdzIHBsYW5lKS4gKi9cbiAgaGFzT3duU291cmNlKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHNsaWNlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFpbWFnZSAmJiAhIXRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnBlclNsaWNlLmhhcyhzbGljZSk7XG4gIH1cblxuICAvKiogRXZlcnkgc2xpY2Ugb2YgYGltYWdlYCB3aXRoIGEgc291cmNlIG9mIGl0cyBvd24gKG5vdCBjb3VudGluZyBhIGAncGxhbmVzJ2Agc291cmNlKS4gKi9cbiAgc2xpY2VzV2l0aFNvdXJjZShpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogbnVtYmVyW10ge1xuICAgIGlmICghaW1hZ2UpIHJldHVybiBbXTtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy5wZXJTbGljZS5rZXlzKCkgPz8gW10pLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBpbWFnZWAgaGFzIG9uZSBzb3VyY2Ugb3ZlciBhbGwgaXRzIHNsaWNlcy4gKi9cbiAgaGFzUGxhbmVzU291cmNlKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFpbWFnZSAmJiAhIXRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnBsYW5lcztcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgc291cmNlIGJlaGluZCBgc2xpY2VgIG9mIGBpbWFnZWAsIG9wZW5pbmcgaXQgaWYgbmVlZGVkLiBSZXNvbHZlcyBudWxsIHdoZW4gdGhlcmUgaXNcbiAgICogbm9uZSwgYW5kIHJlamVjdHMgd2hlbiBpdCBjYW5ub3QgYmUgb3BlbmVkLlxuICAgKi9cbiAgYXN5bmMgYmluZGluZyhpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzbGljZTogbnVtYmVyKTogUHJvbWlzZTxSZWdpb25Tb3VyY2VCaW5kaW5nIHwgbnVsbD4ge1xuICAgIGNvbnN0IGVudHJ5ID0gaW1hZ2UgPyB0aGlzLmVudHJ5KGltYWdlLCBzbGljZSkgOiBudWxsO1xuICAgIGlmICghZW50cnkpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHNvdXJjZSA9IGF3YWl0IHRoaXMub3BlbkVudHJ5KGVudHJ5KTtcbiAgICByZXR1cm4geyBzb3VyY2UsIHBsYW5lOiBlbnRyeS5wbGFuZSA/PyBzbGljZSB9O1xuICB9XG5cbiAgLyoqIFRoZSBpZHMgdGFrZW4gZnJvbSBgc2xpY2VgJ3Mgc291cmNlLiAqL1xuICB0YWtlbihpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzbGljZTogbnVtYmVyKTogUmVhZG9ubHlTZXQ8c3RyaW5nPiB7XG4gICAgcmV0dXJuIChpbWFnZSAmJiB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy50YWtlbi5nZXQoc2xpY2UpKSB8fCBOT05FO1xuICB9XG5cbiAgLyoqIEV2ZXJ5IGlkIHRha2VuIGZyb20gYW55IHNsaWNlIG9mIGBpbWFnZWAgKGEgYCdwbGFuZXMnYCBzb3VyY2UncyBpZHMgYXJlIHVuaXF1ZSBhY3Jvc3MgdGhlbSkuICovXG4gIGFsbFRha2VuKGltYWdlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgdGFrZW4gPSBpbWFnZSA/IHRoaXMuaW1hZ2VzLmdldChpbWFnZSk/LnRha2VuIDogdW5kZWZpbmVkO1xuICAgIHJldHVybiB0YWtlbiA/IEFycmF5LmZyb20odGFrZW4udmFsdWVzKCkpLmZsYXRNYXAoKGlkcykgPT4gQXJyYXkuZnJvbShpZHMpKSA6IFtdO1xuICB9XG5cbiAgLyoqIFRoZSBzbGljZXMgb2YgYGltYWdlYCB3aG9zZSBzb3VyY2Ugd2FzIGltcG9ydGVkIChzZWUge0BsaW5rIGF0dGFjaH0pLCBpbiBvcmRlci4gKi9cbiAgaW1wb3J0ZWRTbGljZXMoaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCk6IG51bWJlcltdIHtcbiAgICBjb25zdCBpbXBvcnRlZCA9IGltYWdlID8gdGhpcy5pbWFnZXMuZ2V0KGltYWdlKT8uaW1wb3J0ZWQgOiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIGltcG9ydGVkID8gQXJyYXkuZnJvbShpbXBvcnRlZCkuc29ydCgoYSwgYikgPT4gYSAtIGIpIDogW107XG4gIH1cblxuICAvKiogVGhlIHNsaWNlcyBvZiBgaW1hZ2VgIHdpdGggYW55dGhpbmcgdGFrZW4gZnJvbSB0aGVpciBzb3VyY2UuICovXG4gIHNsaWNlc1dpdGhUYWtlbihpbWFnZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogbnVtYmVyW10ge1xuICAgIGNvbnN0IHRha2VuID0gaW1hZ2UgPyB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpPy50YWtlbiA6IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gdGFrZW4gPyBBcnJheS5mcm9tKHRha2VuLmtleXMoKSkgOiBbXTtcbiAgfVxuXG4gIC8qKiBSZXBsYWNlIHRoZSBpZHMgdGFrZW4gZnJvbSBgc2xpY2VgJ3Mgc291cmNlIChjb3B5LW9uLXdyaXRlOiBgaWRzYCBpcyBrZXB0IGFzIGdpdmVuKS4gKi9cbiAgc2V0VGFrZW4oaW1hZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2xpY2U6IG51bWJlciwgaWRzOiBSZWFkb25seVNldDxzdHJpbmc+KTogdm9pZCB7XG4gICAgaWYgKCFpbWFnZSkgcmV0dXJuO1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIGlmICghc291cmNlcykgcmV0dXJuO1xuICAgIGlmIChpZHMuc2l6ZSkgc291cmNlcy50YWtlbi5zZXQoc2xpY2UsIGlkcyk7XG4gICAgZWxzZSBzb3VyY2VzLnRha2VuLmRlbGV0ZShzbGljZSk7XG4gIH1cblxuICBwcml2YXRlIGVudHJ5KGltYWdlOiBzdHJpbmcsIHNsaWNlOiBudW1iZXIpOiBFbnRyeSB8IG51bGwge1xuICAgIGNvbnN0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIHJldHVybiBzb3VyY2VzPy5wZXJTbGljZS5nZXQoc2xpY2UpID8/IHNvdXJjZXM/LnBsYW5lcyA/PyBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBpbWFnZVNvdXJjZXMoaW1hZ2U6IHN0cmluZyk6IEltYWdlU291cmNlcyB7XG4gICAgbGV0IHNvdXJjZXMgPSB0aGlzLmltYWdlcy5nZXQoaW1hZ2UpO1xuICAgIGlmICghc291cmNlcykge1xuICAgICAgc291cmNlcyA9IHsgcGxhbmVzOiBudWxsLCBwZXJTbGljZTogbmV3IE1hcCgpLCB0YWtlbjogbmV3IE1hcCgpLCBpbXBvcnRlZDogbmV3IFNldCgpIH07XG4gICAgICB0aGlzLmltYWdlcy5zZXQoaW1hZ2UsIHNvdXJjZXMpO1xuICAgIH1cbiAgICByZXR1cm4gc291cmNlcztcbiAgfVxuXG4gIHByaXZhdGUgb3BlbkVudHJ5KGVudHJ5OiBFbnRyeSk6IFByb21pc2U8UmVnaW9uU291cmNlPiB7XG4gICAgY29uc3QgYXQgPSB0aGlzLm9wZW5PcmRlci5pbmRleE9mKGVudHJ5KTtcbiAgICBpZiAoYXQgPj0gMCkgdGhpcy5vcGVuT3JkZXIuc3BsaWNlKGF0LCAxKTtcbiAgICB0aGlzLm9wZW5PcmRlci5wdXNoKGVudHJ5KTtcbiAgICBpZiAoIWVudHJ5LnNvdXJjZSkge1xuICAgICAgY29uc3Qgb3BlbmluZyA9IGVudHJ5Lm9wZW4oKTtcbiAgICAgIGVudHJ5LnNvdXJjZSA9IG9wZW5pbmc7XG4gICAgICBvcGVuaW5nLnRoZW4oXG4gICAgICAgIChzb3VyY2UpID0+IHtcbiAgICAgICAgICBpZiAoZW50cnkuc291cmNlID09PSBvcGVuaW5nKSBlbnRyeS5yZWFkeSA9IHNvdXJjZTtcbiAgICAgICAgICBlbHNlIHNvdXJjZS5kaXNwb3NlKCk7IC8vIGNsb3NlZCB3aGlsZSBpdCBvcGVuZWRcbiAgICAgICAgfSxcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIGlmIChlbnRyeS5zb3VyY2UgPT09IG9wZW5pbmcpIGVudHJ5LnNvdXJjZSA9IG51bGw7IC8vIHRyeSBhZ2FpbiBuZXh0IHRpbWVcbiAgICAgICAgfSxcbiAgICAgICk7XG4gICAgfVxuICAgIHdoaWxlICh0aGlzLm9wZW5PcmRlci5sZW5ndGggPiBPUEVOX1JFR0lPTl9TT1VSQ0VTKSB7XG4gICAgICBjb25zdCBbb2xkZXN0XSA9IHRoaXMub3Blbk9yZGVyLnNwbGljZShcbiAgICAgICAgdGhpcy5vcGVuT3JkZXIuZmluZEluZGV4KChlKSA9PiBlICE9PSB0aGlzLnNob3duKSxcbiAgICAgICAgMSxcbiAgICAgICk7XG4gICAgICB0aGlzLmNsb3NlU291cmNlKG9sZGVzdCk7XG4gICAgfVxuICAgIHJldHVybiBlbnRyeS5zb3VyY2U7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlKGVudHJ5OiBFbnRyeSk6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gdGhpcy5vcGVuT3JkZXIuaW5kZXhPZihlbnRyeSk7XG4gICAgaWYgKGF0ID49IDApIHRoaXMub3Blbk9yZGVyLnNwbGljZShhdCwgMSk7XG4gICAgdGhpcy5jbG9zZVNvdXJjZShlbnRyeSk7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlU291cmNlKGVudHJ5OiBFbnRyeSk6IHZvaWQge1xuICAgIGVudHJ5LnJlYWR5Py5kaXNwb3NlKCk7XG4gICAgZW50cnkucmVhZHkgPSBudWxsO1xuICAgIGVudHJ5LnNvdXJjZSA9IG51bGw7XG4gIH1cbn1cbiJdfQ==