@jax-data-science/sci-image-visualizer 0.11.0 → 0.12.1
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.
- package/esm2022/index.mjs +4 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +18 -6
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +70 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +29 -14
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +11 -1
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +9 -4
- package/esm2022/lib/region-editor/region-editor.component.mjs +46 -41
- package/esm2022/lib/region-import/label-volume.mjs +35 -4
- package/esm2022/lib/region-import/ome-zarr-labels.mjs +253 -0
- package/esm2022/lib/region-import/open-annotations.mjs +289 -0
- package/esm2022/lib/region-import/zarr-codecs.mjs +167 -0
- package/esm2022/lib/region-import/zip.mjs +157 -0
- package/esm2022/lib/routing-visualizer.service.mjs +20 -7
- package/esm2022/lib/visualizer/region-load.mjs +16 -1
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DnPlIP2F.mjs} +1103 -71
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DnPlIP2F.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-Bs987_-E.mjs} +4 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-DEDSm_NL.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-Bs987_-E.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +7 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +13 -1
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +40 -1
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +11 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +5 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +6 -1
- package/lib/region-editor/region-editor.component.d.ts +5 -4
- package/lib/region-import/label-volume.d.ts +4 -0
- package/lib/region-import/ome-zarr-labels.d.ts +36 -0
- package/lib/region-import/open-annotations.d.ts +73 -0
- package/lib/region-import/zarr-codecs.d.ts +14 -0
- package/lib/region-import/zip.d.ts +31 -0
- package/lib/routing-visualizer.service.d.ts +9 -1
- package/package.json +2 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BELcx0jv.mjs.map +0 -1
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
const EOCD = 0x06054b50;
|
|
2
|
+
const ZIP64_LOCATOR = 0x07064b50;
|
|
3
|
+
const ZIP64_EOCD = 0x06064b50;
|
|
4
|
+
const CENTRAL = 0x02014b50;
|
|
5
|
+
const LOCAL = 0x04034b50;
|
|
6
|
+
const U32 = 0xffffffff;
|
|
7
|
+
/** Whether a file name is a zip archive. */
|
|
8
|
+
export function isZipName(name) {
|
|
9
|
+
return /\.zip$/i.test(name);
|
|
10
|
+
}
|
|
11
|
+
/** The members of the archive in `bytes` (directories and macOS metadata left out). */
|
|
12
|
+
export function readZip(bytes, inflateRaw = platformInflateRaw) {
|
|
13
|
+
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
14
|
+
const eocd = findEocd(view);
|
|
15
|
+
let count = view.getUint16(eocd + 10, true);
|
|
16
|
+
let dirOffset = view.getUint32(eocd + 16, true);
|
|
17
|
+
if (count === 0xffff || dirOffset === U32) {
|
|
18
|
+
const locator = eocd - 20;
|
|
19
|
+
if (locator < 0 || view.getUint32(locator, true) !== ZIP64_LOCATOR)
|
|
20
|
+
throw new Error('zip: ZIP64 locator missing');
|
|
21
|
+
const z64 = num(view, locator + 8);
|
|
22
|
+
if (view.getUint32(z64, true) !== ZIP64_EOCD)
|
|
23
|
+
throw new Error('zip: ZIP64 directory end missing');
|
|
24
|
+
count = num(view, z64 + 32);
|
|
25
|
+
dirOffset = num(view, z64 + 48);
|
|
26
|
+
}
|
|
27
|
+
const entries = [];
|
|
28
|
+
let at = dirOffset;
|
|
29
|
+
for (let i = 0; i < count; i++) {
|
|
30
|
+
if (view.getUint32(at, true) !== CENTRAL)
|
|
31
|
+
throw new Error('zip: bad central directory');
|
|
32
|
+
const flags = view.getUint16(at + 8, true);
|
|
33
|
+
const method = view.getUint16(at + 10, true);
|
|
34
|
+
const crc = view.getUint32(at + 16, true);
|
|
35
|
+
let compressed = view.getUint32(at + 20, true);
|
|
36
|
+
let size = view.getUint32(at + 24, true);
|
|
37
|
+
const nameLen = view.getUint16(at + 28, true);
|
|
38
|
+
const extraLen = view.getUint16(at + 30, true);
|
|
39
|
+
const commentLen = view.getUint16(at + 32, true);
|
|
40
|
+
let local = view.getUint32(at + 42, true);
|
|
41
|
+
const nameBytes = bytes.subarray(at + 46, at + 46 + nameLen);
|
|
42
|
+
const name = (flags & 0x800 ? new TextDecoder() : new TextDecoder('latin1'))
|
|
43
|
+
.decode(nameBytes)
|
|
44
|
+
.replace(/\\/g, '/');
|
|
45
|
+
// ZIP64: the 32-bit fields that overflowed are in the extra field, in this order.
|
|
46
|
+
let x = at + 46 + nameLen;
|
|
47
|
+
const extraEnd = x + extraLen;
|
|
48
|
+
while (x + 4 <= extraEnd) {
|
|
49
|
+
const id = view.getUint16(x, true);
|
|
50
|
+
const len = view.getUint16(x + 2, true);
|
|
51
|
+
if (id === 0x0001) {
|
|
52
|
+
let p = x + 4;
|
|
53
|
+
if (size === U32)
|
|
54
|
+
((size = num(view, p)), (p += 8));
|
|
55
|
+
if (compressed === U32)
|
|
56
|
+
((compressed = num(view, p)), (p += 8));
|
|
57
|
+
if (local === U32)
|
|
58
|
+
local = num(view, p);
|
|
59
|
+
}
|
|
60
|
+
x += 4 + len;
|
|
61
|
+
}
|
|
62
|
+
at = extraEnd + commentLen;
|
|
63
|
+
if (name.endsWith('/') || /(^|\/)__MACOSX\//.test(name) || /(^|\/)\.DS_Store$/.test(name))
|
|
64
|
+
continue;
|
|
65
|
+
const entry = { flags, method, crc, compressed, size, local };
|
|
66
|
+
entries.push({ name, size, bytes: () => readMember(bytes, view, name, entry, inflateRaw) });
|
|
67
|
+
}
|
|
68
|
+
return entries;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* `files` with every `.zip` among them replaced by its members, named by their paths in it (a
|
|
72
|
+
* single top folder the archive wraps everything in is kept, as a folder pick would keep it).
|
|
73
|
+
*/
|
|
74
|
+
export async function expandZips(files, inflateRaw) {
|
|
75
|
+
const out = [];
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
if (!isZipName(file.name)) {
|
|
78
|
+
out.push(file);
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
for (const entry of readZip(await file.bytes(), inflateRaw)) {
|
|
82
|
+
out.push({
|
|
83
|
+
name: entry.name,
|
|
84
|
+
bytes: () => entry.bytes(),
|
|
85
|
+
text: async () => new TextDecoder().decode(await entry.bytes()),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
async function readMember(bytes, view, name, m, inflateRaw) {
|
|
92
|
+
if (m.flags & 0x1)
|
|
93
|
+
throw new Error(`zip: ${name} is encrypted`);
|
|
94
|
+
if (view.getUint32(m.local, true) !== LOCAL)
|
|
95
|
+
throw new Error(`zip: ${name}: bad local header`);
|
|
96
|
+
const start = m.local + 30 + view.getUint16(m.local + 26, true) + view.getUint16(m.local + 28, true);
|
|
97
|
+
const raw = bytes.subarray(start, start + m.compressed);
|
|
98
|
+
if (raw.length !== m.compressed)
|
|
99
|
+
throw new Error(`zip: ${name} is truncated`);
|
|
100
|
+
let out;
|
|
101
|
+
if (m.method === 0)
|
|
102
|
+
out = raw;
|
|
103
|
+
else if (m.method === 8)
|
|
104
|
+
out = await inflateRaw(raw);
|
|
105
|
+
else
|
|
106
|
+
throw new Error(`zip: ${name} uses compression method ${m.method}, not stored or deflate`);
|
|
107
|
+
if (out.length !== m.size)
|
|
108
|
+
throw new Error(`zip: ${name} is ${out.length} bytes, expected ${m.size}`);
|
|
109
|
+
if (crc32(out) !== m.crc)
|
|
110
|
+
throw new Error(`zip: ${name} fails its CRC check`);
|
|
111
|
+
return out;
|
|
112
|
+
}
|
|
113
|
+
/** The end-of-central-directory record: the last one, within the 64 KiB a comment may take. */
|
|
114
|
+
function findEocd(view) {
|
|
115
|
+
const stop = Math.max(0, view.byteLength - 22 - 0xffff);
|
|
116
|
+
for (let at = view.byteLength - 22; at >= stop; at--) {
|
|
117
|
+
if (view.getUint32(at, true) === EOCD)
|
|
118
|
+
return at;
|
|
119
|
+
}
|
|
120
|
+
throw new Error('zip: not a zip archive (no central directory)');
|
|
121
|
+
}
|
|
122
|
+
/** A little-endian u64 that fits a double (archives under 8 PB). */
|
|
123
|
+
function num(view, at) {
|
|
124
|
+
return view.getUint32(at, true) + view.getUint32(at + 4, true) * 0x100000000;
|
|
125
|
+
}
|
|
126
|
+
let crcTable = null;
|
|
127
|
+
/** CRC-32 (IEEE), as zip records it. */
|
|
128
|
+
export function crc32(data) {
|
|
129
|
+
if (!crcTable) {
|
|
130
|
+
crcTable = new Uint32Array(256);
|
|
131
|
+
for (let n = 0; n < 256; n++) {
|
|
132
|
+
let c = n;
|
|
133
|
+
for (let k = 0; k < 8; k++)
|
|
134
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
135
|
+
crcTable[n] = c >>> 0;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let c = 0xffffffff;
|
|
139
|
+
for (let i = 0; i < data.length; i++)
|
|
140
|
+
c = crcTable[(c ^ data[i]) & 0xff] ^ (c >>> 8);
|
|
141
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
142
|
+
}
|
|
143
|
+
async function platformInflateRaw(bytes) {
|
|
144
|
+
if (typeof DecompressionStream === 'undefined')
|
|
145
|
+
throw new Error('zip: deflated members need DecompressionStream');
|
|
146
|
+
let inflater;
|
|
147
|
+
try {
|
|
148
|
+
// Compression Streams' raw DEFLATE (Chrome 103, Firefox 113, Safari 16.4 on).
|
|
149
|
+
inflater = new DecompressionStream('deflate-raw');
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new Error('zip: this browser cannot inflate zip members (no DecompressionStream "deflate-raw")');
|
|
153
|
+
}
|
|
154
|
+
const stream = new Blob([bytes]).stream().pipeThrough(inflater);
|
|
155
|
+
return new Uint8Array(await new Response(stream).arrayBuffer());
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemlwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yZWdpb24taW1wb3J0L3ppcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1QkEsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDO0FBQ3hCLE1BQU0sYUFBYSxHQUFHLFVBQVUsQ0FBQztBQUNqQyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUM7QUFDOUIsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDO0FBQzNCLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQztBQUN6QixNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUM7QUFFdkIsNENBQTRDO0FBQzVDLE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBWTtJQUNwQyxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDOUIsQ0FBQztBQUVELHVGQUF1RjtBQUN2RixNQUFNLFVBQVUsT0FBTyxDQUFDLEtBQWlCLEVBQUUsYUFBeUIsa0JBQWtCO0lBQ3BGLE1BQU0sSUFBSSxHQUFHLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDNUUsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxHQUFHLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1QyxJQUFJLFNBQVMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDaEQsSUFBSSxLQUFLLEtBQUssTUFBTSxJQUFJLFNBQVMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUMxQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzFCLElBQUksT0FBTyxHQUFHLENBQUMsSUFBSSxJ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QUMsQ0FBQztJQUM1RSxPQUFPLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztBQUNsRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgbWVtYmVycyBvZiBhIGAuemlwYCwgcmVhZCBpbiB0aGUgYnJvd3NlcjogYW5ub3RhdGlvbnMgaGFuZGVkIG92ZXIgYXMgb25lIGFyY2hpdmUgKGEgZm9sZGVyXG4gKiBvZiBwZXItc2xpY2UgR2VvSlNPTiwgYSBsYWJlbCB2b2x1bWUgd2l0aCBpdHMgb250b2xvZ3ksIGFuIE9NRS1aYXJyIHN0b3JlJ3MgbGFiZWxzKS5cbiAqXG4gKiBPbmx5IHdoYXQgc3VjaCBhcmNoaXZlcyB1c2U6IHN0b3JlZCBvciBkZWZsYXRlZCBtZW1iZXJzLCBaSVA2NCBzaXplcyBhbmQgb2Zmc2V0cywgVVRGLTggb3JcbiAqIGxlZ2FjeSBuYW1lcy4gQW4gZW5jcnlwdGVkIG9yIG90aGVyd2lzZSBjb21wcmVzc2VkIG1lbWJlciB0aHJvd3Mgd2hlbiBpdCBpcyByZWFkLCByYXRoZXIgdGhhbiBiZVxuICogcmVhZCB3cm9uZ2x5OyBhIG1lbWJlcidzIENSQy0zMiBpcyBjaGVja2VkLiBNZW1iZXJzIGFyZSByZWFkIG9uIGRlbWFuZCwgc28gYW4gYXJjaGl2ZSBvZiBtYW55XG4gKiBjaHVua3MgKGEgemFyciBzdG9yZSkgaXMgbm90IGluZmxhdGVkIHdob2xlLiBQdXJlOiB1c2FibGUgZnJvbSB3b3JrZXJzLlxuICovXG5pbXBvcnQgdHlwZSB7IFJlZ2lvbkltcG9ydEZpbGUgfSBmcm9tICcuL3JlZ2lvbi1pbXBvcnQnO1xuXG4vKiogT25lIG1lbWJlciBvZiBhbiBhcmNoaXZlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBaaXBFbnRyeSB7XG4gIC8qKiBJdHMgcGF0aCBpbiB0aGUgYXJjaGl2ZSwgJy8nLXNlcGFyYXRlZC4gKi9cbiAgbmFtZTogc3RyaW5nO1xuICAvKiogSXRzIHVuY29tcHJlc3NlZCBzaXplLCBpbiBieXRlcy4gKi9cbiAgc2l6ZTogbnVtYmVyO1xuICBieXRlcygpOiBQcm9taXNlPFVpbnQ4QXJyYXk+O1xufVxuXG4vKiogSW5mbGF0ZSByYXcgREVGTEFURSBkYXRhIChkZWZhdWx0OiB0aGUgcGxhdGZvcm0ncyBgRGVjb21wcmVzc2lvblN0cmVhbSgnZGVmbGF0ZS1yYXcnKWApLiAqL1xuZXhwb3J0IHR5cGUgSW5mbGF0ZVJhdyA9IChieXRlczogVWludDhBcnJheSkgPT4gUHJvbWlzZTxVaW50OEFycmF5PjtcblxuY29uc3QgRU9DRCA9IDB4MDYwNTRiNTA7XG5jb25zdCBaSVA2NF9MT0NBVE9SID0gMHgwNzA2NGI1MDtcbmNvbnN0IFpJUDY0X0VPQ0QgPSAweDA2MDY0YjUwO1xuY29uc3QgQ0VOVFJBTCA9IDB4MDIwMTRiNTA7XG5jb25zdCBMT0NBTCA9IDB4MDQwMzRiNTA7XG5jb25zdCBVMzIgPSAweGZmZmZmZmZmO1xuXG4vKiogV2hldGhlciBhIGZpbGUgbmFtZSBpcyBhIHppcCBhcmNoaXZlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzWmlwTmFtZShuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIC9cXC56aXAkL2kudGVzdChuYW1lKTtcbn1cblxuLyoqIFRoZSBtZW1iZXJzIG9mIHRoZSBhcmNoaXZlIGluIGBieXRlc2AgKGRpcmVjdG9yaWVzIGFuZCBtYWNPUyBtZXRhZGF0YSBsZWZ0IG91dCkuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZFppcChieXRlczogVWludDhBcnJheSwgaW5mbGF0ZVJhdzogSW5mbGF0ZVJhdyA9IHBsYXRmb3JtSW5mbGF0ZVJhdyk6IFppcEVudHJ5W10ge1xuICBjb25zdCB2aWV3ID0gbmV3IERhdGFWaWV3KGJ5dGVzLmJ1ZmZlciwgYnl0ZXMuYnl0ZU9mZnNldCwgYnl0ZXMuYnl0ZUxlbmd0aCk7XG4gIGNvbnN0IGVvY2QgPSBmaW5kRW9jZCh2aWV3KTtcbiAgbGV0IGNvdW50ID0gdmlldy5nZXRVaW50MTYoZW9jZCArIDEwLCB0cnVlKTtcbiAgbGV0IGRpck9mZnNldCA9IHZpZXcuZ2V0VWludDMyKGVvY2QgKyAxNiwgdHJ1ZSk7XG4gIGlmIChjb3VudCA9PT0gMHhmZmZmIHx8IGRpck9mZnNldCA9PT0gVTMyKSB7XG4gICAgY29uc3QgbG9jYXRvciA9IGVvY2QgLSAyMDtcbiAgICBpZiAobG9jYXRvciA8IDAgfHwgdmlldy5nZXRVaW50MzIobG9jYXRvciwgdHJ1ZSkgIT09IFpJUDY0X0xPQ0FUT1IpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogWklQNjQgbG9jYXRvciBtaXNzaW5nJyk7XG4gICAgY29uc3QgejY0ID0gbnVtKHZpZXcsIGxvY2F0b3IgKyA4KTtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoejY0LCB0cnVlKSAhPT0gWklQNjRfRU9DRCkgdGhyb3cgbmV3IEVycm9yKCd6aXA6IFpJUDY0IGRpcmVjdG9yeSBlbmQgbWlzc2luZycpO1xuICAgIGNvdW50ID0gbnVtKHZpZXcsIHo2NCArIDMyKTtcbiAgICBkaXJPZmZzZXQgPSBudW0odmlldywgejY0ICsgNDgpO1xuICB9XG4gIGNvbnN0IGVudHJpZXM6IFppcEVudHJ5W10gPSBbXTtcbiAgbGV0IGF0ID0gZGlyT2Zmc2V0O1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGNvdW50OyBpKyspIHtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoYXQsIHRydWUpICE9PSBDRU5UUkFMKSB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogYmFkIGNlbnRyYWwgZGlyZWN0b3J5Jyk7XG4gICAgY29uc3QgZmxhZ3MgPSB2aWV3LmdldFVpbnQxNihhdCArIDgsIHRydWUpO1xuICAgIGNvbnN0IG1ldGhvZCA9IHZpZXcuZ2V0VWludDE2KGF0ICsgMTAsIHRydWUpO1xuICAgIGNvbnN0IGNyYyA9IHZpZXcuZ2V0VWludDMyKGF0ICsgMTYsIHRydWUpO1xuICAgIGxldCBjb21wcmVzc2VkID0gdmlldy5nZXRVaW50MzIoYXQgKyAyMCwgdHJ1ZSk7XG4gICAgbGV0IHNpemUgPSB2aWV3LmdldFVpbnQzMihhdCArIDI0LCB0cnVlKTtcbiAgICBjb25zdCBuYW1lTGVuID0gdmlldy5nZXRVaW50MTYoYXQgKyAyOCwgdHJ1ZSk7XG4gICAgY29uc3QgZXh0cmFMZW4gPSB2aWV3LmdldFVpbnQxNihhdCArIDMwLCB0cnVlKTtcbiAgICBjb25zdCBjb21tZW50TGVuID0gdmlldy5nZXRVaW50MTYoYXQgKyAzMiwgdHJ1ZSk7XG4gICAgbGV0IGxvY2FsID0gdmlldy5nZXRVaW50MzIoYXQgKyA0MiwgdHJ1ZSk7XG4gICAgY29uc3QgbmFtZUJ5dGVzID0gYnl0ZXMuc3ViYXJyYXkoYXQgKyA0NiwgYXQgKyA0NiArIG5hbWVMZW4pO1xuICAgIGNvbnN0IG5hbWUgPSAoZmxhZ3MgJiAweDgwMCA/IG5ldyBUZXh0RGVjb2RlcigpIDogbmV3IFRleHREZWNvZGVyKCdsYXRpbjEnKSlcbiAgICAgIC5kZWNvZGUobmFtZUJ5dGVzKVxuICAgICAgLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgICAvLyBaSVA2NDogdGhlIDMyLWJpdCBmaWVsZHMgdGhhdCBvdmVyZmxvd2VkIGFyZSBpbiB0aGUgZXh0cmEgZmllbGQsIGluIHRoaXMgb3JkZXIuXG4gICAgbGV0IHggPSBhdCArIDQ2ICsgbmFtZUxlbjtcbiAgICBjb25zdCBleHRyYUVuZCA9IHggKyBleHRyYUxlbjtcbiAgICB3aGlsZSAoeCArIDQgPD0gZXh0cmFFbmQpIHtcbiAgICAgIGNvbnN0IGlkID0gdmlldy5nZXRVaW50MTYoeCwgdHJ1ZSk7XG4gICAgICBjb25zdCBsZW4gPSB2aWV3LmdldFVpbnQxNih4ICsgMiwgdHJ1ZSk7XG4gICAgICBpZiAoaWQgPT09IDB4MDAwMSkge1xuICAgICAgICBsZXQgcCA9IHggKyA0O1xuICAgICAgICBpZiAoc2l6ZSA9PT0gVTMyKSAoKHNpemUgPSBudW0odmlldywgcCkpLCAocCArPSA4KSk7XG4gICAgICAgIGlmIChjb21wcmVzc2VkID09PSBVMzIpICgoY29tcHJlc3NlZCA9IG51bSh2aWV3LCBwKSksIChwICs9IDgpKTtcbiAgICAgICAgaWYgKGxvY2FsID09PSBVMzIpIGxvY2FsID0gbnVtKHZpZXcsIHApO1xuICAgICAgfVxuICAgICAgeCArPSA0ICsgbGVuO1xuICAgIH1cbiAgICBhdCA9IGV4dHJhRW5kICsgY29tbWVudExlbjtcbiAgICBpZiAobmFtZS5lbmRzV2l0aCgnLycpIHx8IC8oXnxcXC8pX19NQUNPU1hcXC8vLnRlc3QobmFtZSkgfHwgLyhefFxcLylcXC5EU19TdG9yZSQvLnRlc3QobmFtZSkpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGVudHJ5ID0geyBmbGFncywgbWV0aG9kLCBjcmMsIGNvbXByZXNzZWQsIHNpemUsIGxvY2FsIH07XG4gICAgZW50cmllcy5wdXNoKHsgbmFtZSwgc2l6ZSwgYnl0ZXM6ICgpID0+IHJlYWRNZW1iZXIoYnl0ZXMsIHZpZXcsIG5hbWUsIGVudHJ5LCBpbmZsYXRlUmF3KSB9KTtcbiAgfVxuICByZXR1cm4gZW50cmllcztcbn1cblxuLyoqXG4gKiBgZmlsZXNgIHdpdGggZXZlcnkgYC56aXBgIGFtb25nIHRoZW0gcmVwbGFjZWQgYnkgaXRzIG1lbWJlcnMsIG5hbWVkIGJ5IHRoZWlyIHBhdGhzIGluIGl0IChhXG4gKiBzaW5nbGUgdG9wIGZvbGRlciB0aGUgYXJjaGl2ZSB3cmFwcyBldmVyeXRoaW5nIGluIGlzIGtlcHQsIGFzIGEgZm9sZGVyIHBpY2sgd291bGQga2VlcCBpdCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBleHBhbmRaaXBzKFxuICBmaWxlczogcmVhZG9ubHkgUmVnaW9uSW1wb3J0RmlsZVtdLFxuICBpbmZsYXRlUmF3PzogSW5mbGF0ZVJhdyxcbik6IFByb21pc2U8UmVnaW9uSW1wb3J0RmlsZVtdPiB7XG4gIGNvbnN0IG91dDogUmVnaW9uSW1wb3J0RmlsZVtdID0gW107XG4gIGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuICAgIGlmICghaXNaaXBOYW1lKGZpbGUubmFtZSkpIHtcbiAgICAgIG91dC5wdXNoKGZpbGUpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgcmVhZFppcChhd2FpdCBmaWxlLmJ5dGVzKCksIGluZmxhdGVSYXcpKSB7XG4gICAgICBvdXQucHVzaCh7XG4gICAgICAgIG5hbWU6IGVudHJ5Lm5hbWUsXG4gICAgICAgIGJ5dGVzOiAoKSA9PiBlbnRyeS5ieXRlcygpLFxuICAgICAgICB0ZXh0OiBhc3luYyAoKSA9PiBuZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoYXdhaXQgZW50cnkuYnl0ZXMoKSksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuaW50ZXJmYWNlIE1lbWJlciB7XG4gIGZsYWdzOiBudW1iZXI7XG4gIG1ldGhvZDogbnVtYmVyO1xuICBjcmM6IG51bWJlcjtcbiAgY29tcHJlc3NlZDogbnVtYmVyO1xuICBzaXplOiBudW1iZXI7XG4gIGxvY2FsOiBudW1iZXI7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJlYWRNZW1iZXIoXG4gIGJ5dGVzOiBVaW50OEFycmF5LFxuICB2aWV3OiBEYXRhVmlldyxcbiAgbmFtZTogc3RyaW5nLFxuICBtOiBNZW1iZXIsXG4gIGluZmxhdGVSYXc6IEluZmxhdGVSYXcsXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgaWYgKG0uZmxhZ3MgJiAweDEpIHRocm93IG5ldyBFcnJvcihgemlwOiAke25hbWV9IGlzIGVuY3J5cHRlZGApO1xuICBpZiAodmlldy5nZXRVaW50MzIobS5sb2NhbCwgdHJ1ZSkgIT09IExPQ0FMKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfTogYmFkIGxvY2FsIGhlYWRlcmApO1xuICBjb25zdCBzdGFydCA9IG0ubG9jYWwgKyAzMCArIHZpZXcuZ2V0VWludDE2KG0ubG9jYWwgKyAyNiwgdHJ1ZSkgKyB2aWV3LmdldFVpbnQxNihtLmxvY2FsICsgMjgsIHRydWUpO1xuICBjb25zdCByYXcgPSBieXRlcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBtLmNvbXByZXNzZWQpO1xuICBpZiAocmF3Lmxlbmd0aCAhPT0gbS5jb21wcmVzc2VkKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBpcyB0cnVuY2F0ZWRgKTtcbiAgbGV0IG91dDogVWludDhBcnJheTtcbiAgaWYgKG0ubWV0aG9kID09PSAwKSBvdXQgPSByYXc7XG4gIGVsc2UgaWYgKG0ubWV0aG9kID09PSA4KSBvdXQgPSBhd2FpdCBpbmZsYXRlUmF3KHJhdyk7XG4gIGVsc2UgdGhyb3cgbmV3IEVycm9yKGB6aXA6ICR7bmFtZX0gdXNlcyBjb21wcmVzc2lvbiBtZXRob2QgJHttLm1ldGhvZH0sIG5vdCBzdG9yZWQgb3IgZGVmbGF0ZWApO1xuICBpZiAob3V0Lmxlbmd0aCAhPT0gbS5zaXplKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBpcyAke291dC5sZW5ndGh9IGJ5dGVzLCBleHBlY3RlZCAke20uc2l6ZX1gKTtcbiAgaWYgKGNyYzMyKG91dCkgIT09IG0uY3JjKSB0aHJvdyBuZXcgRXJyb3IoYHppcDogJHtuYW1lfSBmYWlscyBpdHMgQ1JDIGNoZWNrYCk7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKiBUaGUgZW5kLW9mLWNlbnRyYWwtZGlyZWN0b3J5IHJlY29yZDogdGhlIGxhc3Qgb25lLCB3aXRoaW4gdGhlIDY0IEtpQiBhIGNvbW1lbnQgbWF5IHRha2UuICovXG5mdW5jdGlvbiBmaW5kRW9jZCh2aWV3OiBEYXRhVmlldyk6IG51bWJlciB7XG4gIGNvbnN0IHN0b3AgPSBNYXRoLm1heCgwLCB2aWV3LmJ5dGVMZW5ndGggLSAyMiAtIDB4ZmZmZik7XG4gIGZvciAobGV0IGF0ID0gdmlldy5ieXRlTGVuZ3RoIC0gMjI7IGF0ID49IHN0b3A7IGF0LS0pIHtcbiAgICBpZiAodmlldy5nZXRVaW50MzIoYXQsIHRydWUpID09PSBFT0NEKSByZXR1cm4gYXQ7XG4gIH1cbiAgdGhyb3cgbmV3IEVycm9yKCd6aXA6IG5vdCBhIHppcCBhcmNoaXZlIChubyBjZW50cmFsIGRpcmVjdG9yeSknKTtcbn1cblxuLyoqIEEgbGl0dGxlLWVuZGlhbiB1NjQgdGhhdCBmaXRzIGEgZG91YmxlIChhcmNoaXZlcyB1bmRlciA4IFBCKS4gKi9cbmZ1bmN0aW9uIG51bSh2aWV3OiBEYXRhVmlldywgYXQ6IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiB2aWV3LmdldFVpbnQzMihhdCwgdHJ1ZSkgKyB2aWV3LmdldFVpbnQzMihhdCArIDQsIHRydWUpICogMHgxMDAwMDAwMDA7XG59XG5cbmxldCBjcmNUYWJsZTogVWludDMyQXJyYXkgfCBudWxsID0gbnVsbDtcblxuLyoqIENSQy0zMiAoSUVFRSksIGFzIHppcCByZWNvcmRzIGl0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyYzMyKGRhdGE6IFVpbnQ4QXJyYXkpOiBudW1iZXIge1xuICBpZiAoIWNyY1RhYmxlKSB7XG4gICAgY3JjVGFibGUgPSBuZXcgVWludDMyQXJyYXkoMjU2KTtcbiAgICBmb3IgKGxldCBuID0gMDsgbiA8IDI1NjsgbisrKSB7XG4gICAgICBsZXQgYyA9IG47XG4gICAgICBmb3IgKGxldCBrID0gMDsgayA8IDg7IGsrKykgYyA9IGMgJiAxID8gMHhlZGI4ODMyMCBeIChjID4+PiAxKSA6IGMgPj4+IDE7XG4gICAgICBjcmNUYWJsZVtuXSA9IGMgPj4+IDA7XG4gICAgfVxuICB9XG4gIGxldCBjID0gMHhmZmZmZmZmZjtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBkYXRhLmxlbmd0aDsgaSsrKSBjID0gY3JjVGFibGVbKGMgXiBkYXRhW2ldKSAmIDB4ZmZdIF4gKGMgPj4+IDgpO1xuICByZXR1cm4gKGMgXiAweGZmZmZmZmZmKSA+Pj4gMDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcGxhdGZvcm1JbmZsYXRlUmF3KGJ5dGVzOiBVaW50OEFycmF5KTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIGlmICh0eXBlb2YgRGVjb21wcmVzc2lvblN0cmVhbSA9PT0gJ3VuZGVmaW5lZCcpXG4gICAgdGhyb3cgbmV3IEVycm9yKCd6aXA6IGRlZmxhdGVkIG1lbWJlcnMgbmVlZCBEZWNvbXByZXNzaW9uU3RyZWFtJyk7XG4gIGxldCBpbmZsYXRlcjogRGVjb21wcmVzc2lvblN0cmVhbTtcbiAgdHJ5IHtcbiAgICAvLyBDb21wcmVzc2lvbiBTdHJlYW1zJyByYXcgREVGTEFURSAoQ2hyb21lIDEwMywgRmlyZWZveCAxMTMsIFNhZmFyaSAxNi40IG9uKS5cbiAgICBpbmZsYXRlciA9IG5ldyBEZWNvbXByZXNzaW9uU3RyZWFtKCdkZWZsYXRlLXJhdycpO1xuICB9IGNhdGNoIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ppcDogdGhpcyBicm93c2VyIGNhbm5vdCBpbmZsYXRlIHppcCBtZW1iZXJzIChubyBEZWNvbXByZXNzaW9uU3RyZWFtIFwiZGVmbGF0ZS1yYXdcIiknKTtcbiAgfVxuICBjb25zdCBzdHJlYW0gPSBuZXcgQmxvYihbYnl0ZXMgYXMgQmxvYlBhcnRdKS5zdHJlYW0oKS5waXBlVGhyb3VnaChpbmZsYXRlcik7XG4gIHJldHVybiBuZXcgVWludDhBcnJheShhd2FpdCBuZXcgUmVzcG9uc2Uoc3RyZWFtKS5hcnJheUJ1ZmZlcigpKTtcbn1cbiJdfQ==
|