quickwin 2.2.0 → 2.3.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.
- package/README.en.md +7 -7
- package/README.md +7 -7
- package/constants.ts +1063 -0
- package/enum_map.d.ts +129 -0
- package/examples/PdfCanvas.js +2 -2
- package/examples/PdfCanvas.tsx +3 -2
- package/examples/{execd.js → execd/main.js} +563 -122
- package/examples/execd/tray.js +192 -0
- package/examples/{execd_worker.js → execd/worker.js} +7 -7
- package/examples/pdf_preview2.js +46 -46
- package/examples/pdf_preview2.ts +55 -54
- package/examples/pdf_viewer.js +34 -19
- package/examples/pdf_viewer.tsx +6 -5
- package/examples/test_gallery.js +35 -20
- package/examples/test_gallery.tsx +9 -8
- package/examples/test_react_lazy.js +34 -19
- package/examples/test_react_lazy.tsx +7 -6
- package/examples/test_react_listbox.js +34 -19
- package/examples/test_react_listbox.tsx +8 -7
- package/examples/test_root_window.js +34 -19
- package/examples/test_root_window.tsx +5 -5
- package/examples/test_tab.js +34 -19
- package/examples/test_tab.tsx +7 -6
- package/examples/tray_demo.js +8 -8
- package/examples/tray_demo.tsx +9 -8
- package/lib/dumpRects.js +2 -2
- package/lib/dumpRects.ts +3 -2
- package/lib/fetch.js +15 -15
- package/lib/fetch.ts +16 -15
- package/lib/ffi/bind.js +3 -3
- package/lib/ffi/bind.ts +3 -3
- package/lib/http-server.js +4 -4
- package/lib/http-server.ts +5 -4
- package/lib/react-qw/components/Button.js +2 -2
- package/lib/react-qw/components/CheckBox.js +4 -4
- package/lib/react-qw/components/ComboBox.js +10 -10
- package/lib/react-qw/components/DateTimePicker.js +12 -12
- package/lib/react-qw/components/Input.js +7 -7
- package/lib/react-qw/components/Link.js +4 -4
- package/lib/react-qw/components/ListBox.js +12 -12
- package/lib/react-qw/components/ListView.js +35 -35
- package/lib/react-qw/components/PathPicker.js +3 -3
- package/lib/react-qw/components/ProgressBar.js +4 -4
- package/lib/react-qw/components/RadioButton.js +4 -4
- package/lib/react-qw/components/ScrollView.js +28 -28
- package/lib/react-qw/components/Slider.js +11 -11
- package/lib/react-qw/components/Tab.js +10 -10
- package/lib/react-qw/components/Tooltip.js +8 -8
- package/lib/react-qw/components/TreeView.js +20 -20
- package/lib/react-qw/index.js +5 -5
- package/lib/react-qw/index.ts +6 -5
- package/lib/react-qw/props.js +4 -4
- package/lib/react-qw/props.ts +5 -4
- package/lib/react-qw/reconciler.js +10 -10
- package/lib/react-qw/reconciler.ts +11 -10
- package/lib/text-measure.js +3 -3
- package/lib/text-measure.ts +4 -3
- package/lib/websocket.js +17 -17
- package/lib/websocket.ts +18 -17
- package/lib/windows/advapi32.js +7 -7
- package/lib/windows/advapi32.ts +7 -7
- package/lib/windows/gdi32.js +16 -16
- package/lib/windows/gdi32.ts +16 -16
- package/lib/windows/kernel32.js +41 -2
- package/lib/windows/kernel32.ts +45 -2
- package/lib/windows/shell32.js +24 -3
- package/lib/windows/shell32.ts +27 -4
- package/lib/windows/structs.js +54 -0
- package/lib/windows/structs.ts +63 -1
- package/lib/windows/user32.js +18 -6
- package/lib/windows/user32.ts +18 -6
- package/lib/windows/winspool.js +3 -3
- package/lib/windows/winspool.ts +3 -3
- package/package.json +4 -3
- package/quickwin.d.ts +32 -10
- package/qwin-nowasm-x86.exe +0 -0
- package/qwin-nowasm.exe +0 -0
- package/qwin-x86.exe +0 -0
- package/qwin.exe +0 -0
- package/test/test_ffi_bind.js +7 -7
- package/test/test_ffi_bind.ts +8 -8
- package/test/test_ffi_struct.js +2 -2
- package/test/test_ffi_struct.ts +3 -3
- package/test/test_ffi_windows.js +1 -1
- package/test/test_ffi_windows.ts +1 -1
- package/test/test_files.js +7 -7
- package/test/test_files.ts +8 -8
- package/test/test_gdi_draw.js +51 -51
- package/test/test_gdi_draw.ts +57 -57
- package/test/test_http_server.js +3 -3
- package/test/test_http_server.ts +4 -3
- package/test/test_ipv6.js +3 -3
- package/test/test_ipv6.ts +4 -3
- package/test/test_net_event.js +3 -3
- package/test/test_net_event.ts +4 -3
- package/test/test_printer.js +4 -4
- package/test/test_printer.ts +5 -5
- package/test/test_react_complex.js +36 -21
- package/test/test_react_counter.js +34 -19
- package/test/test_react_flex.js +36 -21
- package/test/test_react_hidden.js +34 -19
- package/test/test_react_listview_link.js +35 -20
- package/test/test_react_notify.js +52 -37
- package/test/test_react_render.js +34 -19
- package/test/test_registry.js +6 -6
- package/test/test_registry.ts +8 -8
- package/test/test_wolfssl_read.js +8 -8
- package/test/test_wolfssl_read.ts +9 -8
- package/examples/execd.tsx +0 -798
- package/examples/execd_worker.ts +0 -127
- package/quickwin_const.d.ts +0 -1063
|
@@ -1367,9 +1367,9 @@ var require_scheduler_development = __commonJS({
|
|
|
1367
1367
|
}
|
|
1368
1368
|
return first;
|
|
1369
1369
|
}
|
|
1370
|
-
function compare(a2,
|
|
1371
|
-
var diff = a2.sortIndex -
|
|
1372
|
-
return 0 !== diff ? diff : a2.id -
|
|
1370
|
+
function compare(a2, b8) {
|
|
1371
|
+
var diff = a2.sortIndex - b8.sortIndex;
|
|
1372
|
+
return 0 !== diff ? diff : a2.id - b8.id;
|
|
1373
1373
|
}
|
|
1374
1374
|
function advanceTimers(currentTime) {
|
|
1375
1375
|
for (var timer = peek(timerQueue); null !== timer; ) {
|
|
@@ -1667,14 +1667,14 @@ var require_react_reconciler_development = __commonJS({
|
|
|
1667
1667
|
throw Error("Unable to find node on an unmounted component.");
|
|
1668
1668
|
return alternate !== fiber ? null : fiber;
|
|
1669
1669
|
}
|
|
1670
|
-
for (var a2 = fiber,
|
|
1670
|
+
for (var a2 = fiber, b8 = alternate; ; ) {
|
|
1671
1671
|
var parentA = a2.return;
|
|
1672
1672
|
if (null === parentA) break;
|
|
1673
1673
|
var parentB = parentA.alternate;
|
|
1674
1674
|
if (null === parentB) {
|
|
1675
|
-
|
|
1676
|
-
if (null !==
|
|
1677
|
-
a2 =
|
|
1675
|
+
b8 = parentA.return;
|
|
1676
|
+
if (null !== b8) {
|
|
1677
|
+
a2 = b8;
|
|
1678
1678
|
continue;
|
|
1679
1679
|
}
|
|
1680
1680
|
break;
|
|
@@ -1682,23 +1682,23 @@ var require_react_reconciler_development = __commonJS({
|
|
|
1682
1682
|
if (parentA.child === parentB.child) {
|
|
1683
1683
|
for (parentB = parentA.child; parentB; ) {
|
|
1684
1684
|
if (parentB === a2) return assertIsMounted(parentA), fiber;
|
|
1685
|
-
if (parentB ===
|
|
1685
|
+
if (parentB === b8) return assertIsMounted(parentA), alternate;
|
|
1686
1686
|
parentB = parentB.sibling;
|
|
1687
1687
|
}
|
|
1688
1688
|
throw Error("Unable to find node on an unmounted component.");
|
|
1689
1689
|
}
|
|
1690
|
-
if (a2.return !==
|
|
1690
|
+
if (a2.return !== b8.return) a2 = parentA, b8 = parentB;
|
|
1691
1691
|
else {
|
|
1692
1692
|
for (var didFindChild = false, _child = parentA.child; _child; ) {
|
|
1693
1693
|
if (_child === a2) {
|
|
1694
1694
|
didFindChild = true;
|
|
1695
1695
|
a2 = parentA;
|
|
1696
|
-
|
|
1696
|
+
b8 = parentB;
|
|
1697
1697
|
break;
|
|
1698
1698
|
}
|
|
1699
|
-
if (_child ===
|
|
1699
|
+
if (_child === b8) {
|
|
1700
1700
|
didFindChild = true;
|
|
1701
|
-
|
|
1701
|
+
b8 = parentA;
|
|
1702
1702
|
a2 = parentB;
|
|
1703
1703
|
break;
|
|
1704
1704
|
}
|
|
@@ -1709,12 +1709,12 @@ var require_react_reconciler_development = __commonJS({
|
|
|
1709
1709
|
if (_child === a2) {
|
|
1710
1710
|
didFindChild = true;
|
|
1711
1711
|
a2 = parentB;
|
|
1712
|
-
|
|
1712
|
+
b8 = parentA;
|
|
1713
1713
|
break;
|
|
1714
1714
|
}
|
|
1715
|
-
if (_child ===
|
|
1715
|
+
if (_child === b8) {
|
|
1716
1716
|
didFindChild = true;
|
|
1717
|
-
|
|
1717
|
+
b8 = parentB;
|
|
1718
1718
|
a2 = parentA;
|
|
1719
1719
|
break;
|
|
1720
1720
|
}
|
|
@@ -1726,7 +1726,7 @@ var require_react_reconciler_development = __commonJS({
|
|
|
1726
1726
|
);
|
|
1727
1727
|
}
|
|
1728
1728
|
}
|
|
1729
|
-
if (a2.alternate !==
|
|
1729
|
+
if (a2.alternate !== b8)
|
|
1730
1730
|
throw Error(
|
|
1731
1731
|
"Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue."
|
|
1732
1732
|
);
|
|
@@ -15071,10 +15071,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
15071
15071
|
setCurrentUpdatePriority(previousPriority), ReactSharedInternals.T = prevTransition;
|
|
15072
15072
|
}
|
|
15073
15073
|
};
|
|
15074
|
-
exports2.discreteUpdates = function(fn, a2,
|
|
15074
|
+
exports2.discreteUpdates = function(fn, a2, b8, c2, d2) {
|
|
15075
15075
|
var prevTransition = ReactSharedInternals.T, previousPriority = getCurrentUpdatePriority();
|
|
15076
15076
|
try {
|
|
15077
|
-
return setCurrentUpdatePriority(2), ReactSharedInternals.T = null, fn(a2,
|
|
15077
|
+
return setCurrentUpdatePriority(2), ReactSharedInternals.T = null, fn(a2, b8, c2, d2);
|
|
15078
15078
|
} finally {
|
|
15079
15079
|
setCurrentUpdatePriority(previousPriority), ReactSharedInternals.T = prevTransition, executionContext === NoContext && (workInProgressRootRenderTargetTime = now$1() + RENDER_TIMEOUT_MS);
|
|
15080
15080
|
}
|
|
@@ -15353,7 +15353,7 @@ var require_constants = __commonJS({
|
|
|
15353
15353
|
}
|
|
15354
15354
|
});
|
|
15355
15355
|
|
|
15356
|
-
// _build/examples/execd.js
|
|
15356
|
+
// _build/examples/execd/main.js
|
|
15357
15357
|
var import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
|
|
15358
15358
|
|
|
15359
15359
|
// _build/lib/polyfill.js
|
|
@@ -15514,7 +15514,7 @@ var URLSearchParamsImpl = class {
|
|
|
15514
15514
|
this._list.push([key, value]);
|
|
15515
15515
|
}
|
|
15516
15516
|
sort() {
|
|
15517
|
-
this._list.sort(([a2], [
|
|
15517
|
+
this._list.sort(([a2], [b8]) => a2 < b8 ? -1 : a2 > b8 ? 1 : 0);
|
|
15518
15518
|
}
|
|
15519
15519
|
forEach(fn) {
|
|
15520
15520
|
for (const [k2, v2] of this._list)
|
|
@@ -15564,43 +15564,43 @@ var URLImpl = class _URLImpl {
|
|
|
15564
15564
|
}
|
|
15565
15565
|
if (base === void 0)
|
|
15566
15566
|
throw new TypeError("Invalid URL");
|
|
15567
|
-
const
|
|
15567
|
+
const b8 = new _URLImpl(base);
|
|
15568
15568
|
if (p2.host) {
|
|
15569
|
-
p2.scheme =
|
|
15569
|
+
p2.scheme = b8._scheme;
|
|
15570
15570
|
this._apply(p2);
|
|
15571
15571
|
return;
|
|
15572
15572
|
}
|
|
15573
15573
|
if (!p2.path && !p2.query) {
|
|
15574
15574
|
this._apply({
|
|
15575
|
-
scheme:
|
|
15576
|
-
user:
|
|
15577
|
-
pass:
|
|
15578
|
-
host:
|
|
15579
|
-
port:
|
|
15580
|
-
path:
|
|
15581
|
-
query:
|
|
15575
|
+
scheme: b8._scheme,
|
|
15576
|
+
user: b8._username,
|
|
15577
|
+
pass: b8._password,
|
|
15578
|
+
host: b8._hostname,
|
|
15579
|
+
port: b8._port,
|
|
15580
|
+
path: b8._pathname,
|
|
15581
|
+
query: b8._query,
|
|
15582
15582
|
fragment: p2.fragment || ""
|
|
15583
15583
|
});
|
|
15584
15584
|
return;
|
|
15585
15585
|
}
|
|
15586
|
-
p2.scheme =
|
|
15586
|
+
p2.scheme = b8._scheme;
|
|
15587
15587
|
if (!p2.user)
|
|
15588
|
-
p2.user =
|
|
15588
|
+
p2.user = b8._username;
|
|
15589
15589
|
if (!p2.pass)
|
|
15590
|
-
p2.pass =
|
|
15590
|
+
p2.pass = b8._password;
|
|
15591
15591
|
if (!p2.host)
|
|
15592
|
-
p2.host =
|
|
15592
|
+
p2.host = b8._hostname;
|
|
15593
15593
|
if (!p2.port)
|
|
15594
|
-
p2.port =
|
|
15594
|
+
p2.port = b8._port;
|
|
15595
15595
|
if (!p2.fragment)
|
|
15596
15596
|
p2.fragment = "";
|
|
15597
15597
|
if (p2.path && !p2.path.startsWith("/")) {
|
|
15598
|
-
const bd =
|
|
15598
|
+
const bd = b8._pathname.substring(0, b8._pathname.lastIndexOf("/") + 1);
|
|
15599
15599
|
p2.path = _normalizePath(bd + p2.path);
|
|
15600
15600
|
} else if (!p2.path) {
|
|
15601
|
-
p2.path =
|
|
15601
|
+
p2.path = b8._pathname;
|
|
15602
15602
|
if (!p2.query)
|
|
15603
|
-
p2.query =
|
|
15603
|
+
p2.query = b8._query;
|
|
15604
15604
|
}
|
|
15605
15605
|
this._apply(p2);
|
|
15606
15606
|
}
|
|
@@ -15705,19 +15705,19 @@ function _normalizeLabel(label) {
|
|
|
15705
15705
|
function _decodeUTF8(buf, fatal) {
|
|
15706
15706
|
let out = "";
|
|
15707
15707
|
for (let i2 = 0; i2 < buf.length; ) {
|
|
15708
|
-
const
|
|
15709
|
-
if (
|
|
15710
|
-
out += String.fromCharCode(
|
|
15708
|
+
const b8 = buf[i2++];
|
|
15709
|
+
if (b8 < 128) {
|
|
15710
|
+
out += String.fromCharCode(b8);
|
|
15711
15711
|
continue;
|
|
15712
15712
|
}
|
|
15713
|
-
if (
|
|
15713
|
+
if (b8 < 192) {
|
|
15714
15714
|
out += fatal ? (() => {
|
|
15715
15715
|
throw new TypeError("unexpected continuation byte");
|
|
15716
15716
|
})() : "\uFFFD";
|
|
15717
15717
|
continue;
|
|
15718
15718
|
}
|
|
15719
15719
|
let c2, min;
|
|
15720
|
-
if (
|
|
15720
|
+
if (b8 < 224) {
|
|
15721
15721
|
if (i2 >= buf.length) {
|
|
15722
15722
|
out += fatal ? (() => {
|
|
15723
15723
|
throw new TypeError("incomplete utf-8");
|
|
@@ -15729,9 +15729,9 @@ function _decodeUTF8(buf, fatal) {
|
|
|
15729
15729
|
out += "\uFFFD";
|
|
15730
15730
|
continue;
|
|
15731
15731
|
}
|
|
15732
|
-
c2 = (
|
|
15732
|
+
c2 = (b8 & 31) << 6 | b22 & 63;
|
|
15733
15733
|
min = 128;
|
|
15734
|
-
} else if (
|
|
15734
|
+
} else if (b8 < 240) {
|
|
15735
15735
|
if (i2 + 1 >= buf.length) {
|
|
15736
15736
|
out += fatal ? (() => {
|
|
15737
15737
|
throw new TypeError("incomplete utf-8");
|
|
@@ -15744,9 +15744,9 @@ function _decodeUTF8(buf, fatal) {
|
|
|
15744
15744
|
out += "\uFFFD";
|
|
15745
15745
|
continue;
|
|
15746
15746
|
}
|
|
15747
|
-
c2 = (
|
|
15747
|
+
c2 = (b8 & 15) << 12 | (b22 & 63) << 6 | b32 & 63;
|
|
15748
15748
|
min = 2048;
|
|
15749
|
-
} else if (
|
|
15749
|
+
} else if (b8 < 248) {
|
|
15750
15750
|
if (i2 + 2 >= buf.length) {
|
|
15751
15751
|
out += fatal ? (() => {
|
|
15752
15752
|
throw new TypeError("incomplete utf-8");
|
|
@@ -15760,7 +15760,7 @@ function _decodeUTF8(buf, fatal) {
|
|
|
15760
15760
|
out += "\uFFFD";
|
|
15761
15761
|
continue;
|
|
15762
15762
|
}
|
|
15763
|
-
c2 = (
|
|
15763
|
+
c2 = (b8 & 7) << 18 | (b22 & 63) << 12 | (b32 & 63) << 6 | b42 & 63;
|
|
15764
15764
|
min = 65536;
|
|
15765
15765
|
} else {
|
|
15766
15766
|
out += fatal ? (() => {
|
|
@@ -15940,31 +15940,31 @@ function sha1Bytes(bytes) {
|
|
|
15940
15940
|
for (let t2 = 16; t2 < 80; t2++) {
|
|
15941
15941
|
w2[t2] = rotl(w2[t2 - 3] ^ w2[t2 - 8] ^ w2[t2 - 14] ^ w2[t2 - 16], 1);
|
|
15942
15942
|
}
|
|
15943
|
-
let a2 = h0,
|
|
15943
|
+
let a2 = h0, b8 = h1, c2 = h2, d2 = h3, e2 = h4;
|
|
15944
15944
|
for (let t2 = 0; t2 < 80; t2++) {
|
|
15945
15945
|
let f2, k2;
|
|
15946
15946
|
if (t2 < 20) {
|
|
15947
|
-
f2 =
|
|
15947
|
+
f2 = b8 & c2 | ~b8 & d2;
|
|
15948
15948
|
k2 = 1518500249;
|
|
15949
15949
|
} else if (t2 < 40) {
|
|
15950
|
-
f2 =
|
|
15950
|
+
f2 = b8 ^ c2 ^ d2;
|
|
15951
15951
|
k2 = 1859775393;
|
|
15952
15952
|
} else if (t2 < 60) {
|
|
15953
|
-
f2 =
|
|
15953
|
+
f2 = b8 & c2 | b8 & d2 | c2 & d2;
|
|
15954
15954
|
k2 = 2400959708;
|
|
15955
15955
|
} else {
|
|
15956
|
-
f2 =
|
|
15956
|
+
f2 = b8 ^ c2 ^ d2;
|
|
15957
15957
|
k2 = 3395469782;
|
|
15958
15958
|
}
|
|
15959
15959
|
const temp = rotl(a2, 5) + f2 + e2 + k2 + w2[t2] >>> 0;
|
|
15960
15960
|
e2 = d2;
|
|
15961
15961
|
d2 = c2;
|
|
15962
|
-
c2 = rotl(
|
|
15963
|
-
|
|
15962
|
+
c2 = rotl(b8, 30);
|
|
15963
|
+
b8 = a2;
|
|
15964
15964
|
a2 = temp;
|
|
15965
15965
|
}
|
|
15966
15966
|
h0 = h0 + a2 >>> 0;
|
|
15967
|
-
h1 = h1 +
|
|
15967
|
+
h1 = h1 + b8 >>> 0;
|
|
15968
15968
|
h2 = h2 + c2 >>> 0;
|
|
15969
15969
|
h3 = h3 + d2 >>> 0;
|
|
15970
15970
|
h4 = h4 + e2 >>> 0;
|
|
@@ -17513,7 +17513,7 @@ function Er(e2) {
|
|
|
17513
17513
|
function Wr(e2, t2) {
|
|
17514
17514
|
return Oe(e2._readableStreamController) ? (function(e3) {
|
|
17515
17515
|
let t3, r2, o2, n2, i2, a2 = V(e3), s2 = false, l2 = false, d2 = false, f2 = false, h2 = false;
|
|
17516
|
-
const
|
|
17516
|
+
const b8 = u((e4) => {
|
|
17517
17517
|
i2 = e4;
|
|
17518
17518
|
});
|
|
17519
17519
|
function m2(e4) {
|
|
@@ -17583,14 +17583,14 @@ function Wr(e2, t2) {
|
|
|
17583
17583
|
const o4 = le([t3, r2]), n3 = Mr(e3, o4);
|
|
17584
17584
|
i2(n3);
|
|
17585
17585
|
}
|
|
17586
|
-
return
|
|
17586
|
+
return b8;
|
|
17587
17587
|
}
|
|
17588
17588
|
function R2(o3) {
|
|
17589
17589
|
if (h2 = true, r2 = o3, f2) {
|
|
17590
17590
|
const o4 = le([t3, r2]), n3 = Mr(e3, o4);
|
|
17591
17591
|
i2(n3);
|
|
17592
17592
|
}
|
|
17593
|
-
return
|
|
17593
|
+
return b8;
|
|
17594
17594
|
}
|
|
17595
17595
|
function T2() {
|
|
17596
17596
|
}
|
|
@@ -17601,14 +17601,14 @@ function Wr(e2, t2) {
|
|
|
17601
17601
|
const h2 = u((e4) => {
|
|
17602
17602
|
a2 = e4;
|
|
17603
17603
|
});
|
|
17604
|
-
function
|
|
17604
|
+
function b8() {
|
|
17605
17605
|
if (s2) return l2 = true, c(void 0);
|
|
17606
17606
|
s2 = true;
|
|
17607
17607
|
return te(t3, { _chunkSteps: (e4) => {
|
|
17608
17608
|
y(() => {
|
|
17609
17609
|
l2 = false;
|
|
17610
17610
|
const t4 = e4, r3 = e4;
|
|
17611
|
-
d2 || Rr(n2._readableStreamController, t4), f2 || Rr(i2._readableStreamController, r3), s2 = false, l2 &&
|
|
17611
|
+
d2 || Rr(n2._readableStreamController, t4), f2 || Rr(i2._readableStreamController, r3), s2 = false, l2 && b8();
|
|
17612
17612
|
});
|
|
17613
17613
|
}, _closeSteps: () => {
|
|
17614
17614
|
s2 = false, d2 || wr(n2._readableStreamController), f2 || wr(i2._readableStreamController), d2 && f2 || a2(void 0);
|
|
@@ -17632,7 +17632,7 @@ function Wr(e2, t2) {
|
|
|
17632
17632
|
}
|
|
17633
17633
|
function S2() {
|
|
17634
17634
|
}
|
|
17635
|
-
return n2 = Dr(S2,
|
|
17635
|
+
return n2 = Dr(S2, b8, m2), i2 = Dr(S2, b8, p2), _(t3._closedPromise, (e4) => (Tr(n2._readableStreamController, e4), Tr(i2._readableStreamController, e4), d2 && f2 || a2(void 0), null)), [n2, i2];
|
|
17636
17636
|
})(e2);
|
|
17637
17637
|
}
|
|
17638
17638
|
function Or(r2) {
|
|
@@ -17941,7 +17941,7 @@ var TransformStream = class {
|
|
|
17941
17941
|
if (void 0 !== i2.readableType) throw new RangeError("Invalid readableType specified");
|
|
17942
17942
|
if (void 0 !== i2.writableType) throw new RangeError("Invalid writableType specified");
|
|
17943
17943
|
const a2 = mt(n2, 0), s2 = pt(n2), l2 = mt(o2, 1), f2 = pt(o2);
|
|
17944
|
-
let
|
|
17944
|
+
let b8;
|
|
17945
17945
|
!(function(e3, t3, r3, o3, n3, i3) {
|
|
17946
17946
|
function a3() {
|
|
17947
17947
|
return t3;
|
|
@@ -18005,7 +18005,7 @@ var TransformStream = class {
|
|
|
18005
18005
|
return Ct(a4), Nt(a4, Object.create(WritableStreamDefaultController.prototype), e4, t4, r4, o4, n4, i4), a4;
|
|
18006
18006
|
})(a3, s3, c2, l3, r3, o3), e3._readable = Dr(a3, d2, f3, n3, i3), e3._backpressure = void 0, e3._backpressureChangePromise = void 0, e3._backpressureChangePromise_resolve = void 0, ao(e3, true), e3._transformStreamController = void 0;
|
|
18007
18007
|
})(this, u((e3) => {
|
|
18008
|
-
|
|
18008
|
+
b8 = e3;
|
|
18009
18009
|
}), l2, f2, a2, s2), (function(e3, t3) {
|
|
18010
18010
|
const r3 = Object.create(TransformStreamDefaultController.prototype);
|
|
18011
18011
|
let o3, n3, i3;
|
|
@@ -18021,7 +18021,7 @@ var TransformStream = class {
|
|
|
18021
18021
|
!(function(e4, t4, r4, o4, n4) {
|
|
18022
18022
|
t4._controlledTransformStream = e4, e4._transformStreamController = t4, t4._transformAlgorithm = r4, t4._flushAlgorithm = o4, t4._cancelAlgorithm = n4, t4._finishPromise = void 0, t4._finishPromise_resolve = void 0, t4._finishPromise_reject = void 0;
|
|
18023
18023
|
})(e3, r3, o3, n3, i3);
|
|
18024
|
-
})(this, i2), void 0 !== i2.start ?
|
|
18024
|
+
})(this, i2), void 0 !== i2.start ? b8(i2.start(this._transformStreamController)) : b8(void 0);
|
|
18025
18025
|
}
|
|
18026
18026
|
get readable() {
|
|
18027
18027
|
if (!ro(this)) throw _o("readable");
|
|
@@ -19044,10 +19044,10 @@ async function sendResponse(c2, method, res) {
|
|
|
19044
19044
|
await writeStreamingBody(c2, res.body, chunked, chunked && trailerDeclared ? res.trailers : void 0);
|
|
19045
19045
|
}
|
|
19046
19046
|
|
|
19047
|
-
// _build/examples/execd.js
|
|
19048
|
-
import * as
|
|
19047
|
+
// _build/examples/execd/main.js
|
|
19048
|
+
import * as os7 from "os";
|
|
19049
19049
|
import * as std2 from "std";
|
|
19050
|
-
import * as
|
|
19050
|
+
import * as gui19 from "gui";
|
|
19051
19051
|
|
|
19052
19052
|
// _build/lib/exec-log.js
|
|
19053
19053
|
var RequestLog = class {
|
|
@@ -19566,13 +19566,13 @@ function lower(v2) {
|
|
|
19566
19566
|
type: { tag: "array", elementType: el.type, elementSize: el.size }
|
|
19567
19567
|
};
|
|
19568
19568
|
}
|
|
19569
|
-
const
|
|
19570
|
-
if (
|
|
19571
|
-
const rawUnit =
|
|
19569
|
+
const b8 = /^([A-Za-z_]\w*):(\d+)$/.exec(v2);
|
|
19570
|
+
if (b8) {
|
|
19571
|
+
const rawUnit = b8[1];
|
|
19572
19572
|
const unit = normToken(rawUnit);
|
|
19573
19573
|
if (!isCNumberToken(unit) || unit === "f32" || unit === "f64")
|
|
19574
19574
|
throw new Error(`ffi-struct: bitfield unit must be an integer type, got "${rawUnit}"`);
|
|
19575
|
-
const width = Number(
|
|
19575
|
+
const width = Number(b8[2]);
|
|
19576
19576
|
const s3 = SizeAlign[unit];
|
|
19577
19577
|
const cap = s3 * 8;
|
|
19578
19578
|
if (!Number.isInteger(width) || width < 1)
|
|
@@ -19888,10 +19888,53 @@ function buildDecl(kind, member, pack) {
|
|
|
19888
19888
|
decl[k2] = v2;
|
|
19889
19889
|
return decl;
|
|
19890
19890
|
}
|
|
19891
|
-
function
|
|
19891
|
+
function structArray(def) {
|
|
19892
|
+
const { fields, size } = def;
|
|
19893
|
+
const readN = (dv, n2) => {
|
|
19894
|
+
const out = [];
|
|
19895
|
+
for (let i2 = 0; i2 < n2; i2++)
|
|
19896
|
+
out.push(doDecode(dv, i2 * size, fields));
|
|
19897
|
+
return out;
|
|
19898
|
+
};
|
|
19899
|
+
return {
|
|
19900
|
+
encode: (els) => {
|
|
19901
|
+
if (!Array.isArray(els) || els.length === 0)
|
|
19902
|
+
throw new Error(`ffi-struct: structArray(def).encode(els) requires a non-empty element array (pass NULL for an empty pointer position)`);
|
|
19903
|
+
const out = def.alloc(els.length);
|
|
19904
|
+
for (let i2 = 0; i2 < els.length; i2++)
|
|
19905
|
+
def.encode(els[i2], out, i2 * def.size);
|
|
19906
|
+
return out;
|
|
19907
|
+
},
|
|
19908
|
+
decode: ((p2, count) => {
|
|
19909
|
+
if (count !== void 0 && (!Number.isInteger(count) || count < 0))
|
|
19910
|
+
throw new Error(`ffi-struct: structArray.decode(p, count) requires a non-negative integer count, got ${count}`);
|
|
19911
|
+
if (typeof p2 === "number") {
|
|
19912
|
+
if (count === void 0)
|
|
19913
|
+
throw new Error(`ffi-struct: structArray.decode(address, count) requires an explicit count (a bare address carries no length)`);
|
|
19914
|
+
if (count === 0)
|
|
19915
|
+
return [];
|
|
19916
|
+
return readN(new DataView(ffi2.readBytes(p2, count * size)), count);
|
|
19917
|
+
}
|
|
19918
|
+
let n2;
|
|
19919
|
+
if (count !== void 0) {
|
|
19920
|
+
n2 = count;
|
|
19921
|
+
if (n2 * size > p2.byteLength)
|
|
19922
|
+
throw new Error(`ffi-struct: structArray.decode: count ${n2} \xD7 size ${size} = ${n2 * size} exceeds buffer byteLength ${p2.byteLength}`);
|
|
19923
|
+
} else {
|
|
19924
|
+
if (p2.byteLength % size !== 0)
|
|
19925
|
+
throw new Error(`ffi-struct: structArray.decode: byteLength ${p2.byteLength} is not a multiple of size ${size} (mixed buffer? pass count explicitly)`);
|
|
19926
|
+
n2 = p2.byteLength / size;
|
|
19927
|
+
}
|
|
19928
|
+
if (n2 === 0)
|
|
19929
|
+
return [];
|
|
19930
|
+
return readN(new DataView(p2), n2);
|
|
19931
|
+
})
|
|
19932
|
+
};
|
|
19933
|
+
}
|
|
19934
|
+
function struct(a2, b8, c2) {
|
|
19892
19935
|
const isNamed = typeof a2 === "string";
|
|
19893
|
-
const raw = isNamed ?
|
|
19894
|
-
const opts = isNamed ? c2 :
|
|
19936
|
+
const raw = isNamed ? b8 : a2;
|
|
19937
|
+
const opts = isNamed ? c2 : b8;
|
|
19895
19938
|
return createStruct(buildDecl("struct", raw, opts?.pack));
|
|
19896
19939
|
}
|
|
19897
19940
|
|
|
@@ -20185,6 +20228,41 @@ var DEVMODEW_DECL = {
|
|
|
20185
20228
|
dmPanningHeight: "u32"
|
|
20186
20229
|
};
|
|
20187
20230
|
var DEVMODEW = /* @__PURE__ */ struct("DEVMODEW", DEVMODEW_DECL);
|
|
20231
|
+
var MOUSEINPUT_DECL = {
|
|
20232
|
+
"#": "struct",
|
|
20233
|
+
dx: "i32",
|
|
20234
|
+
dy: "i32",
|
|
20235
|
+
mouseData: "u32",
|
|
20236
|
+
dwFlags: "u32",
|
|
20237
|
+
time: "u32",
|
|
20238
|
+
dwExtraInfo: "<>ptr"
|
|
20239
|
+
};
|
|
20240
|
+
var KEYBDINPUT_DECL = {
|
|
20241
|
+
"#": "struct",
|
|
20242
|
+
wVk: "u16",
|
|
20243
|
+
wScan: "u16",
|
|
20244
|
+
dwFlags: "u32",
|
|
20245
|
+
time: "u32",
|
|
20246
|
+
dwExtraInfo: "<>ptr"
|
|
20247
|
+
};
|
|
20248
|
+
var INPUT_DECL = {
|
|
20249
|
+
"#": "struct",
|
|
20250
|
+
type: "u32",
|
|
20251
|
+
data: {
|
|
20252
|
+
"#": "union",
|
|
20253
|
+
mi: MOUSEINPUT_DECL,
|
|
20254
|
+
ki: KEYBDINPUT_DECL
|
|
20255
|
+
}
|
|
20256
|
+
};
|
|
20257
|
+
var INPUT = /* @__PURE__ */ struct("INPUT", INPUT_DECL);
|
|
20258
|
+
var NOTIFYICONIDENTIFIER_DECL = {
|
|
20259
|
+
"#": "struct",
|
|
20260
|
+
cbSize: "u32",
|
|
20261
|
+
hWnd: "<HWND>ptr",
|
|
20262
|
+
uID: "u32",
|
|
20263
|
+
guidItem: "u32[4]"
|
|
20264
|
+
};
|
|
20265
|
+
var NOTIFYICONIDENTIFIER = /* @__PURE__ */ struct("NOTIFYICONIDENTIFIER", NOTIFYICONIDENTIFIER_DECL);
|
|
20188
20266
|
|
|
20189
20267
|
// _build/lib/windows/user32.js
|
|
20190
20268
|
var b2 = (name, sig, encoders) => bind2("user32.dll", name, sig, encoders);
|
|
@@ -20193,13 +20271,17 @@ var LONG_PTR_SYM = os4.arch === "x64" ? "PtrW" : "W";
|
|
|
20193
20271
|
var SetWindowPos = /* @__PURE__ */ b2("SetWindowPos", "<HWND>ptr <>ptr@SetWindowPosHwnd i32 i32 i32 i32 u32 -> i32");
|
|
20194
20272
|
var GetWindowRect = /* @__PURE__ */ b2("GetWindowRect", "<HWND>ptr <RECT>ptr -> i32");
|
|
20195
20273
|
var GetClientRect = /* @__PURE__ */ b2("GetClientRect", "<HWND>ptr <RECT>ptr -> i32");
|
|
20274
|
+
var IsWindow = /* @__PURE__ */ b2("IsWindow", "<HWND>ptr -> i32");
|
|
20196
20275
|
var IsWindowVisible = /* @__PURE__ */ b2("IsWindowVisible", "<HWND>ptr -> i32");
|
|
20197
20276
|
var IsIconic = /* @__PURE__ */ b2("IsIconic", "<HWND>ptr -> i32");
|
|
20277
|
+
var FindWindow = /* @__PURE__ */ b2("FindWindowW", "<WCHAR>ptr <WCHAR>ptr -> <HWND>ptr");
|
|
20278
|
+
var FindWindowEx = /* @__PURE__ */ b2("FindWindowExW", "<HWND>ptr <HWND>ptr <WCHAR>ptr <WCHAR>ptr -> <HWND>ptr");
|
|
20198
20279
|
var GetWindowText = /* @__PURE__ */ b2("GetWindowTextW", "<HWND>ptr <BYTE>ptr i32 -> i32");
|
|
20199
20280
|
var SetWindowText = /* @__PURE__ */ b2("SetWindowTextW", "<HWND>ptr <WCHAR>ptr -> i32");
|
|
20200
20281
|
var GetClassName = /* @__PURE__ */ b2("GetClassNameW", "<HWND>ptr <BYTE>ptr i32 -> i32");
|
|
20201
20282
|
var GetWindowLongPtr = /* @__PURE__ */ b2("GetWindowLong" + LONG_PTR_SYM, "<HWND>ptr i32@Gwlp -> <>ptr");
|
|
20202
20283
|
var SetWindowLongPtr = /* @__PURE__ */ b2("SetWindowLong" + LONG_PTR_SYM, "<HWND>ptr i32@Gwlp <>ptr -> <>ptr");
|
|
20284
|
+
var GetWindowThreadProcessId = /* @__PURE__ */ b2("GetWindowThreadProcessId", "<HWND>ptr <BYTE>ptr -> u32");
|
|
20203
20285
|
var EnableWindow = /* @__PURE__ */ b2("EnableWindow", "<HWND>ptr i32 -> i32");
|
|
20204
20286
|
var SetParent = /* @__PURE__ */ b2("SetParent", "<HWND>ptr <HWND>ptr -> <HWND>ptr");
|
|
20205
20287
|
var DefWindowProc = /* @__PURE__ */ b2("DefWindowProcW", "<HWND>ptr u32@AnyMsg <>ptr <>ptr -> <>ptr");
|
|
@@ -20214,6 +20296,8 @@ var LoadCursor = /* @__PURE__ */ b2("LoadCursorW", "<HMODULE>ptr <>ptr -> <HCURS
|
|
|
20214
20296
|
var GetCursorPos = /* @__PURE__ */ b2("GetCursorPos", "<POINT>ptr -> i32");
|
|
20215
20297
|
var ScreenToClient = /* @__PURE__ */ b2("ScreenToClient", "<HWND>ptr <POINT>ptr -> i32");
|
|
20216
20298
|
var ClientToScreen = /* @__PURE__ */ b2("ClientToScreen", "<HWND>ptr <POINT>ptr -> i32");
|
|
20299
|
+
var INPUTArr = /* @__PURE__ */ structArray(INPUT);
|
|
20300
|
+
var SendInput = /* @__PURE__ */ b2("SendInput", "u32 <INPUT>ptr i32 -> u32", { INPUT: INPUTArr });
|
|
20217
20301
|
var ShowScrollBar = /* @__PURE__ */ b2("ShowScrollBar", "<HWND>ptr u32 i32 -> i32");
|
|
20218
20302
|
var GetSystemMetrics = /* @__PURE__ */ b2("GetSystemMetrics", "i32 -> i32");
|
|
20219
20303
|
var EnumWindows = /* @__PURE__ */ b2("EnumWindows", "<>ptr <>ptr -> i32");
|
|
@@ -20266,14 +20350,14 @@ function applyProps(instance, newProps, _oldProps) {
|
|
|
20266
20350
|
gui.ShowWindow(
|
|
20267
20351
|
hwnd,
|
|
20268
20352
|
newProps.hidden ? 0 : 5
|
|
20269
|
-
/*
|
|
20353
|
+
/* ShowWindowCmd.SHOW */
|
|
20270
20354
|
);
|
|
20271
20355
|
}
|
|
20272
20356
|
if ("visible" in newProps) {
|
|
20273
20357
|
gui.ShowWindow(
|
|
20274
20358
|
hwnd,
|
|
20275
20359
|
newProps.visible ? 5 : 0
|
|
20276
|
-
/*
|
|
20360
|
+
/* ShowWindowCmd.HIDE */
|
|
20277
20361
|
);
|
|
20278
20362
|
}
|
|
20279
20363
|
}
|
|
@@ -20369,7 +20453,7 @@ function measureText(hdc, text, maxWidth) {
|
|
|
20369
20453
|
-1,
|
|
20370
20454
|
r2.ptr,
|
|
20371
20455
|
1024
|
|
20372
|
-
/*
|
|
20456
|
+
/* DrawTextFlag.CALCRECT */
|
|
20373
20457
|
);
|
|
20374
20458
|
const { right, bottom } = RECT.decode(r2);
|
|
20375
20459
|
return { width: right, height: bottom };
|
|
@@ -20417,7 +20501,7 @@ function setupWindowProc(instance, hwnd) {
|
|
|
20417
20501
|
const oldProc = GetWindowLongPtr(
|
|
20418
20502
|
hwnd,
|
|
20419
20503
|
-4
|
|
20420
|
-
/*
|
|
20504
|
+
/* Gwlp.WNDPROC */
|
|
20421
20505
|
);
|
|
20422
20506
|
instancesByHwnd.set(hwnd, instance);
|
|
20423
20507
|
gui3.SetWindowProc(hwnd, (hwnd2, msg, wParam, lParam) => {
|
|
@@ -20505,7 +20589,7 @@ function runFlexLayout(inst) {
|
|
|
20505
20589
|
r2.width * scaleFactor,
|
|
20506
20590
|
r2.height * scaleFactor,
|
|
20507
20591
|
64
|
|
20508
|
-
/*
|
|
20592
|
+
/* SetWindowPosFlag.SWP_SHOWWINDOW */
|
|
20509
20593
|
);
|
|
20510
20594
|
InvalidateRect(child.hwnd, NULL, 1);
|
|
20511
20595
|
child.lastRect = { x: r2.x, y: r2.y, w: r2.width, h: r2.height };
|
|
@@ -20661,7 +20745,7 @@ var hostConfig = {
|
|
|
20661
20745
|
gui3.ShowWindow(
|
|
20662
20746
|
instance.hwnd,
|
|
20663
20747
|
0
|
|
20664
|
-
/*
|
|
20748
|
+
/* ShowWindowCmd.HIDE */
|
|
20665
20749
|
);
|
|
20666
20750
|
},
|
|
20667
20751
|
hideTextInstance(instance) {
|
|
@@ -20669,7 +20753,7 @@ var hostConfig = {
|
|
|
20669
20753
|
gui3.ShowWindow(
|
|
20670
20754
|
instance.hwnd,
|
|
20671
20755
|
0
|
|
20672
|
-
/*
|
|
20756
|
+
/* ShowWindowCmd.HIDE */
|
|
20673
20757
|
);
|
|
20674
20758
|
},
|
|
20675
20759
|
unhideInstance(instance, _props) {
|
|
@@ -20677,7 +20761,7 @@ var hostConfig = {
|
|
|
20677
20761
|
gui3.ShowWindow(
|
|
20678
20762
|
instance.hwnd,
|
|
20679
20763
|
5
|
|
20680
|
-
/*
|
|
20764
|
+
/* ShowWindowCmd.SHOW */
|
|
20681
20765
|
);
|
|
20682
20766
|
},
|
|
20683
20767
|
unhideTextInstance(instance, _text) {
|
|
@@ -20685,7 +20769,7 @@ var hostConfig = {
|
|
|
20685
20769
|
gui3.ShowWindow(
|
|
20686
20770
|
instance.hwnd,
|
|
20687
20771
|
5
|
|
20688
|
-
/*
|
|
20772
|
+
/* ShowWindowCmd.SHOW */
|
|
20689
20773
|
);
|
|
20690
20774
|
},
|
|
20691
20775
|
shouldSetTextContent(_type, props) {
|
|
@@ -21113,7 +21197,7 @@ function getCellFont(hwnd, style) {
|
|
|
21113
21197
|
...base,
|
|
21114
21198
|
...style.bold ? {
|
|
21115
21199
|
lfWeight: 700
|
|
21116
|
-
/*
|
|
21200
|
+
/* FontWeight.BOLD */
|
|
21117
21201
|
} : {},
|
|
21118
21202
|
...style.italic ? { lfItalic: 1 } : {},
|
|
21119
21203
|
...style.underline ? { lfUnderline: 1 } : {}
|
|
@@ -21171,7 +21255,7 @@ function resolveCellStyle(columns, data, row, colIndex) {
|
|
|
21171
21255
|
}
|
|
21172
21256
|
function makeLVItem(i2, sub, text, image) {
|
|
21173
21257
|
const textBuf = WCHAR.encode(text);
|
|
21174
|
-
const
|
|
21258
|
+
const b8 = LVITEMW.encode({
|
|
21175
21259
|
mask: 1 | (image !== void 0 ? 2 : 0),
|
|
21176
21260
|
iItem: i2,
|
|
21177
21261
|
iSubItem: sub,
|
|
@@ -21188,8 +21272,8 @@ function makeLVItem(i2, sub, text, image) {
|
|
|
21188
21272
|
piColFmt: 0,
|
|
21189
21273
|
iGroup: 0
|
|
21190
21274
|
});
|
|
21191
|
-
|
|
21192
|
-
return
|
|
21275
|
+
b8.__textBuf = textBuf;
|
|
21276
|
+
return b8;
|
|
21193
21277
|
}
|
|
21194
21278
|
var ListView = (0, import_react9.forwardRef)(function ListViewInner({ columns, data, style, icons, iconSize, getIcon }, ref) {
|
|
21195
21279
|
const lvRef = (0, import_react9.useRef)(null);
|
|
@@ -21235,7 +21319,7 @@ var ListView = (0, import_react9.forwardRef)(function ListViewInner({ columns, d
|
|
|
21235
21319
|
4150,
|
|
21236
21320
|
0,
|
|
21237
21321
|
32 | 1 | 65536
|
|
21238
|
-
/*
|
|
21322
|
+
/* LvExStyle.DOUBLEBUFFER */
|
|
21239
21323
|
);
|
|
21240
21324
|
const n2 = columns.length;
|
|
21241
21325
|
for (let j2 = 0; j2 < n2; j2++) {
|
|
@@ -21280,7 +21364,7 @@ var ListView = (0, import_react9.forwardRef)(function ListViewInner({ columns, d
|
|
|
21280
21364
|
4126,
|
|
21281
21365
|
j2,
|
|
21282
21366
|
-2
|
|
21283
|
-
/*
|
|
21367
|
+
/* LvColumnWidthCmd.AUTOSIZE_USEHEADER */
|
|
21284
21368
|
);
|
|
21285
21369
|
}
|
|
21286
21370
|
}
|
|
@@ -21422,7 +21506,7 @@ var ScrollView = (0, import_react12.forwardRef)(({ children, style, contentWidth
|
|
|
21422
21506
|
natW,
|
|
21423
21507
|
natH,
|
|
21424
21508
|
4
|
|
21425
|
-
/*
|
|
21509
|
+
/* SetWindowPosFlag.SWP_NOZORDER */
|
|
21426
21510
|
);
|
|
21427
21511
|
forceFlexLayout(content);
|
|
21428
21512
|
if (natW > svW) {
|
|
@@ -21461,7 +21545,7 @@ var ScrollView = (0, import_react12.forwardRef)(({ children, style, contentWidth
|
|
|
21461
21545
|
0,
|
|
21462
21546
|
0,
|
|
21463
21547
|
1 | 4
|
|
21464
|
-
/*
|
|
21548
|
+
/* SetWindowPosFlag.SWP_NOZORDER */
|
|
21465
21549
|
);
|
|
21466
21550
|
gui12.SetScrollInfo(sv, bar, { pos: newPos }, true);
|
|
21467
21551
|
}
|
|
@@ -21527,7 +21611,7 @@ var ScrollView = (0, import_react12.forwardRef)(({ children, style, contentWidth
|
|
|
21527
21611
|
handleScroll(
|
|
21528
21612
|
e2,
|
|
21529
21613
|
1
|
|
21530
|
-
/*
|
|
21614
|
+
/* ScrollBar.VERT */
|
|
21531
21615
|
);
|
|
21532
21616
|
return 0;
|
|
21533
21617
|
}
|
|
@@ -21535,7 +21619,7 @@ var ScrollView = (0, import_react12.forwardRef)(({ children, style, contentWidth
|
|
|
21535
21619
|
handleScroll(
|
|
21536
21620
|
e2,
|
|
21537
21621
|
0
|
|
21538
|
-
/*
|
|
21622
|
+
/* ScrollBar.HORZ */
|
|
21539
21623
|
);
|
|
21540
21624
|
return 0;
|
|
21541
21625
|
}
|
|
@@ -21699,7 +21783,7 @@ function deleteAllItems(hTree) {
|
|
|
21699
21783
|
4353,
|
|
21700
21784
|
1,
|
|
21701
21785
|
-65536
|
|
21702
|
-
/*
|
|
21786
|
+
/* TvInsertAfter.ROOT */
|
|
21703
21787
|
);
|
|
21704
21788
|
}
|
|
21705
21789
|
var TreeView = (0, import_react16.forwardRef)(function TreeViewInner({ data, onSelect, defaultSelectedKey, selectedKey: controlledKey, style }, ref) {
|
|
@@ -21731,7 +21815,7 @@ var TreeView = (0, import_react16.forwardRef)(function TreeViewInner({ data, onS
|
|
|
21731
21815
|
4396,
|
|
21732
21816
|
0,
|
|
21733
21817
|
4
|
|
21734
|
-
/*
|
|
21818
|
+
/* TvExStyle.DOUBLEBUFFER */
|
|
21735
21819
|
);
|
|
21736
21820
|
}, []);
|
|
21737
21821
|
(0, import_react16.useEffect)(() => {
|
|
@@ -21773,9 +21857,16 @@ var b4 = (name, sig) => bind2("comdlg32.dll", name, sig);
|
|
|
21773
21857
|
var GetOpenFileName = /* @__PURE__ */ b4("GetOpenFileNameW", "<OPENFILENAMEW>ptr -> u32");
|
|
21774
21858
|
|
|
21775
21859
|
// _build/lib/windows/shell32.js
|
|
21776
|
-
var b5 = (name, sig) => bind2("shell32.dll", name, sig);
|
|
21860
|
+
var b5 = (name, sig, encoders) => bind2("shell32.dll", name, sig, encoders);
|
|
21777
21861
|
var SHBrowseForFolder = /* @__PURE__ */ b5("SHBrowseForFolderW", "<BROWSEINFOW>ptr -> <>ptr");
|
|
21778
21862
|
var SHGetPathFromIDList = /* @__PURE__ */ b5("SHGetPathFromIDListW", "<>ptr <BYTE>ptr -> u32");
|
|
21863
|
+
var Shell_NotifyIconGetRect = (() => {
|
|
21864
|
+
try {
|
|
21865
|
+
return b5("Shell_NotifyIconGetRect", "<NOTIFYICONIDENTIFIER>ptr <RECT>ptr -> i32", { NOTIFYICONIDENTIFIER });
|
|
21866
|
+
} catch {
|
|
21867
|
+
return null;
|
|
21868
|
+
}
|
|
21869
|
+
})();
|
|
21779
21870
|
|
|
21780
21871
|
// _build/lib/windows/ole32.js
|
|
21781
21872
|
var b6 = (name, sig) => bind2("ole32.dll", name, sig);
|
|
@@ -21928,28 +22019,183 @@ function createRoot(container) {
|
|
|
21928
22019
|
};
|
|
21929
22020
|
}
|
|
21930
22021
|
|
|
21931
|
-
// _build/examples/execd.js
|
|
22022
|
+
// _build/examples/execd/main.js
|
|
21932
22023
|
var import_react18 = __toESM(require_react(), 1);
|
|
22024
|
+
|
|
22025
|
+
// _build/examples/execd/tray.js
|
|
22026
|
+
import * as os6 from "os";
|
|
22027
|
+
import * as gui18 from "gui";
|
|
22028
|
+
|
|
22029
|
+
// _build/lib/windows/kernel32.js
|
|
22030
|
+
var b7 = (name, sig, encoders) => bind2("kernel32.dll", name, sig, encoders);
|
|
22031
|
+
var CloseHandle = /* @__PURE__ */ b7("CloseHandle", "<>ptr -> i32");
|
|
22032
|
+
var OpenProcess = /* @__PURE__ */ b7("OpenProcess", "u32 i32 u32 -> <HPROCESS>ptr");
|
|
22033
|
+
var GetCurrentProcess = /* @__PURE__ */ b7("GetCurrentProcess", " -> <HPROCESS>ptr");
|
|
22034
|
+
var VirtualAllocEx = /* @__PURE__ */ b7("VirtualAllocEx", "<HPROCESS>ptr <>ptr <>ptr u32 u32 -> <>ptr");
|
|
22035
|
+
var VirtualFreeEx = /* @__PURE__ */ b7("VirtualFreeEx", "<HPROCESS>ptr <>ptr <>ptr u32 -> i32");
|
|
22036
|
+
var ReadProcessMemory = /* @__PURE__ */ b7("ReadProcessMemory", "<HPROCESS>ptr <>ptr <BYTE>ptr <>ptr <>ptr -> i32");
|
|
22037
|
+
var IsWow64Process = /* @__PURE__ */ b7("IsWow64Process", "<HPROCESS>ptr <BYTE>ptr -> i32");
|
|
22038
|
+
|
|
22039
|
+
// _build/examples/execd/tray.js
|
|
22040
|
+
var TB_GETBUTTON = 1047;
|
|
22041
|
+
var TB_BUTTONCOUNT = 1048;
|
|
22042
|
+
var TB_GETITEMRECT = 1053;
|
|
22043
|
+
var CLS_BUF = 512;
|
|
22044
|
+
var OS64 = os6.arch === "x64" || (() => {
|
|
22045
|
+
const wow = new PtrArrayBuffer(4);
|
|
22046
|
+
return IsWow64Process(GetCurrentProcess(), wow) !== 0 && new Uint32Array(wow)[0] !== 0;
|
|
22047
|
+
})();
|
|
22048
|
+
var TBBUTTON_DWDATA = OS64 ? 16 : 12;
|
|
22049
|
+
var TBBUTTON_ISTRING = OS64 ? 24 : 16;
|
|
22050
|
+
var TBBUTTON_SZ = OS64 ? 32 : 20;
|
|
22051
|
+
var TRAYDATA_UID = OS64 ? 8 : 4;
|
|
22052
|
+
var REMOTE_BUF = 256;
|
|
22053
|
+
function findToolbars(root) {
|
|
22054
|
+
const out = [];
|
|
22055
|
+
const cls = WCHAR.alloc(CLS_BUF);
|
|
22056
|
+
const walk = (parent) => {
|
|
22057
|
+
let child = FindWindowEx(parent, NULL, NULL, NULL);
|
|
22058
|
+
while (child) {
|
|
22059
|
+
const n2 = GetClassName(child, cls, CLS_BUF);
|
|
22060
|
+
if (n2 > 0 && WCHAR.decode(cls) === "ToolbarWindow32")
|
|
22061
|
+
out.push(child);
|
|
22062
|
+
walk(child);
|
|
22063
|
+
child = FindWindowEx(parent, child, NULL, NULL);
|
|
22064
|
+
}
|
|
22065
|
+
};
|
|
22066
|
+
walk(root);
|
|
22067
|
+
return out;
|
|
22068
|
+
}
|
|
22069
|
+
function readToolbar(tb, area, out) {
|
|
22070
|
+
const count = gui18.SendMessage(tb, TB_BUTTONCOUNT, 0, 0);
|
|
22071
|
+
if (!Number.isInteger(count) || count <= 0 || count > 512)
|
|
22072
|
+
return;
|
|
22073
|
+
const pidBuf = BYTE.alloc(4);
|
|
22074
|
+
if (GetWindowThreadProcessId(tb, pidBuf) === 0)
|
|
22075
|
+
return;
|
|
22076
|
+
const pid = new Uint32Array(pidBuf)[0];
|
|
22077
|
+
const proc = OpenProcess(56, 0, pid);
|
|
22078
|
+
if (!proc)
|
|
22079
|
+
throw new Error("OpenProcess(explorer " + pid + ") failed");
|
|
22080
|
+
const remote = VirtualAllocEx(proc, NULL, REMOTE_BUF, 12288, 4);
|
|
22081
|
+
if (!remote) {
|
|
22082
|
+
CloseHandle(proc);
|
|
22083
|
+
throw new Error("VirtualAllocEx failed");
|
|
22084
|
+
}
|
|
22085
|
+
try {
|
|
22086
|
+
const tbBuf = BYTE.alloc(REMOTE_BUF), trBuf = BYTE.alloc(REMOTE_BUF), tipBuf = BYTE.alloc(REMOTE_BUF);
|
|
22087
|
+
const dvTb = new DataView(tbBuf), dvTr = new DataView(trBuf);
|
|
22088
|
+
for (let i2 = 0; i2 < count; i2++) {
|
|
22089
|
+
if (!gui18.SendMessage(tb, TB_GETBUTTON, i2, remote))
|
|
22090
|
+
continue;
|
|
22091
|
+
if (!ReadProcessMemory(proc, remote, tbBuf, TBBUTTON_SZ, NULL))
|
|
22092
|
+
continue;
|
|
22093
|
+
const dwData = OS64 ? Number(dvTb.getBigUint64(TBBUTTON_DWDATA, true)) : dvTb.getUint32(TBBUTTON_DWDATA, true);
|
|
22094
|
+
if (dwData < 65536)
|
|
22095
|
+
continue;
|
|
22096
|
+
if (!ReadProcessMemory(proc, dwData, trBuf, TRAYDATA_UID + 4, NULL))
|
|
22097
|
+
continue;
|
|
22098
|
+
const hWnd = OS64 ? Number(dvTr.getBigUint64(0, true)) : dvTr.getUint32(0, true);
|
|
22099
|
+
const uID = dvTr.getUint32(TRAYDATA_UID, true);
|
|
22100
|
+
if (!hWnd || !IsWindow(hWnd))
|
|
22101
|
+
continue;
|
|
22102
|
+
let rect = null;
|
|
22103
|
+
if (gui18.SendMessage(tb, TB_GETITEMRECT, i2, remote) && ReadProcessMemory(proc, remote, trBuf, 16, NULL)) {
|
|
22104
|
+
const L2 = dvTr.getInt32(0, true), T2 = dvTr.getInt32(4, true);
|
|
22105
|
+
const R2 = dvTr.getInt32(8, true), B2 = dvTr.getInt32(12, true);
|
|
22106
|
+
if (!(L2 === 0 && T2 === 0 && R2 === 0 && B2 === 0)) {
|
|
22107
|
+
const tl = POINT.encode({ x: L2, y: T2 }), br2 = POINT.encode({ x: R2, y: B2 });
|
|
22108
|
+
if (ClientToScreen(tb, tl.ptr) && ClientToScreen(tb, br2.ptr)) {
|
|
22109
|
+
const a2 = POINT.decode(tl), b8 = POINT.decode(br2);
|
|
22110
|
+
rect = { left: a2.x, top: a2.y, right: b8.x, bottom: b8.y };
|
|
22111
|
+
}
|
|
22112
|
+
}
|
|
22113
|
+
}
|
|
22114
|
+
const iStr = OS64 ? Number(dvTb.getBigUint64(TBBUTTON_ISTRING, true)) : dvTb.getUint32(TBBUTTON_ISTRING, true);
|
|
22115
|
+
let tooltip = null;
|
|
22116
|
+
if (iStr >= 65536 && ReadProcessMemory(proc, iStr, tipBuf, 256, NULL)) {
|
|
22117
|
+
const dvTip = new DataView(tipBuf);
|
|
22118
|
+
let s2 = "";
|
|
22119
|
+
for (let off = 0; off < 256; off += 2) {
|
|
22120
|
+
const c2 = dvTip.getUint16(off, true);
|
|
22121
|
+
if (c2 === 0)
|
|
22122
|
+
break;
|
|
22123
|
+
s2 += String.fromCharCode(c2);
|
|
22124
|
+
}
|
|
22125
|
+
tooltip = s2 === "" ? null : s2;
|
|
22126
|
+
}
|
|
22127
|
+
out.push({ area, index: i2, hWnd, uID, tooltip, rect });
|
|
22128
|
+
}
|
|
22129
|
+
} finally {
|
|
22130
|
+
VirtualFreeEx(proc, remote, 0, 32768);
|
|
22131
|
+
CloseHandle(proc);
|
|
22132
|
+
}
|
|
22133
|
+
}
|
|
22134
|
+
function collectArea(root, area, out) {
|
|
22135
|
+
for (const tb of findToolbars(root))
|
|
22136
|
+
readToolbar(tb, area, out);
|
|
22137
|
+
}
|
|
22138
|
+
function collectVisible(root, out) {
|
|
22139
|
+
let main = null;
|
|
22140
|
+
let mainRight = -Infinity;
|
|
22141
|
+
for (const tb of findToolbars(root)) {
|
|
22142
|
+
const rc2 = RECT.alloc();
|
|
22143
|
+
if (!GetWindowRect(tb, rc2.ptr))
|
|
22144
|
+
continue;
|
|
22145
|
+
const right = RECT.decode(rc2).right;
|
|
22146
|
+
if (right > mainRight) {
|
|
22147
|
+
mainRight = right;
|
|
22148
|
+
main = tb;
|
|
22149
|
+
}
|
|
22150
|
+
}
|
|
22151
|
+
if (main)
|
|
22152
|
+
readToolbar(main, "visible", out);
|
|
22153
|
+
}
|
|
22154
|
+
function listTrayIcons() {
|
|
22155
|
+
const icons = [];
|
|
22156
|
+
const tray = FindWindow("Shell_TrayWnd", NULL);
|
|
22157
|
+
if (tray) {
|
|
22158
|
+
const notifyArea = FindWindowEx(tray, NULL, "TrayNotifyWnd", NULL);
|
|
22159
|
+
collectVisible(notifyArea ? notifyArea : tray, icons);
|
|
22160
|
+
}
|
|
22161
|
+
const overflow = FindWindow("NotifyIconOverflowWindow", NULL);
|
|
22162
|
+
if (overflow)
|
|
22163
|
+
collectArea(overflow, "overflow", icons);
|
|
22164
|
+
return icons;
|
|
22165
|
+
}
|
|
22166
|
+
function probeTrayIcon(hWnd, uID) {
|
|
22167
|
+
if (!Shell_NotifyIconGetRect)
|
|
22168
|
+
return { hr: -1, hrName: "unsupported", rect: null };
|
|
22169
|
+
const rc2 = RECT.alloc();
|
|
22170
|
+
const hr2 = Shell_NotifyIconGetRect({ cbSize: NOTIFYICONIDENTIFIER.size, hWnd, uID }, rc2.ptr);
|
|
22171
|
+
const hrName = hr2 === 0 ? "found" : hr2 === 1 ? "hidden" : hr2 === -2147467259 ? "not_found" : "hr=0x" + (hr2 >>> 0).toString(16);
|
|
22172
|
+
if (hr2 !== 0)
|
|
22173
|
+
return { hr: hr2, hrName, rect: null };
|
|
22174
|
+
const r2 = RECT.decode(rc2);
|
|
22175
|
+
return { hr: hr2, hrName, rect: { left: r2.left, top: r2.top, right: r2.right, bottom: r2.bottom } };
|
|
22176
|
+
}
|
|
22177
|
+
|
|
22178
|
+
// _build/examples/execd/main.js
|
|
21933
22179
|
function parseArgs() {
|
|
21934
|
-
let
|
|
22180
|
+
let gui20 = true;
|
|
21935
22181
|
let token = null;
|
|
21936
22182
|
const args = typeof scriptArgs === "undefined" ? [] : scriptArgs;
|
|
21937
22183
|
const normToken2 = (v2) => v2 === "" ? null : v2;
|
|
21938
22184
|
for (let i2 = 0; i2 < args.length; i2++) {
|
|
21939
22185
|
const a2 = args[i2] ?? "";
|
|
21940
22186
|
if (a2 === "--nogui") {
|
|
21941
|
-
|
|
22187
|
+
gui20 = false;
|
|
21942
22188
|
} else if (a2 === "--gui") {
|
|
21943
|
-
|
|
22189
|
+
gui20 = (args[++i2] ?? "") !== "0";
|
|
21944
22190
|
} else if (a2.startsWith("--gui=")) {
|
|
21945
|
-
|
|
22191
|
+
gui20 = a2.slice(6) !== "0";
|
|
21946
22192
|
} else if (a2 === "--token") {
|
|
21947
22193
|
token = normToken2(args[++i2] ?? "");
|
|
21948
22194
|
} else if (a2.startsWith("--token=")) {
|
|
21949
22195
|
token = normToken2(a2.slice(8));
|
|
21950
22196
|
}
|
|
21951
22197
|
}
|
|
21952
|
-
return { gui:
|
|
22198
|
+
return { gui: gui20, token };
|
|
21953
22199
|
}
|
|
21954
22200
|
var cfg = parseArgs();
|
|
21955
22201
|
var log = new RequestLog(100);
|
|
@@ -21983,7 +22229,7 @@ function formatInfo() {
|
|
|
21983
22229
|
function refreshGui() {
|
|
21984
22230
|
if (!guiUpdater || guiTimer !== null)
|
|
21985
22231
|
return;
|
|
21986
|
-
guiTimer =
|
|
22232
|
+
guiTimer = os7.setTimeout(() => {
|
|
21987
22233
|
guiTimer = null;
|
|
21988
22234
|
const u2 = guiUpdater;
|
|
21989
22235
|
if (u2)
|
|
@@ -22013,10 +22259,10 @@ function initGui() {
|
|
|
22013
22259
|
height: 420
|
|
22014
22260
|
});
|
|
22015
22261
|
root.render((0, import_jsx_runtime16.jsx)(LogPanel, {}));
|
|
22016
|
-
|
|
22262
|
+
gui19.ShowWindow(
|
|
22017
22263
|
root.hwnd,
|
|
22018
22264
|
9
|
|
22019
|
-
/*
|
|
22265
|
+
/* ShowWindowCmd.RESTORE */
|
|
22020
22266
|
);
|
|
22021
22267
|
} catch (ex) {
|
|
22022
22268
|
console.error("[execd] gui init failed (fallback headless):", ex);
|
|
@@ -22045,7 +22291,7 @@ function authCheck(req) {
|
|
|
22045
22291
|
}
|
|
22046
22292
|
function runInWorker(cmd, signal, timeoutMs) {
|
|
22047
22293
|
const spawnCmd = cmd;
|
|
22048
|
-
const worker = new os6.Worker("data:text/javascript;base64,aW1wb3J0KmFzIE90IGZyb20ib3MiO2ltcG9ydCphcyBMdCBmcm9tInN0ZCI7aW1wb3J0KmFzIGIgZnJvbSJmZmkiO2ltcG9ydCphcyBkdCBmcm9tIm9zIjtpbXBvcnQqYXMgbXQgZnJvbSJzdGQiO2ltcG9ydCphcyAkIGZyb20id2luIjt2YXIgUHQ9eyJ1dGYtOCI6InV0Zi04Iix1dGY4OiJ1dGYtOCIsInVuaWNvZGUtMS0xLXV0Zi04IjoidXRmLTgiLCJ1dGYtMTYiOiJ1dGYtMTZsZSIsInV0Zi0xNmxlIjoidXRmLTE2bGUiLCJ1dGYtMTZiZSI6InV0Zi0xNmJlIn07ZnVuY3Rpb24gc3QodCl7aWYoIXQpcmV0dXJuInV0Zi04IjtsZXQgZT1QdFt0LnRyaW0oKS50b0xvd2VyQ2FzZSgpXTtpZihlKXJldHVybiBlO3Rocm93IG5ldyBSYW5nZUVycm9yKGBUaGUgZW5jb2RpbmcgbGFiZWwgIiR7dH0iIGlzIG5vdCBzdXBwb3J0ZWRgKX1mdW5jdGlvbiBNdCh0LGUpe2xldCByPSIiO2ZvcihsZXQgbj0wO248dC5sZW5ndGg7KXtsZXQgbz10W24rK107aWYobzwxMjgpe3IrPVN0cmluZy5mcm9tQ2hhckNvZGUobyk7Y29udGludWV9aWYobzwxOTIpe3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigidW5leHBlY3RlZCBjb250aW51YXRpb24gYnl0ZSIpfSkoKToiXHVGRkZEIjtjb250aW51ZX1sZXQgaSxjO2lmKG88MjI0KXtpZihuPj10Lmxlbmd0aCl7cis9ZT8oKCk9Pnt0aHJvdyBuZXcgVHlwZUVycm9yKCJpbmNvbXBsZXRlIHV0Zi04Iil9KSgpOiJcdUZGRkQiO2JyZWFrfWxldCBzPXRbbisrXTtpZigocyYxOTIpIT09MTI4KXtyKz0iXHVGRkZEIjtjb250aW51ZX1pPShvJjMxKTw8NnxzJjYzLGM9MTI4fWVsc2UgaWYobzwyNDApe2lmKG4rMT49dC5sZW5ndGgpe3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW5jb21wbGV0ZSB1dGYtOCIpfSkoKToiXHVGRkZEIjticmVha31sZXQgcz10W24rK10sdT10W24rK107aWYoKHMmMTkyKSE9PTEyOHx8KHUmMTkyKSE9PTEyOCl7cis9Ilx1RkZGRCI7Y29udGludWV9aT0obyYxNSk8PDEyfChzJjYzKTw8Nnx1JjYzLGM9MjA0OH1lbHNlIGlmKG88MjQ4KXtpZihuKzI+PXQubGVuZ3RoKXtyKz1lPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoImluY29tcGxldGUgdXRmLTgiKX0pKCk6Ilx1RkZGRCI7YnJlYWt9bGV0IHM9dFtuKytdLHU9dFtuKytdLHA9dFtuKytdO2lmKChzJjE5MikhPT0xMjh8fCh1JjE5MikhPT0xMjh8fChwJjE5MikhPT0xMjgpe3IrPSJcdUZGRkQiO2NvbnRpbnVlfWk9KG8mNyk8PDE4fChzJjYzKTw8MTJ8KHUmNjMpPDw2fHAmNjMsYz02NTUzNn1lbHNle3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW52YWxpZCB1dGYtOCBzdGFydCIpfSkoKToiXHVGRkZEIjtjb250aW51ZX1pZihpPGN8fGk+PTU1Mjk2JiZpPD01NzM0M3x8aT4xMTE0MTExKXtyKz1lPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoImludmFsaWQgdXRmLTggY29kZXBvaW50Iil9KSgpOiJcdUZGRkQiO2NvbnRpbnVlfWk8PTY1NTM1P3IrPVN0cmluZy5mcm9tQ2hhckNvZGUoaSk6KGktPTY1NTM2LHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8aT4+MTAsNTYzMjB8aSYxMDIzKSl9cmV0dXJuIHJ9ZnVuY3Rpb24gV3QodCxlLHIpe2xldCBuPW5ldyBEYXRhVmlldyh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQsdC5ieXRlTGVuZ3RoKSxvPSIiO2ZvcihsZXQgaT0wO2krMTx0Lmxlbmd0aDtpKz0yKXtsZXQgYz1uLmdldFVpbnQxNihpLGUpO2lmKGM+PTU1Mjk2JiZjPD01NjMxOSl7aWYoaSs9MixpKzE+PXQubGVuZ3RoKXtvKz1yPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoInRydW5jYXRlZCBzdXJyb2dhdGUgcGFpciIpfSkoKToiXHVGRkZEIjticmVha31sZXQgcz1uLmdldFVpbnQxNihpLGUpO3M+PTU2MzIwJiZzPD01NzM0Mz9vKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGMscyk6KG8rPXI/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW52YWxpZCBzdXJyb2dhdGUgcGFpciIpfSkoKToiXHVGRkZEIixpLT0yKX1lbHNlIGM+PTU2MzIwJiZjPD01NzM0Mz9vKz1yPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoInVuZXhwZWN0ZWQgdHJhaWxpbmcgc3Vycm9nYXRlIil9KSgpOiJcdUZGRkQiOm8rPVN0cmluZy5mcm9tQ2hhckNvZGUoYyl9cmV0dXJuIG99dmFyIFk9Y2xhc3N7X2VuY29kaW5nO19mYXRhbDtfaWdub3JlQk9NO2NvbnN0cnVjdG9yKGUscil7dGhpcy5fZW5jb2Rpbmc9c3QoZSksdGhpcy5fZmF0YWw9cj8uZmF0YWw/PyExLHRoaXMuX2lnbm9yZUJPTT1yPy5pZ25vcmVCT00/PyExfWdldCBlbmNvZGluZygpe3JldHVybiB0aGlzLl9lbmNvZGluZ31nZXQgZmF0YWwoKXtyZXR1cm4gdGhpcy5fZmF0YWx9Z2V0IGlnbm9yZUJPTSgpe3JldHVybiB0aGlzLl9pZ25vcmVCT019ZGVjb2RlKGUpe2lmKCFlKXJldHVybiIiO2xldCByPWUgaW5zdGFuY2VvZiBVaW50OEFycmF5P2U6ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyP25ldyBVaW50OEFycmF5KGUpOm5ldyBVaW50OEFycmF5KGUuYnVmZmVyLGUuYnl0ZU9mZnNldCxlLmJ5dGVMZW5ndGgpO2lmKHRoaXMuX2VuY29kaW5nPT09InV0Zi04IilyZXR1cm4gTXQocix0aGlzLl9mYXRhbCk7bGV0IG49dGhpcy5fZW5jb2Rpbmc9PT0idXRmLTE2bGUiLG89MDtpZihyLmxlbmd0aD49MiYmIXRoaXMuX2lnbm9yZUJPTSl7bGV0IGk9bj9yWzBdOnJbMV0scz0obj9yWzFdOnJbMF0pPDw4fGk7KHM9PT02NTI3OXx8cz09PTY1NTM0KSYmKG89Mil9cmV0dXJuIFd0KHIuc2xpY2Uobyksbix0aGlzLl9mYXRhbCl9fSx2PWNsYXNze19lbmNvZGluZztjb25zdHJ1Y3RvcihlKXt0aGlzLl9lbmNvZGluZz1zdChlKX1nZXQgZW5jb2RpbmcoKXtyZXR1cm4gdGhpcy5fZW5jb2Rpbmd9ZW5jb2RlKGUpe2lmKCFlKXJldHVybiBuZXcgVWludDhBcnJheSgwKTtpZih0aGlzLl9lbmNvZGluZz09PSJ1dGYtOCIpe2xldCBpPVtdO2ZvcihsZXQgYz0wO2M8ZS5sZW5ndGg7YysrKXtsZXQgcz1lLmNoYXJDb2RlQXQoYyk7aWYoczwxMjgpaS5wdXNoKHMpO2Vsc2UgaWYoczwyMDQ4KWkucHVzaCgxOTJ8cz4+NiwxMjh8cyY2Myk7ZWxzZSBpZihzPDU1Mjk2fHxzPj01NzM0NClpLnB1c2goMjI0fHM+PjEyLDEyOHxzPj42JjYzLDEyOHxzJjYzKTtlbHNle2MrKztsZXQgdT1lLmNoYXJDb2RlQXQoYyk7cz02NTUzNisoKHMmMTAyMyk8PDEwKXx1JjEwMjMsaS5wdXNoKDI0MHxzPj4xOCwxMjh8cz4+MTImNjMsMTI4fHM+PjYmNjMsMTI4fHMmNjMpfX1yZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaSl9bGV0IHI9dGhpcy5fZW5jb2Rpbmc9PT0idXRmLTE2bGUiLG49bmV3IEFycmF5QnVmZmVyKGUubGVuZ3RoKjIpLG89bmV3IERhdGFWaWV3KG4pO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7aSsrKW8uc2V0VWludDE2KGkqMixlLmNoYXJDb2RlQXQoaSkscik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG4pfX07dHlwZW9mIGdsb2JhbFRoaXMuVGV4dERlY29kZXI+InUiJiYoZ2xvYmFsVGhpcy5UZXh0RGVjb2Rlcj1ZKTt0eXBlb2YgZ2xvYmFsVGhpcy5UZXh0RW5jb2Rlcj4idSImJihnbG9iYWxUaGlzLlRleHRFbmNvZGVyPXYpO2ltcG9ydHtidWZmZXJQdHIgYXMgUnR9ZnJvbSJmZmkiO2ltcG9ydCphcyBjdCBmcm9tIm9zIjt2YXIga3Q9WyJ2b2lkIiwidTgiLCJpOCIsInUxNiIsImkxNiIsInUzMiIsImkzMiIsInU2NCIsImk2NCIsImYzMiIsImY2NCIsInB0ciJdLGo9L148KFtBLVphLXpfXVx3KnwpPnB0cighfEBbQS1aYS16X11cdyopPyQvO2Z1bmN0aW9uIHkodCl7cmV0dXJuIGoudGVzdCh0KX12YXIgdXQ9L148KFtBLVphLXpfXVx3Kik+JC87ZnVuY3Rpb24gTih0KXtyZXR1cm4gdXQudGVzdCh0KX1mdW5jdGlvbiBXKHQpe3JldHVybiB1dC5leGVjKHQpPy5bMV18fCIifWZ1bmN0aW9uIFgodCl7cmV0dXJuIGouZXhlYyh0KT8uWzFdfHwiIn12YXIgYXQ9dD0+e2lmKHkodCkpcmV0dXJuInB0ciI7aWYoTih0KSl0aHJvdyBuZXcgRXJyb3IoYGZmaTogY1Rva2VuVG9UeXBlOiBieS12YWx1ZSB0b2tlbiAiJHt0fSIgaGFzIG5vIHNjYWxhciBzbG90IHR5cGVgKTtyZXR1cm4gdH0sRD1jdC5hcmNoPT09Ing2NCI/ODo0LFI9e3U4OjEsaTg6MSx1MTY6MixpMTY6Mix1MzI6NCxpMzI6NCx1NjQ6OCxpNjQ6OCxmMzI6NCxmNjQ6OH0sTz0wO2Z1bmN0aW9uIGsodCl7aWYoeSh0KSl7bGV0IG89ai5leGVjKHQpLGk9bz8uWzFdfHwiIjtyZXR1cm4gbz8uWzJdPy5zdGFydHNXaXRoKCJAIik/YDwke2l9PnB0cmA6dH1pZihOKHQpKXJldHVybiB0O2xldCBlPXQuaW5kZXhPZigiQCIpLHI9ZT49MD90LnNsaWNlKDAsZSk6dDtpZigoZTwwfHwvXltBLVphLXpfXVx3KiQvLnRlc3QodC5zbGljZShlKzEpKSkmJnIhPT0icHRyIiYma3QuaW5jbHVkZXMocikpcmV0dXJuIHI7dGhyb3cgbmV3IEVycm9yKCJVbmtub3duIHRva2VuOiAiK3QpfWZ1bmN0aW9uIHoodCxlLHIpe3N3aXRjaChyKXtjYXNlInU4IjpyZXR1cm4gdC5nZXRVaW50OChlKTtjYXNlImk4IjpyZXR1cm4gdC5nZXRJbnQ4KGUpO2Nhc2UidTE2IjpyZXR1cm4gdC5nZXRVaW50MTYoZSwhMCk7Y2FzZSJpMTYiOnJldHVybiB0LmdldEludDE2KGUsITApO2Nhc2UidTMyIjpyZXR1cm4gdC5nZXRVaW50MzIoZSwhMCk7Y2FzZSJpMzIiOnJldHVybiB0LmdldEludDMyKGUsITApO2Nhc2UidTY0IjpyZXR1cm4gdC5nZXRCaWdVaW50NjQoZSwhMCk7Y2FzZSJpNjQiOnJldHVybiB0LmdldEJpZ0ludDY0KGUsITApO2Nhc2UiZjMyIjpyZXR1cm4gdC5nZXRGbG9hdDMyKGUsITApO2Nhc2UiZjY0IjpyZXR1cm4gdC5nZXRGbG9hdDY0KGUsITApO2Nhc2UicHRyIjpyZXR1cm4gRD09PTg/TnVtYmVyKHQuZ2V0QmlnSW50NjQoZSwhMCkpOnQuZ2V0SW50MzIoZSwhMCl9fWZ1bmN0aW9uIFoodCxlLHtrOnIsdjpufSl7c3dpdGNoKHIpe2Nhc2UidTgiOnQuc2V0VWludDgoZSxOdW1iZXIobikpO2JyZWFrO2Nhc2UiaTgiOnQuc2V0SW50OChlLE51bWJlcihuKSk7YnJlYWs7Y2FzZSJ1MTYiOnQuc2V0VWludDE2KGUsTnVtYmVyKG4pLCEwKTticmVhaztjYXNlImkxNiI6dC5zZXRJbnQxNihlLE51bWJlcihuKSwhMCk7YnJlYWs7Y2FzZSJ1MzIiOnQuc2V0VWludDMyKGUsbj4+PjAsITApO2JyZWFrO2Nhc2UiaTMyIjp0LnNldFVpbnQzMihlLG4+Pj4wLCEwKTticmVhaztjYXNlInU2NCI6dC5zZXRCaWdVaW50NjQoZSxuLCEwKTticmVhaztjYXNlImk2NCI6dC5zZXRCaWdJbnQ2NChlLG4sITApO2JyZWFrO2Nhc2UiZjMyIjp0LnNldEZsb2F0MzIoZSxuLCEwKTticmVhaztjYXNlImY2NCI6dC5zZXRGbG9hdDY0KGUsbiwhMCk7YnJlYWs7Y2FzZSJwdHIiOntpZihuPT1udWxsKXRocm93IG5ldyBFcnJvcigiZmZpOiBnb3QgbnVsbC91bmRlZmluZWQgZm9yIGEgcHRyIHNsb3Q7IHBhc3MgdGhlIGltcG9ydGVkIE5VTEwgY29uc3RhbnQgZm9yIGVtcHR5Iik7RD09PTg/dC5zZXRCaWdVaW50NjQoZSxCaWdJbnQuYXNVaW50Tig2NCxCaWdJbnQobikpLCEwKTp0LnNldFVpbnQzMihlLG4+Pj4wLCEwKTticmVha319fWZ1bmN0aW9uIF8odCxlLHIpe2xldHtrOm4sdjpvfT1yO2lmKG49PT0idTgifHxuPT09Imk4Inx8bj09PSJ1MTYifHxuPT09ImkxNiIpe3Quc2V0VWludDMyKGUsTnVtYmVyKG8pPj4+MCwhMCk7cmV0dXJufVoodCxlLHIpfXZhciBoPWNsYXNzIGV4dGVuZHMgQXJyYXlCdWZmZXJ7cHRyO2NvbnN0cnVjdG9yKGUpe3N1cGVyKGUpLHRoaXMucHRyPVJ0KHRoaXMpfX07ZnVuY3Rpb24gcSh0LGUpe3JldHVybiBlW3RdfXZhciBwdD1uZXcgTWFwO2Z1bmN0aW9uIF90KHQpe2xldCBlPXB0LmdldCh0KTtpZihlIT09dm9pZCAwKXJldHVybiBlO2xldCByPSQuTG9hZExpYnJhcnkodCk7aWYoIXIpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogTG9hZExpYnJhcnkoIiR7dH0iKSBmYWlsZWRgKTtyZXR1cm4gcHQuc2V0KHQscikscn1mdW5jdGlvbiBCdCh0KXtsZXQgZT10LnNwbGl0KCIgLT4gIik7aWYoZS5sZW5ndGghPT0yKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6IGludmFsaWQgc2lnbmF0dXJlICIke3R9IiAoZXhwZWN0ZWQgImFyZzEgYXJnMiAtPiByZXQiKWApO2xldCByPWVbMF0uc3BsaXQoIiAiKS5maWx0ZXIoaT0+aSE9PSIiKSxuPVtdO2ZvcihsZXQgaSBvZiByKXtsZXQgYz1rKGkpO2lmKGM9PT0idm9pZCIpdGhyb3cgbmV3IEVycm9yKCJWb2lkIGNhbiBub3QgaW4gYXJncyIpO24ucHVzaChjKX1sZXQgbz1rKGVbMV0pO2lmKE4obykpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogIiR7dH0iOiBieS12YWx1ZSBzdHJ1Y3QgYXQgdGhlIHJldHVybiBwb3NpdGlvbiAoPCR7VyhvKX0+KSBpcyBub3Qgc3VwcG9ydGVkIFx1MjAxNCBhcmd1bWVudCBwb3NpdGlvbnMgb25seTsgcGFzcyBhIHN0cnVjdCBvdXQgdGhyb3VnaCBhbiBvdXQtcGFyYW0gc2xvdCBpbnN0ZWFkICg8Tj5wdHIgKyBjYWxsZXIgYnVmZmVyKWApO3JldHVybnthcmdUb2tlbnM6bixyZXRUb2tlbjpvLHNpZzp0fX1mdW5jdGlvbiBVdCh0LGUscixuKXtsZXQgbz1CdChlKTtmb3IobGV0IGkgb2Ygby5hcmdUb2tlbnMpe2lmKCFOKGkpKWNvbnRpbnVlO2xldCBjPVcoaSkscz1xKGMscik7aWYoIXN8fHR5cGVvZiBzLmVuY29kZSE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke2V9OiBieS12YWx1ZSBwb3NpdGlvbiA8JHtjfT4gaGFzIG5vIHJlZ2lzdGVyZWQgbGF5b3V0IChhdmFpbGFibGU6ICR7T2JqZWN0LmtleXMocikuam9pbigiLCAiKXx8Im5vbmUifSlgKTtpZih0eXBlb2Ygcy5zaXplIT0ibnVtYmVyInx8cy5zaXplPDEpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogJHtlfTogYnktdmFsdWUgcG9zaXRpb24gPCR7Y30+IHJlcXVpcmVzIGEgc3RydWN0IGxheW91dCB3aXRoIHNpemUgPj0gMSAoZ290ICR7cy5zaXplfTsgbm9uLXN0cnVjdCBjb2RlY3MgZXhwb3NlIG5vIHNpemUpYCl9cmV0dXJuKC4uLmkpPT56dCh0LG8saSxyLG4pfXZhciBIdD17dTg6NCxpODo0LHUxNjo0LGkxNjo0LHUzMjo0LGkzMjo0LHU2NDo4LGk2NDo4LGYzMjo0LGY2NDo4LHB0cjpEfSxmdD00O2Z1bmN0aW9uIHp0KHQse2FyZ1Rva2VuczplLHJldFRva2VuOnIsc2lnOm59LG8saSxjKXtsZXQgcz1kdC5hcmNoPT09Ing2NCIsdT0oYSxkKT0+e2lmKE4oYSkpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogZ2V0V2lkdGg6IGJ5LXZhbHVlIHRva2VuICIke2F9IiAoZGlzcGF0Y2hlZCBieSB3aWR0aE9mKWApO3JldHVybiBkPzg6eShhKT9EOkh0W2FdfSxwPWE9PntpZihOKGEpKXtpZihzKXJldHVybiA4O2xldCBkPXEoVyhhKSxpKTtpZighZCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiA8JHtXKGEpfT4gYnktdmFsdWUgcG9zaXRpb24gaGFzIG5vIHJlZ2lzdGVyZWQgbGF5b3V0YCk7bGV0IG09ZC5zaXplO3JldHVybiBtJTQ9PT0wP206bSs0LW0lNH1yZXR1cm4gdShhLHMpfSx4PTA7Zm9yKGxldCBhIG9mIGUpeCs9cChhKTtzJiZlLmxlbmd0aDxmdCYmKHg9ZnQqOCk7bGV0IEY9bmV3IEFycmF5QnVmZmVyKHgpLGc9bmV3IERhdGFWaWV3KEYpLFQ9W10sRT0wO2ZvcihsZXQgYT0wO2E8ZS5sZW5ndGg7YSsrKXtsZXQgZD1lW2FdLG09ZC5lbmRzV2l0aCgiISIpLGY9b1thXTtpZih5KGQpKXtsZXQgbD1YKGQpO2lmKHR5cGVvZiBmPT0ibnVtYmVyIil7aWYobSYmZj09PTApdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogJHtufTogYXJnIyR7YSsxfSA8JHtsfT5wdHIhIGdvdCAwIChudWxsIHBvaW50ZXIgZm9yYmlkZGVuIGhlcmU7IHRoZSB0b2tlbiBtYXJrcyB0aGlzIHBvc2l0aW9uIG5vbi1udWxsKWApO18oZyxFLHtrOiJwdHIiLHY6Zn0pfWVsc2V7aWYoZj09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiA8JHtsfT5wdHIgZ290ICR7U3RyaW5nKGYpfTsgcGFzcyB0aGUgaW1wb3J0ZWQgTlVMTCBjb25zdGFudCBmb3IgYW4gZW1wdHkgcG9pbnRlcmApO2xldCBDPWlbbF07aWYoIUMpdGhyb3cgbmV3IEVycm9yKGw9PT0iIj9gZmZpLWJpbmQ6IDw+cHRyIGV4cGVjdHMgbnVtYmVyIChOVUxMIHwgUHRyKSwgZ290ICR7dHlwZW9mIGZ9OyB1c2UgPEJZVEU+cHRyIHdpdGggYSBQdHJBcnJheUJ1ZmZlciAobmV3IFB0ckFycmF5QnVmZmVyKG4pKSwgb3IgZmZpLmJ1ZmZlclB0cihidWYpIGZvciBhbiBhZGRyZXNzYDpgZmZpLWJpbmQ6IHVua25vd24gbGF5b3V0ICI8JHtsfT5wdHIiIChhdmFpbGFibGU6ICR7T2JqZWN0LmtleXMoaSkuam9pbigiLCAiKXx8Im5vbmUifSlgKTtpZighQy5lbmNvZGUpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogPCR7bH0+cHRyIGhhcyBubyBlbmNvZGVyIChvdXQtb25seSBjb2RlYylgKTtsZXQgQT1DLmVuY29kZShmKTtULnB1c2goQSk7bGV0IFA9QS5wdHI7aWYodHlwZW9mIFAhPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiZmZpLWJpbmQ6IGNvZGVjLmVuY29kZSBtdXN0IHJldHVybiBhIFB0ckFycmF5QnVmZmVyLCBnb3QgcGxhaW4gQXJyYXlCdWZmZXIiKTtpZihtJiZQPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke259OiBhcmcjJHthKzF9IDwke2x9PnB0ciEgZW5jb2RlIHByb2R1Y2VkIDAgKG51bGwgcG9pbnRlciBmb3JiaWRkZW4gaGVyZSlgKTtfKGcsRSx7azoicHRyIix2OlB9KX19ZWxzZSBpZihOKGQpKXtsZXQgbD1XKGQpLEM9cShsLGkpO2lmKCFDKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6ICR7bn06IGFyZyMke2ErMX0gPCR7bH0+IGJ5LXZhbHVlIHBvc2l0aW9uIGhhcyBubyByZWdpc3RlcmVkIGxheW91dGApO2lmKGY9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogPCR7bH0+IHZhbHVlIHBvc2l0aW9uIGdvdCAke1N0cmluZyhmKX07IHBhc3MgYSBzdHJ1Y3Qgb2JqZWN0ICh1c2UgPCR7bH0+cHRyIHRvIHBhc3MgYSBwb2ludGVyKWApO2xldCBBPUMuc2l6ZTtpZighc3x8QTw9OCYmKEEmQS0xKT09PTApQy5lbmNvZGUoZixGLEUpO2Vsc2V7bGV0IFA9bmV3IEFycmF5QnVmZmVyKEErMTUpLG90PWIuYnVmZmVyUHRyKFApLGl0PSgxNi1vdCUxNiklMTY7Qy5lbmNvZGUoZixQLGl0KSxULnB1c2goUCksXyhnLEUse2s6InB0ciIsdjpvdCtpdH0pfX1lbHNlIF8oZyxFLHtrOmQsdjpmfSk7RSs9cChkKX1sZXQgTD1uZXcgQXJyYXlCdWZmZXIoOCk7Yi5mZmlDYWxsKHQsRixMLHI9PT0iZjMyInx8cj09PSJmNjQiPzE6MCk7bGV0IFM9JHQoYXQociksTCk7aWYoci5lbmRzV2l0aCgiISIpJiZTPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke259OiByZXR1cm4gJHtyfSBnb3QgMCAodGhlIHRva2VuIHByb21pc2VzIEMgbmV2ZXIgcmV0dXJucyBudWxsIGhlcmUpYCk7aWYoeShyKSYmUyE9PTApe2xldCBhPVgocik7aWYoYSE9PSIiKXtsZXQgZD1jW2FdO2lmKGQ/LmRlY29kZSlyZXR1cm4gZC5kZWNvZGUoUyl9fXJldHVybiBTfWZ1bmN0aW9uICR0KHQsZSl7aWYodCE9PSJ2b2lkIilyZXR1cm4geihuZXcgRGF0YVZpZXcoZSksMCx0KX12YXIgRz17ZW5jb2RlOnQ9PntsZXQgZT1uZXcgVGV4dEVuY29kZXIoInV0Zi0xNmxlIikuZW5jb2RlKHQrIlwwIikscj1uZXcgaChlLmJ5dGVMZW5ndGgpO3JldHVybiBuZXcgVWludDhBcnJheShyKS5zZXQoZSkscn0sZGVjb2RlOnQ9PntpZih0eXBlb2YgdD09Im51bWJlciIpe2xldCBvPSIiLGk9dCxjPWk7Zm9yKDs7KXtsZXQgcz1iLnJlYWRCeXRlKGkpLHU9Yi5yZWFkQnl0ZShpKzEpO2lmKHM9PT0wJiZ1PT09MClyZXR1cm4gbztpZihvKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHN8dTw8OCksaSs9MixpLWM+MTw8MjEpdGhyb3cgbmV3IEVycm9yKCJmZmktYmluZDogV0NIQVIgZGVjb2RlIGV4Y2VlZGVkIDRNaUIgd2l0aG91dCBOVUwiKX19bGV0IGU9bmV3IFVpbnQ4QXJyYXkodCkscj1lLmxlbmd0aCYtMixuPSIiO2ZvcihsZXQgbz0wO288cjtvKz0yKXtsZXQgaT1lW29dfGVbbysxXTw8ODtpZihpPT09MClyZXR1cm4gbjtuKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpfXJldHVybiBufSxhbGxvYzoodD0yNTYpPT5uZXcgaCh0KjIpfSxHdD17ZW5jb2RlOnQ9PntpZighKHQgaW5zdGFuY2VvZiBoKSl0aHJvdyBuZXcgRXJyb3IoImZmaS1iaW5kOiA8QllURT5wdHIgd2FudHMgYSBQdHJBcnJheUJ1ZmZlciAobmV3IFB0ckFycmF5QnVmZmVyKG4pIC8gQllURS5hbGxvYyAvIHN0cnVjdC5lbmNvZGUpLCBub3QgYSBwbGFpbiBBcnJheUJ1ZmZlciIpO3JldHVybiB0fSxhbGxvYzp0PT5uZXcgaCh0KX0sbHQ9e1dDSEFSOkcsQllURTpHdH07ZnVuY3Rpb24gRXQodCxlLHIsbixvKXtsZXQgaT0kLkdldFByb2NBZGRyZXNzKF90KHQpLGUpO2lmKCFpKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6IHByb2MgIiR7ZX0iIG5vdCBmb3VuZCBpbiAke3R9YCk7bGV0IGM9bz8/bjtyZXR1cm4gVXQoaSxyLHsuLi5sdCwuLi5ufSx7Li4ubHQsLi4uYz8/e319KX12YXIgZmU9bmV3IEZpbmFsaXphdGlvblJlZ2lzdHJ5KHQ9PnttdC5wcmludGYoYFtmZmldIGNsb3N1cmUgbGVha2VkIChHQ2VkIHdpdGhvdXQgZGlzcG9zZSk6IHNpZz0iJXMiIHB0cj0weCV4CmAsdC5zaWcsdC5wdHIpfSk7aW1wb3J0KmFzIHh0IGZyb20iZmZpIjtmdW5jdGlvbiBCKHQsZSl7cmV0dXJuIHQrZS0xJn4oZS0xKX12YXIgaHQ9dD0+Ult0XSE9PXZvaWQgMDtmdW5jdGlvbiBRKHQpe2lmKHR5cGVvZiB0PT0ic3RyaW5nIil7bGV0IGU9L14odTh8dTE2KVxbKFxkKylcXUAodXRmLTh8dXRmLTE2bGUpJC8uZXhlYyh0KTtpZihlKXtsZXQgYz1OdW1iZXIoZVsyXSk7aWYoIU51bWJlci5pc0ludGVnZXIoYyl8fGM8MSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IHN0cmluZyBsZW5ndGggbXVzdCBiZSBhbiBpbnRlZ2VyID49IDEsIGdvdCAke2N9YCk7bGV0IHM9ZVsxXT09PSJ1OCI/MToyO3JldHVybntzaXplOnMqYyxhbGlnbjpzLHR5cGU6e3RhZzoic3RyaW5nIixlbmNvZGluZzplWzNdfX19bGV0IHI9L14oW15cW1xdXSspXFsoXGQrKVxdJC8uZXhlYyh0KTtpZihyKXtsZXQgYz1OdW1iZXIoclsyXSk7aWYoIU51bWJlci5pc0ludGVnZXIoYyl8fGM8MSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGFycmF5IGxlbmd0aCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMSwgZ290ICR7Y31gKTtsZXQgcz1RKHJbMV0pO2lmKHMudHlwZS50YWc9PT0iYml0ZmllbGQiKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGRzIGNhbm5vdCBiZSBhcnJheSBlbGVtZW50cyIpO3JldHVybntzaXplOnMuc2l6ZSpjLGFsaWduOnMuYWxpZ24sdHlwZTp7dGFnOiJhcnJheSIsZWxlbWVudFR5cGU6cy50eXBlLGVsZW1lbnRTaXplOnMuc2l6ZX19fWxldCBuPS9eKFtBLVphLXpfXVx3Kik6KFxkKykkLy5leGVjKHQpO2lmKG4pe2xldCBjPW5bMV0scz1rKGMpO2lmKCFodChzKXx8cz09PSJmMzIifHxzPT09ImY2NCIpdGhyb3cgbmV3IEVycm9yKGBmZmktc3RydWN0OiBiaXRmaWVsZCB1bml0IG11c3QgYmUgYW4gaW50ZWdlciB0eXBlLCBnb3QgIiR7Y30iYCk7bGV0IHU9TnVtYmVyKG5bMl0pLHA9UltzXSx4PXAqODtpZighTnVtYmVyLmlzSW50ZWdlcih1KXx8dTwxKXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYml0ZmllbGQgd2lkdGggbXVzdCBiZSBhbiBpbnRlZ2VyID49IDEsIGdvdCAke3V9YCk7aWYodT54KXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYml0ZmllbGQgd2lkdGggJHt1fSBleGNlZWRzIHVuaXQgd2lkdGggJHt4fWApO3JldHVybntzaXplOnAsYWxpZ246cCx0eXBlOnt0YWc6ImJpdGZpZWxkIix1bml0OnMsYml0OjAsd2lkdGg6dX19fWxldCBvPWsodCk7aWYoeShvKSlyZXR1cm57c2l6ZTpELGFsaWduOkQsdHlwZTp7dGFnOiJiYXNpYyIsa2luZDoicHRyIn19O2lmKCFodChvKSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IHVua25vd24ga2luZCAiJHt0fSJgKTtsZXQgaT1SW29dO3JldHVybntzaXplOmksYWxpZ246aSx0eXBlOnt0YWc6ImJhc2ljIixraW5kOm99fX1pZih0JiZ0eXBlb2YgdD09Im9iamVjdCIpe2xldCBlPXQscj1lWyIjIl07aWYocj09PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoImZmaS1zdHJ1Y3Q6IG5lc3RlZCBvYmplY3QgdmFsdWUgcmVxdWlyZXMgYSAnIycga2V5ICgnc3RydWN0JyB8ICd1bmlvbicgfCAnYXJyYXknKSIpO2lmKHI9PT0iYXJyYXkiJiYiI3BhY2siaW4gZSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6ICcjcGFjaycgaXMgb25seSBhbGxvd2VkIG9uIHN0cnVjdC91bmlvbiwgZ290ICcke3J9J2ApO2lmKHI9PT0iYXJyYXkiKXtsZXQgbj1lLmxlbmd0aDtpZighTnVtYmVyLmlzSW50ZWdlcihuKXx8bjwxKXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYXJyYXkgbGVuZ3RoIG11c3QgYmUgYW4gaW50ZWdlciA+PSAxLCBnb3QgJHtTdHJpbmcobil9YCk7bGV0IG89UShlLmVsZW1lbnQpO2lmKG8udHlwZS50YWc9PT0iYml0ZmllbGQiKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGRzIGNhbm5vdCBiZSBhcnJheSBlbGVtZW50cyIpO3JldHVybntzaXplOm8uc2l6ZSpuLGFsaWduOm8uYWxpZ24sdHlwZTp7dGFnOiJhcnJheSIsZWxlbWVudFR5cGU6by50eXBlLGVsZW1lbnRTaXplOm8uc2l6ZX19fWlmKHI9PT0ic3RydWN0Inx8cj09PSJ1bmlvbiIpe2xldCBuPXd0KHQpO3JldHVybntzaXplOm4uc2l6ZSxhbGlnbjpuLm1heEVmZmVjdGl2ZUFsaWduLHR5cGU6e3RhZzpyLGZpZWxkczpuLmZpZWxkc319fXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogdW5rbm93biAnIycgZGVjbGFyYXRpb24gJHtKU09OLnN0cmluZ2lmeShTdHJpbmcocikpfWApfXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogaW52YWxpZCBtZW1iZXIgdmFsdWU6ICR7U3RyaW5nKHQpfWApfWZ1bmN0aW9uIHd0KHQpe2xldCBlPXRbIiMiXT09PSJzdHJ1Y3QiLHI9dFsiI3BhY2siXT8/OCxuPTEsbz0wLGk9W10sYz0wLHM9LTEsdT0wLHA9MCx4PSgpPT57czwwfHwoYz1CKHMrTWF0aC5jZWlsKHUvOCkscCkscz0tMSl9O2ZvcihsZXRbRixnXW9mIE9iamVjdC5lbnRyaWVzKHQpKXtpZihGLnN0YXJ0c1dpdGgoIiMiKSljb250aW51ZTtsZXQgVD0vXihbXkBdKylAKFxkKykkLy5leGVjKEYpLEU9VD9UWzFdOkYsTD1UP051bWJlcihUWzJdKTowLHtzaXplOncsYWxpZ246Uyx0eXBlOmF9PVEoZyksZD10eXBlb2YgZz09InN0cmluZyImJmcuZW5kc1dpdGgoIiEiKSxtPVM7aWYocj4wJiYobT1NYXRoLm1pbihyLG0pKSxMJiYobT1NYXRoLm1heChtLEwpKSxhLnRhZz09PSJiaXRmaWVsZCIpe2lmKEUuc3RhcnRzV2l0aCgiJCIpKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGQgbWVtYmVycyBtdXN0IGJlIG5hbWVkIik7aWYoIWUpe2kucHVzaCh7bmFtZTpFLG9mZnNldDowLHNpemU6dyx0eXBlOnsuLi5hLGJpdDowfX0pLG49TWF0aC5tYXgobixtKSxvPU1hdGgubWF4KG8sdyk7Y29udGludWV9bGV0IGw9YS53aWR0aDsoczwwfHx3IT09cHx8dStsPnAqOCkmJihzPj0wJiZ4KCkscz1CKGMsbSksdT0wLHA9dyksaS5wdXNoKHtuYW1lOkUsb2Zmc2V0OnMsc2l6ZTp3LHR5cGU6ey4uLmEsYml0OnV9fSksdSs9bCxuPU1hdGgubWF4KG4sbSksbz1NYXRoLm1heChvLHcpO2NvbnRpbnVlfXgoKTtsZXQgZj1CKGMsbSk7aWYoIUUuc3RhcnRzV2l0aCgiJCIpKWkucHVzaCh7bmFtZTpFLG9mZnNldDpmLHNpemU6dyx0eXBlOmEsLi4uZD97bm9ubnVsbDohMH06e319KTtlbHNle2lmKGEudGFnIT09InN0cnVjdCImJmEudGFnIT09InVuaW9uIil0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGFub255bW91cyBtZW1iZXIgIiR7RX0iIG11c3QgYmUgYSBzdHJ1Y3QvdW5pb25gKTtmb3IobGV0IGwgb2YgYS5maWVsZHMpaS5wdXNoKHsuLi5sLG9mZnNldDpsLm9mZnNldCtmfSl9ZSYmKGM9Zit3KSxuPU1hdGgubWF4KG4sbSksbz1NYXRoLm1heChvLHcpfXJldHVybiB4KCkse3NpemU6QihlP2M6byxuKSxtYXhFZmZlY3RpdmVBbGlnbjpuLGZpZWxkczppfX1mdW5jdGlvbiBndCh0LGUscil7bGV0IG49UltyXTtyZXR1cm4gbj09PTE/QmlnSW50KHQuZ2V0VWludDgoZSkpOm49PT0yP0JpZ0ludCh0LmdldFVpbnQxNihlLCEwKSk6bj09PTQ/QmlnSW50KHQuZ2V0VWludDMyKGUsITApKTp0LmdldEJpZ1VpbnQ2NChlLCEwKX1mdW5jdGlvbiBWdCh0LGUscixuKXtsZXQgbz1SW3JdO2lmKG89PT0xKXt0LnNldFVpbnQ4KGUsTnVtYmVyKG4mMHhmZm4pKTtyZXR1cm59aWYobz09PTIpe3Quc2V0VWludDE2KGUsTnVtYmVyKG4mMHhmZmZmbiksITApO3JldHVybn1pZihvPT09NCl7dC5zZXRVaW50MzIoZSxOdW1iZXIobiYweGZmZmZmZmZmbiksITApO3JldHVybn10LnNldEJpZ1VpbnQ2NChlLG4mMHhmZmZmZmZmZmZmZmZmZmZmbiwhMCl9ZnVuY3Rpb24gWXQodCxlLHIpe2xldCBuPUJpZ0ludChyLndpZHRoKSxvPWd0KHQsZSxyLnVuaXQpPj5CaWdJbnQoci5iaXQpJigxbjw8biktMW47cmV0dXJuIHIudW5pdFswXT09PSJpIiYmbyYxbjw8bi0xbiYmKG8tPTFuPDxuKSxyLndpZHRoPjUzP286TnVtYmVyKG8pfWZ1bmN0aW9uIHZ0KHQsZSxyLG4pe2xldCBvPUJpZ0ludChyLndpZHRoKSxpPUJpZ0ludChyLmJpdCksYz0oMW48PG8pLTFuLHM9Yzw8aSx1PWd0KHQsZSxyLnVuaXQpLHA9KHR5cGVvZiBuPT0iYmlnaW50Ij9uOkJpZ0ludChNYXRoLnRydW5jKG4pKSkmYztWdCh0LGUsci51bml0LHUmfnN8cDw8aSl9dmFyIGp0PXsidXRmLTgiOm5ldyBUZXh0RW5jb2RlcigidXRmLTgiKSwidXRmLTE2bGUiOm5ldyBUZXh0RW5jb2RlcigidXRmLTE2bGUiKX0sWHQ9eyJ1dGYtOCI6bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2lnbm9yZUJPTTohMH0pLCJ1dGYtMTZsZSI6bmV3IFRleHREZWNvZGVyKCJ1dGYtMTZsZSIse2lnbm9yZUJPTTohMH0pfTtmdW5jdGlvbiBadCh0LGUscixuKXtsZXQgbz1uZXcgVWludDhBcnJheSh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQrZSxyKSxpPW49PT0idXRmLTE2bGUiPzI6MSxjPXI7Zm9yKGxldCBzPTA7cytpPD1yO3MrPWkpaWYob1tzXT09PTAmJihpPT09MXx8b1tzKzFdPT09MCkpe2M9czticmVha31yZXR1cm4gWHRbbl0uZGVjb2RlKG8uc3ViYXJyYXkoMCxjKSl9ZnVuY3Rpb24gcXQodCxlLHIsbixvKXtsZXQgaT1uZXcgVWludDhBcnJheSh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQrZSxyKTtpLmZpbGwoMCk7bGV0IHM9ci0obj09PSJ1dGYtMTZsZSI/MjoxKTtpZihzPD0wKXJldHVybjtsZXQgdT1qdFtuXS5lbmNvZGUoU3RyaW5nKG8/PyIiKSk7aS5zZXQodS5zdWJhcnJheSgwLE1hdGgubWluKHUubGVuZ3RoLHMpKSl9ZnVuY3Rpb24gUXQodCxlLHIsbil7bGV0IG89bi5lbGVtZW50U2l6ZT4wP3Ivbi5lbGVtZW50U2l6ZTowLGk9W107Zm9yKGxldCBjPTA7YzxvO2MrKylpLnB1c2goVHQodCxlK2Mqbi5lbGVtZW50U2l6ZSxuLmVsZW1lbnRUeXBlLG4uZWxlbWVudFNpemUpKTtyZXR1cm4gaX1mdW5jdGlvbiBLdCh0LGUscixuLG8pe2xldCBpPW4uZWxlbWVudFNpemU+MD9yL24uZWxlbWVudFNpemU6MCxjPW8/P1tdO2ZvcihsZXQgcz0wO3M8aTtzKyspRnQodCxlK3Mqbi5lbGVtZW50U2l6ZSxuLmVsZW1lbnRUeXBlLG4uZWxlbWVudFNpemUsY1tzXSl9ZnVuY3Rpb24gVHQodCxlLHIsbil7c3dpdGNoKHIudGFnKXtjYXNlImJhc2ljIjpyZXR1cm4geih0LGUsci5raW5kKTtjYXNlImJpdGZpZWxkIjpyZXR1cm4gWXQodCxlLHIpO2Nhc2Uic3RyaW5nIjpyZXR1cm4gWnQodCxlLG4sci5lbmNvZGluZyk7Y2FzZSJzdHJ1Y3QiOmNhc2UidW5pb24iOnJldHVybiBLKHQsZSxyLmZpZWxkcyk7Y2FzZSJhcnJheSI6cmV0dXJuIFF0KHQsZSxuLHIpfX1mdW5jdGlvbiBGdCh0LGUscixuLG8pe3N3aXRjaChyLnRhZyl7Y2FzZSJiYXNpYyI6Wih0LGUse2s6ci5raW5kLHY6b30pO2JyZWFrO2Nhc2UiYml0ZmllbGQiOnZ0KHQsZSxyLG8/PzApO2JyZWFrO2Nhc2Uic3RyaW5nIjpxdCh0LGUsbixyLmVuY29kaW5nLG8pO2JyZWFrO2Nhc2Uic3RydWN0IjpjYXNlInVuaW9uIjpTdCh0LGUsci5maWVsZHMsbz8/e30pO2JyZWFrO2Nhc2UiYXJyYXkiOkt0KHQsZSxuLHIsbyk7YnJlYWt9fWZ1bmN0aW9uIEsodCxlLHIpe2xldCBuPXt9O2ZvcihsZXQgbyBvZiByKXtsZXQgaT1UdCh0LGUrby5vZmZzZXQsby50eXBlLG8uc2l6ZSk7aWYoby5ub25udWxsJiZpPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGRlY29kZTogJyEnIGZpZWxkICIke28ubmFtZX0iIGdvdCAwIChDIGRpZCBub3QgZmlsbCBpdCwgb3IgZGVjb2RlIHdhcyBjYWxsZWQgb24gYW4gdW5maWxsZWQgc2xvdClgKTtuW28ubmFtZV09aX1yZXR1cm4gbn1mdW5jdGlvbiBTdCh0LGUscixuKXtmb3IobGV0IG8gb2YgciluW28ubmFtZV0hPT12b2lkIDAmJkZ0KHQsZStvLm9mZnNldCxvLnR5cGUsby5zaXplLG5bby5uYW1lXSl9ZnVuY3Rpb24gSnQodCl7bGV0e2ZpZWxkczplLHNpemU6cixtYXhFZmZlY3RpdmVBbGlnbjpufT13dCh0KTtyZXR1cm57ZmllbGRzOmUsc2l6ZTpyLHN0cnVjdEFsaWduOm4sZGVjb2RlOm89PksodHlwZW9mIG89PSJudW1iZXIiP25ldyBEYXRhVmlldyh4dC5yZWFkQnl0ZXMobyxyKSk6bmV3IERhdGFWaWV3KG8pLDAsZSksYWxsb2M6KG89PntpZihvIT09dm9pZCAwJiYoIU51bWJlci5pc0ludGVnZXIobyl8fG88MSkpdGhyb3cgbmV3IEVycm9yKCJmZmktc3RydWN0OiBhbGxvYyhuKSByZXF1aXJlcyBhbiBpbnRlZ2VyIG4gPj0gMSAoUEFCKDApIG5ldmVyIGVzY2FwZXMgXHUyMDE0IHBhc3MgTlVMTCBmb3IgYW4gZW1wdHkgcG9pbnRlciBwb3NpdGlvbikiKTtyZXR1cm4gbmV3IGgocioobz8/MSkpfSksZW5jb2RlOigobyxpLGMpPT57aWYobz09bnVsbCl0aHJvdyBuZXcgRXJyb3IoImZmaS1zdHJ1Y3Q6IGVuY29kZSh2KSByZXF1aXJlcyBhbiBhcmd1bWVudDsgdXNlIGFsbG9jKCkgZm9yIGEgemVyb2VkIG91dC1wYXJhbSBzbG90Iik7bGV0IHM9aT8/bmV3IGgocik7cmV0dXJuIFN0KG5ldyBEYXRhVmlldyhzKSxjPz8wLGUsbyksc30pLG9mZnNldE9mOm89Pntmb3IobGV0IGkgb2YgZSlpZihpLm5hbWU9PT1vKXJldHVybiBpLm9mZnNldDt0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IG5vIGZpZWxkICIke299ImApfX19ZnVuY3Rpb24gdGUodCxlLHIpe2xldCBuPWVbIiMiXTtpZihuIT09dm9pZCAwJiZuIT09dCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6ICR7dH0oKSByZWNlaXZlZCBhICcke1N0cmluZyhuKX0nIGRlY2xhcmF0aW9uIChraW5kIG1pc21hdGNoIFx1MjAxNCB1c2UgJHtufSgpIGZvciBpdClgKTtsZXQgbz1lWyIjcGFjayJdO2lmKHI9PT12b2lkIDAmJm8hPT12b2lkIDApcj1vO2Vsc2UgaWYociE9PXZvaWQgMCYmbyE9PXZvaWQgMCYmciE9PW8pdGhyb3cgbmV3IEVycm9yKGBmZmktc3RydWN0OiAjcGFjayBjb25mbGljdDogb3B0cy5wYWNrPSR7cn0gdnMgZGVjbGFyYXRpb24gJHtTdHJpbmcobyl9YCk7bGV0IGk9eyIjIjp0fTtyIT09dm9pZCAwJiYoaVsiI3BhY2siXT1yKTtmb3IobGV0W2Msc11vZiBPYmplY3QuZW50cmllcyhlKSljLnN0YXJ0c1dpdGgoIiMiKXx8KGlbY109cyk7cmV0dXJuIGl9ZnVuY3Rpb24gVSh0LGUscil7bGV0IG49dHlwZW9mIHQ9PSJzdHJpbmciO3JldHVybiBKdCh0ZSgic3RydWN0IixuP2U6dCwobj9yOmUpPy5wYWNrKSl9dmFyIGVlPXsiIyI6InN0cnVjdCIsY2I6InUzMiIsbHBSZXNlcnZlZDoiPD5wdHIiLGxwRGVza3RvcDoiPD5wdHIiLGxwVGl0bGU6Ijw+cHRyIixkd1g6InUzMiIsZHdZOiJ1MzIiLGR3WFNpemU6InUzMiIsZHdZU2l6ZToidTMyIixkd1hDb3VudENoYXJzOiJ1MzIiLGR3WUNvdW50Q2hhcnM6InUzMiIsZHdGaWxsQXR0cmlidXRlOiJ1MzIiLGR3RmxhZ3M6InUzMiIsd1Nob3dXaW5kb3c6InUxNkBTaG93V2luZG93Q21kIixjYlJlc2VydmVkMjoidTE2IixscFJlc2VydmVkMjoiPD5wdHIiLGhTdGRJbnB1dDoiPEhGSUxFPnB0ciIsaFN0ZE91dHB1dDoiPEhGSUxFPnB0ciIsaFN0ZEVycm9yOiI8SEZJTEU+cHRyIn0sVj1VKCJTVEFSVFVQSU5GT1ciLGVlKSxyZT17IiMiOiJzdHJ1Y3QiLGhQcm9jZXNzOiI8SFBST0NFU1M+cHRyISIsaFRocmVhZDoiPEhUSFJFQUQ+cHRyISIsZHdQcm9jZXNzSWQ6InUzMiIsZHdUaHJlYWRJZDoidTMyIn0sSj1VKCJQUk9DRVNTX0lORk9STUFUSU9OIixyZSk7dmFyIEk9KHQsZSxyKT0+RXQoImtlcm5lbDMyLmRsbCIsdCxlLHIpLEN0PUkoIkNyZWF0ZVBpcGUiLCI8PnB0ciA8PnB0ciA8PnB0ciB1MzIgLT4gaTMyIiksdHQ9SSgiU2V0SGFuZGxlSW5mb3JtYXRpb24iLCI8SEZJTEU+cHRyISB1MzIgdTMyIC0+IGkzMiIpLGJ0PUkoIkNyZWF0ZVByb2Nlc3NXIiwiPFdDSEFSPnB0ciA8V0NIQVI+cHRyIDw+cHRyIDw+cHRyIGkzMiB1MzIgPD5wdHIgPFdDSEFSPnB0ciA8U1RBUlRVUElORk9XPnB0ciA8UFJPQ0VTU19JTkZPUk1BVElPTj5wdHIgLT4gaTMyIix7U1RBUlRVUElORk9XOlZ9KSxJdD1JKCJXYWl0Rm9yU2luZ2xlT2JqZWN0IiwiPD5wdHIgdTMyIC0+IHUzMiIpLHl0PUkoIkdldEV4aXRDb2RlUHJvY2VzcyIsIjxIUFJPQ0VTUz5wdHIhIDxCWVRFPnB0ciAtPiBpMzIiKSxNPUkoIkNsb3NlSGFuZGxlIiwiPD5wdHIgLT4gaTMyIik7dmFyIE50PUkoIlJlYWRGaWxlIiwiPEhGSUxFPnB0ciEgPEJZVEU+cHRyIHUzMiA8QllURT5wdHIgPD5wdHIgLT4gaTMyIik7dmFyIGV0PUkoIkdldExhc3RFcnJvciIsIiAtPiB1MzIiKSxEdD1JKCJHZXRTeXN0ZW1EaXJlY3RvcnlXIiwiPEJZVEU+cHRyIHUzMiAtPiB1MzIiKTt2YXIgbmU9dD0+e3RyeXtsZXQgZT1MdC5vcGVuKCJkaWFnLmxvZyIsImEiKTtlJiYoZS5wdXRzKGAke0RhdGUubm93KCl9ICR7dH0KYCksZS5jbG9zZSgpKX1jYXRjaHt9fSxydD0xLG9lPTI1NixpZT00Mjk0OTY3Mjk1LEg9T3QuV29ya2VyLnBhcmVudCxBdD0iQzpcXFdpbmRvd3NcXFN5c3RlbTMyIjt0cnl7bGV0IHQ9Ry5hbGxvYygyNTYpLHI9RHQodCwyNTYpPjA/Ry5kZWNvZGUodCk6IiI7ciYmKEF0PXIpfWNhdGNoKHQpe25lKCJTWVMtRElSLUZBSUw6ICIrU3RyaW5nKHQpKX12YXIgbnQ9VSgiUElQRV9IQU5ETEVTIix7aFJlYWQ6IjxIRklMRT5wdHIhIixoV3JpdGU6IjxIRklMRT5wdHIhIn0pO2Z1bmN0aW9uIHNlKHQsZSl7bGV0IHI9bnQuYWxsb2MoKTtpZighQ3Qoci5wdHIsci5wdHIrbnQub2Zmc2V0T2YoImhXcml0ZSIpLE8sMCkpdGhyb3cgbmV3IEVycm9yKCJDcmVhdGVQaXBlIGVycj0iK2V0KCkpO2xldHtoUmVhZDpuLGhXcml0ZTpvfT1udC5kZWNvZGUocik7dHQobyxydCxydCksdHQobixydCwwKTtsZXQgaT1KLmFsbG9jKCksYz1gJHtBdH1cXGNtZC5leGUgL3UgL2MgJHtlfWA7aWYoIWJ0KE8sYyxPLE8sMSwwLE8sTyx7Y2I6Vi5zaXplLGR3RmxhZ3M6b2UsaFN0ZE91dHB1dDpvLGhTdGRFcnJvcjpvfSxpLnB0cikpdGhyb3cgTShuKSxNKG8pLG5ldyBFcnJvcigiQ3JlYXRlUHJvY2Vzc1cgZXJyPSIrZXQoKSsiIGNtZD0iK2MpO2xldHtoUHJvY2VzczpzLGhUaHJlYWQ6dSxkd1Byb2Nlc3NJZDpwfT1KLmRlY29kZShpKTtNKHUpLE0obyksSC5wb3N0TWVzc2FnZSh7dHlwZToiaW5mbyIsaWQ6dCxwaWQ6cH0pO2xldCB4PW5ldyBoKDQwOTYpLEY9bmV3IFVpbnQ4QXJyYXkoeCksZz1uZXcgaCg0KSxUPW5ldyBVaW50MzJBcnJheShnKTtmb3IoO1RbMF09MCwhIU50KG4seCw0MDk2LGcsTyk7KXtsZXQgUz1UWzBdO2lmKFM9PT0wKWJyZWFrO0gucG9zdE1lc3NhZ2Uoe3R5cGU6ImRhdGEiLGlkOnQsY2h1bms6Ri5zbGljZSgwLFMpfSl9SXQocyxpZSk7bGV0IEU9bmV3IGgoNCksTD1uZXcgSW50MzJBcnJheShFKTt5dChzLEUpO2xldCB3PUxbMF07cmV0dXJuIE0obiksTShzKSx3fUgub25tZXNzYWdlPXQ9PntsZXQgZT10LmRhdGE7aWYoZS50eXBlPT09InJ1biImJnR5cGVvZiBlLmNtZD09InN0cmluZyIpe2xldCByPS0xLG49bnVsbDt0cnl7cj1zZShlLmlkLGUuY21kKX1jYXRjaChvKXtuPVN0cmluZyhvKX1ILnBvc3RNZXNzYWdlKHt0eXBlOiJyZXN1bHQiLGlkOmUuaWQsY29kZTpyLGVycm9yOm59KX1ILm9ubWVzc2FnZT1udWxsfTsK");
|
|
22294
|
+
const worker = new os7.Worker("data:text/javascript;base64,aW1wb3J0KmFzIE90IGZyb20ib3MiO2ltcG9ydCphcyBQdCBmcm9tInN0ZCI7aW1wb3J0KmFzIEMgZnJvbSJmZmkiO2ltcG9ydCphcyBkdCBmcm9tIm9zIjtpbXBvcnQqYXMgbXQgZnJvbSJzdGQiO2ltcG9ydCphcyAkIGZyb20id2luIjt2YXIgQXQ9eyJ1dGYtOCI6InV0Zi04Iix1dGY4OiJ1dGYtOCIsInVuaWNvZGUtMS0xLXV0Zi04IjoidXRmLTgiLCJ1dGYtMTYiOiJ1dGYtMTZsZSIsInV0Zi0xNmxlIjoidXRmLTE2bGUiLCJ1dGYtMTZiZSI6InV0Zi0xNmJlIn07ZnVuY3Rpb24gc3QodCl7aWYoIXQpcmV0dXJuInV0Zi04IjtsZXQgZT1BdFt0LnRyaW0oKS50b0xvd2VyQ2FzZSgpXTtpZihlKXJldHVybiBlO3Rocm93IG5ldyBSYW5nZUVycm9yKGBUaGUgZW5jb2RpbmcgbGFiZWwgIiR7dH0iIGlzIG5vdCBzdXBwb3J0ZWRgKX1mdW5jdGlvbiBNdCh0LGUpe2xldCByPSIiO2ZvcihsZXQgbj0wO248dC5sZW5ndGg7KXtsZXQgbz10W24rK107aWYobzwxMjgpe3IrPVN0cmluZy5mcm9tQ2hhckNvZGUobyk7Y29udGludWV9aWYobzwxOTIpe3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigidW5leHBlY3RlZCBjb250aW51YXRpb24gYnl0ZSIpfSkoKToiXHVGRkZEIjtjb250aW51ZX1sZXQgaSxjO2lmKG88MjI0KXtpZihuPj10Lmxlbmd0aCl7cis9ZT8oKCk9Pnt0aHJvdyBuZXcgVHlwZUVycm9yKCJpbmNvbXBsZXRlIHV0Zi04Iil9KSgpOiJcdUZGRkQiO2JyZWFrfWxldCBzPXRbbisrXTtpZigocyYxOTIpIT09MTI4KXtyKz0iXHVGRkZEIjtjb250aW51ZX1pPShvJjMxKTw8NnxzJjYzLGM9MTI4fWVsc2UgaWYobzwyNDApe2lmKG4rMT49dC5sZW5ndGgpe3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW5jb21wbGV0ZSB1dGYtOCIpfSkoKToiXHVGRkZEIjticmVha31sZXQgcz10W24rK10sdT10W24rK107aWYoKHMmMTkyKSE9PTEyOHx8KHUmMTkyKSE9PTEyOCl7cis9Ilx1RkZGRCI7Y29udGludWV9aT0obyYxNSk8PDEyfChzJjYzKTw8Nnx1JjYzLGM9MjA0OH1lbHNlIGlmKG88MjQ4KXtpZihuKzI+PXQubGVuZ3RoKXtyKz1lPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoImluY29tcGxldGUgdXRmLTgiKX0pKCk6Ilx1RkZGRCI7YnJlYWt9bGV0IHM9dFtuKytdLHU9dFtuKytdLHA9dFtuKytdO2lmKChzJjE5MikhPT0xMjh8fCh1JjE5MikhPT0xMjh8fChwJjE5MikhPT0xMjgpe3IrPSJcdUZGRkQiO2NvbnRpbnVlfWk9KG8mNyk8PDE4fChzJjYzKTw8MTJ8KHUmNjMpPDw2fHAmNjMsYz02NTUzNn1lbHNle3IrPWU/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW52YWxpZCB1dGYtOCBzdGFydCIpfSkoKToiXHVGRkZEIjtjb250aW51ZX1pZihpPGN8fGk+PTU1Mjk2JiZpPD01NzM0M3x8aT4xMTE0MTExKXtyKz1lPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoImludmFsaWQgdXRmLTggY29kZXBvaW50Iil9KSgpOiJcdUZGRkQiO2NvbnRpbnVlfWk8PTY1NTM1P3IrPVN0cmluZy5mcm9tQ2hhckNvZGUoaSk6KGktPTY1NTM2LHIrPVN0cmluZy5mcm9tQ2hhckNvZGUoNTUyOTZ8aT4+MTAsNTYzMjB8aSYxMDIzKSl9cmV0dXJuIHJ9ZnVuY3Rpb24gV3QodCxlLHIpe2xldCBuPW5ldyBEYXRhVmlldyh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQsdC5ieXRlTGVuZ3RoKSxvPSIiO2ZvcihsZXQgaT0wO2krMTx0Lmxlbmd0aDtpKz0yKXtsZXQgYz1uLmdldFVpbnQxNihpLGUpO2lmKGM+PTU1Mjk2JiZjPD01NjMxOSl7aWYoaSs9MixpKzE+PXQubGVuZ3RoKXtvKz1yPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoInRydW5jYXRlZCBzdXJyb2dhdGUgcGFpciIpfSkoKToiXHVGRkZEIjticmVha31sZXQgcz1uLmdldFVpbnQxNihpLGUpO3M+PTU2MzIwJiZzPD01NzM0Mz9vKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGMscyk6KG8rPXI/KCgpPT57dGhyb3cgbmV3IFR5cGVFcnJvcigiaW52YWxpZCBzdXJyb2dhdGUgcGFpciIpfSkoKToiXHVGRkZEIixpLT0yKX1lbHNlIGM+PTU2MzIwJiZjPD01NzM0Mz9vKz1yPygoKT0+e3Rocm93IG5ldyBUeXBlRXJyb3IoInVuZXhwZWN0ZWQgdHJhaWxpbmcgc3Vycm9nYXRlIil9KSgpOiJcdUZGRkQiOm8rPVN0cmluZy5mcm9tQ2hhckNvZGUoYyl9cmV0dXJuIG99dmFyIFY9Y2xhc3N7X2VuY29kaW5nO19mYXRhbDtfaWdub3JlQk9NO2NvbnN0cnVjdG9yKGUscil7dGhpcy5fZW5jb2Rpbmc9c3QoZSksdGhpcy5fZmF0YWw9cj8uZmF0YWw/PyExLHRoaXMuX2lnbm9yZUJPTT1yPy5pZ25vcmVCT00/PyExfWdldCBlbmNvZGluZygpe3JldHVybiB0aGlzLl9lbmNvZGluZ31nZXQgZmF0YWwoKXtyZXR1cm4gdGhpcy5fZmF0YWx9Z2V0IGlnbm9yZUJPTSgpe3JldHVybiB0aGlzLl9pZ25vcmVCT019ZGVjb2RlKGUpe2lmKCFlKXJldHVybiIiO2xldCByPWUgaW5zdGFuY2VvZiBVaW50OEFycmF5P2U6ZSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyP25ldyBVaW50OEFycmF5KGUpOm5ldyBVaW50OEFycmF5KGUuYnVmZmVyLGUuYnl0ZU9mZnNldCxlLmJ5dGVMZW5ndGgpO2lmKHRoaXMuX2VuY29kaW5nPT09InV0Zi04IilyZXR1cm4gTXQocix0aGlzLl9mYXRhbCk7bGV0IG49dGhpcy5fZW5jb2Rpbmc9PT0idXRmLTE2bGUiLG89MDtpZihyLmxlbmd0aD49MiYmIXRoaXMuX2lnbm9yZUJPTSl7bGV0IGk9bj9yWzBdOnJbMV0scz0obj9yWzFdOnJbMF0pPDw4fGk7KHM9PT02NTI3OXx8cz09PTY1NTM0KSYmKG89Mil9cmV0dXJuIFd0KHIuc2xpY2Uobyksbix0aGlzLl9mYXRhbCl9fSx2PWNsYXNze19lbmNvZGluZztjb25zdHJ1Y3RvcihlKXt0aGlzLl9lbmNvZGluZz1zdChlKX1nZXQgZW5jb2RpbmcoKXtyZXR1cm4gdGhpcy5fZW5jb2Rpbmd9ZW5jb2RlKGUpe2lmKCFlKXJldHVybiBuZXcgVWludDhBcnJheSgwKTtpZih0aGlzLl9lbmNvZGluZz09PSJ1dGYtOCIpe2xldCBpPVtdO2ZvcihsZXQgYz0wO2M8ZS5sZW5ndGg7YysrKXtsZXQgcz1lLmNoYXJDb2RlQXQoYyk7aWYoczwxMjgpaS5wdXNoKHMpO2Vsc2UgaWYoczwyMDQ4KWkucHVzaCgxOTJ8cz4+NiwxMjh8cyY2Myk7ZWxzZSBpZihzPDU1Mjk2fHxzPj01NzM0NClpLnB1c2goMjI0fHM+PjEyLDEyOHxzPj42JjYzLDEyOHxzJjYzKTtlbHNle2MrKztsZXQgdT1lLmNoYXJDb2RlQXQoYyk7cz02NTUzNisoKHMmMTAyMyk8PDEwKXx1JjEwMjMsaS5wdXNoKDI0MHxzPj4xOCwxMjh8cz4+MTImNjMsMTI4fHM+PjYmNjMsMTI4fHMmNjMpfX1yZXR1cm4gbmV3IFVpbnQ4QXJyYXkoaSl9bGV0IHI9dGhpcy5fZW5jb2Rpbmc9PT0idXRmLTE2bGUiLG49bmV3IEFycmF5QnVmZmVyKGUubGVuZ3RoKjIpLG89bmV3IERhdGFWaWV3KG4pO2ZvcihsZXQgaT0wO2k8ZS5sZW5ndGg7aSsrKW8uc2V0VWludDE2KGkqMixlLmNoYXJDb2RlQXQoaSkscik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG4pfX07dHlwZW9mIGdsb2JhbFRoaXMuVGV4dERlY29kZXI+InUiJiYoZ2xvYmFsVGhpcy5UZXh0RGVjb2Rlcj1WKTt0eXBlb2YgZ2xvYmFsVGhpcy5UZXh0RW5jb2Rlcj4idSImJihnbG9iYWxUaGlzLlRleHRFbmNvZGVyPXYpO2ltcG9ydHtidWZmZXJQdHIgYXMgUnR9ZnJvbSJmZmkiO2ltcG9ydCphcyBjdCBmcm9tIm9zIjt2YXIga3Q9WyJ2b2lkIiwidTgiLCJpOCIsInUxNiIsImkxNiIsInUzMiIsImkzMiIsInU2NCIsImk2NCIsImYzMiIsImY2NCIsInB0ciJdLGo9L148KFtBLVphLXpfXVx3KnwpPnB0cighfEBbQS1aYS16X11cdyopPyQvO2Z1bmN0aW9uIE4odCl7cmV0dXJuIGoudGVzdCh0KX12YXIgdXQ9L148KFtBLVphLXpfXVx3Kik+JC87ZnVuY3Rpb24geSh0KXtyZXR1cm4gdXQudGVzdCh0KX1mdW5jdGlvbiBXKHQpe3JldHVybiB1dC5leGVjKHQpPy5bMV18fCIifWZ1bmN0aW9uIFgodCl7cmV0dXJuIGouZXhlYyh0KT8uWzFdfHwiIn12YXIgYXQ9dD0+e2lmKE4odCkpcmV0dXJuInB0ciI7aWYoeSh0KSl0aHJvdyBuZXcgRXJyb3IoYGZmaTogY1Rva2VuVG9UeXBlOiBieS12YWx1ZSB0b2tlbiAiJHt0fSIgaGFzIG5vIHNjYWxhciBzbG90IHR5cGVgKTtyZXR1cm4gdH0sRD1jdC5hcmNoPT09Ing2NCI/ODo0LFI9e3U4OjEsaTg6MSx1MTY6MixpMTY6Mix1MzI6NCxpMzI6NCx1NjQ6OCxpNjQ6OCxmMzI6NCxmNjQ6OH0sTz0wO2Z1bmN0aW9uIGsodCl7aWYoTih0KSl7bGV0IG89ai5leGVjKHQpLGk9bz8uWzFdfHwiIjtyZXR1cm4gbz8uWzJdPy5zdGFydHNXaXRoKCJAIik/YDwke2l9PnB0cmA6dH1pZih5KHQpKXJldHVybiB0O2xldCBlPXQuaW5kZXhPZigiQCIpLHI9ZT49MD90LnNsaWNlKDAsZSk6dDtpZigoZTwwfHwvXltBLVphLXpfXVx3KiQvLnRlc3QodC5zbGljZShlKzEpKSkmJnIhPT0icHRyIiYma3QuaW5jbHVkZXMocikpcmV0dXJuIHI7dGhyb3cgbmV3IEVycm9yKCJVbmtub3duIHRva2VuOiAiK3QpfWZ1bmN0aW9uIHoodCxlLHIpe3N3aXRjaChyKXtjYXNlInU4IjpyZXR1cm4gdC5nZXRVaW50OChlKTtjYXNlImk4IjpyZXR1cm4gdC5nZXRJbnQ4KGUpO2Nhc2UidTE2IjpyZXR1cm4gdC5nZXRVaW50MTYoZSwhMCk7Y2FzZSJpMTYiOnJldHVybiB0LmdldEludDE2KGUsITApO2Nhc2UidTMyIjpyZXR1cm4gdC5nZXRVaW50MzIoZSwhMCk7Y2FzZSJpMzIiOnJldHVybiB0LmdldEludDMyKGUsITApO2Nhc2UidTY0IjpyZXR1cm4gdC5nZXRCaWdVaW50NjQoZSwhMCk7Y2FzZSJpNjQiOnJldHVybiB0LmdldEJpZ0ludDY0KGUsITApO2Nhc2UiZjMyIjpyZXR1cm4gdC5nZXRGbG9hdDMyKGUsITApO2Nhc2UiZjY0IjpyZXR1cm4gdC5nZXRGbG9hdDY0KGUsITApO2Nhc2UicHRyIjpyZXR1cm4gRD09PTg/TnVtYmVyKHQuZ2V0QmlnSW50NjQoZSwhMCkpOnQuZ2V0SW50MzIoZSwhMCl9fWZ1bmN0aW9uIFoodCxlLHtrOnIsdjpufSl7c3dpdGNoKHIpe2Nhc2UidTgiOnQuc2V0VWludDgoZSxOdW1iZXIobikpO2JyZWFrO2Nhc2UiaTgiOnQuc2V0SW50OChlLE51bWJlcihuKSk7YnJlYWs7Y2FzZSJ1MTYiOnQuc2V0VWludDE2KGUsTnVtYmVyKG4pLCEwKTticmVhaztjYXNlImkxNiI6dC5zZXRJbnQxNihlLE51bWJlcihuKSwhMCk7YnJlYWs7Y2FzZSJ1MzIiOnQuc2V0VWludDMyKGUsbj4+PjAsITApO2JyZWFrO2Nhc2UiaTMyIjp0LnNldFVpbnQzMihlLG4+Pj4wLCEwKTticmVhaztjYXNlInU2NCI6dC5zZXRCaWdVaW50NjQoZSxuLCEwKTticmVhaztjYXNlImk2NCI6dC5zZXRCaWdJbnQ2NChlLG4sITApO2JyZWFrO2Nhc2UiZjMyIjp0LnNldEZsb2F0MzIoZSxuLCEwKTticmVhaztjYXNlImY2NCI6dC5zZXRGbG9hdDY0KGUsbiwhMCk7YnJlYWs7Y2FzZSJwdHIiOntpZihuPT1udWxsKXRocm93IG5ldyBFcnJvcigiZmZpOiBnb3QgbnVsbC91bmRlZmluZWQgZm9yIGEgcHRyIHNsb3Q7IHBhc3MgdGhlIGltcG9ydGVkIE5VTEwgY29uc3RhbnQgZm9yIGVtcHR5Iik7RD09PTg/dC5zZXRCaWdVaW50NjQoZSxCaWdJbnQuYXNVaW50Tig2NCxCaWdJbnQobikpLCEwKTp0LnNldFVpbnQzMihlLG4+Pj4wLCEwKTticmVha319fWZ1bmN0aW9uIF8odCxlLHIpe2xldHtrOm4sdjpvfT1yO2lmKG49PT0idTgifHxuPT09Imk4Inx8bj09PSJ1MTYifHxuPT09ImkxNiIpe3Quc2V0VWludDMyKGUsTnVtYmVyKG8pPj4+MCwhMCk7cmV0dXJufVoodCxlLHIpfXZhciB4PWNsYXNzIGV4dGVuZHMgQXJyYXlCdWZmZXJ7cHRyO2NvbnN0cnVjdG9yKGUpe3N1cGVyKGUpLHRoaXMucHRyPVJ0KHRoaXMpfX07ZnVuY3Rpb24gcSh0LGUpe3JldHVybiBlW3RdfXZhciBwdD1uZXcgTWFwO2Z1bmN0aW9uIF90KHQpe2xldCBlPXB0LmdldCh0KTtpZihlIT09dm9pZCAwKXJldHVybiBlO2xldCByPSQuTG9hZExpYnJhcnkodCk7aWYoIXIpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogTG9hZExpYnJhcnkoIiR7dH0iKSBmYWlsZWRgKTtyZXR1cm4gcHQuc2V0KHQscikscn1mdW5jdGlvbiBVdCh0KXtsZXQgZT10LnNwbGl0KCIgLT4gIik7aWYoZS5sZW5ndGghPT0yKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6IGludmFsaWQgc2lnbmF0dXJlICIke3R9IiAoZXhwZWN0ZWQgImFyZzEgYXJnMiAtPiByZXQiKWApO2xldCByPWVbMF0uc3BsaXQoIiAiKS5maWx0ZXIoaT0+aSE9PSIiKSxuPVtdO2ZvcihsZXQgaSBvZiByKXtsZXQgYz1rKGkpO2lmKGM9PT0idm9pZCIpdGhyb3cgbmV3IEVycm9yKCJWb2lkIGNhbiBub3QgaW4gYXJncyIpO24ucHVzaChjKX1sZXQgbz1rKGVbMV0pO2lmKHkobykpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogIiR7dH0iOiBieS12YWx1ZSBzdHJ1Y3QgYXQgdGhlIHJldHVybiBwb3NpdGlvbiAoPCR7VyhvKX0+KSBpcyBub3Qgc3VwcG9ydGVkIFx1MjAxNCBhcmd1bWVudCBwb3NpdGlvbnMgb25seTsgcGFzcyBhIHN0cnVjdCBvdXQgdGhyb3VnaCBhbiBvdXQtcGFyYW0gc2xvdCBpbnN0ZWFkICg8Tj5wdHIgKyBjYWxsZXIgYnVmZmVyKWApO3JldHVybnthcmdUb2tlbnM6bixyZXRUb2tlbjpvLHNpZzp0fX1mdW5jdGlvbiBCdCh0LGUscixuKXtsZXQgbz1VdChlKTtmb3IobGV0IGkgb2Ygby5hcmdUb2tlbnMpe2lmKCF5KGkpKWNvbnRpbnVlO2xldCBjPVcoaSkscz1xKGMscik7aWYoIXN8fHR5cGVvZiBzLmVuY29kZSE9ImZ1bmN0aW9uIil0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke2V9OiBieS12YWx1ZSBwb3NpdGlvbiA8JHtjfT4gaGFzIG5vIHJlZ2lzdGVyZWQgbGF5b3V0IChhdmFpbGFibGU6ICR7T2JqZWN0LmtleXMocikuam9pbigiLCAiKXx8Im5vbmUifSlgKTtpZih0eXBlb2Ygcy5zaXplIT0ibnVtYmVyInx8cy5zaXplPDEpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogJHtlfTogYnktdmFsdWUgcG9zaXRpb24gPCR7Y30+IHJlcXVpcmVzIGEgc3RydWN0IGxheW91dCB3aXRoIHNpemUgPj0gMSAoZ290ICR7cy5zaXplfTsgbm9uLXN0cnVjdCBjb2RlY3MgZXhwb3NlIG5vIHNpemUpYCl9cmV0dXJuKC4uLmkpPT56dCh0LG8saSxyLG4pfXZhciBIdD17dTg6NCxpODo0LHUxNjo0LGkxNjo0LHUzMjo0LGkzMjo0LHU2NDo4LGk2NDo4LGYzMjo0LGY2NDo4LHB0cjpEfSxmdD00O2Z1bmN0aW9uIHp0KHQse2FyZ1Rva2VuczplLHJldFRva2VuOnIsc2lnOm59LG8saSxjKXtsZXQgcz1kdC5hcmNoPT09Ing2NCIsdT0oYSxkKT0+e2lmKHkoYSkpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogZ2V0V2lkdGg6IGJ5LXZhbHVlIHRva2VuICIke2F9IiAoZGlzcGF0Y2hlZCBieSB3aWR0aE9mKWApO3JldHVybiBkPzg6TihhKT9EOkh0W2FdfSxwPWE9PntpZih5KGEpKXtpZihzKXJldHVybiA4O2xldCBkPXEoVyhhKSxpKTtpZighZCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiA8JHtXKGEpfT4gYnktdmFsdWUgcG9zaXRpb24gaGFzIG5vIHJlZ2lzdGVyZWQgbGF5b3V0YCk7bGV0IG09ZC5zaXplO3JldHVybiBtJTQ9PT0wP206bSs0LW0lNH1yZXR1cm4gdShhLHMpfSxoPTA7Zm9yKGxldCBhIG9mIGUpaCs9cChhKTtzJiZlLmxlbmd0aDxmdCYmKGg9ZnQqOCk7bGV0IEY9bmV3IEFycmF5QnVmZmVyKGgpLGc9bmV3IERhdGFWaWV3KEYpLFQ9W10sRT0wO2ZvcihsZXQgYT0wO2E8ZS5sZW5ndGg7YSsrKXtsZXQgZD1lW2FdLG09ZC5lbmRzV2l0aCgiISIpLGY9b1thXTtpZihOKGQpKXtsZXQgbD1YKGQpO2lmKHR5cGVvZiBmPT0ibnVtYmVyIil7aWYobSYmZj09PTApdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogJHtufTogYXJnIyR7YSsxfSA8JHtsfT5wdHIhIGdvdCAwIChudWxsIHBvaW50ZXIgZm9yYmlkZGVuIGhlcmU7IHRoZSB0b2tlbiBtYXJrcyB0aGlzIHBvc2l0aW9uIG5vbi1udWxsKWApO18oZyxFLHtrOiJwdHIiLHY6Zn0pfWVsc2V7aWYoZj09bnVsbCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiA8JHtsfT5wdHIgZ290ICR7U3RyaW5nKGYpfTsgcGFzcyB0aGUgaW1wb3J0ZWQgTlVMTCBjb25zdGFudCBmb3IgYW4gZW1wdHkgcG9pbnRlcmApO2xldCBJPWlbbF07aWYoIUkpdGhyb3cgbmV3IEVycm9yKGw9PT0iIj9gZmZpLWJpbmQ6IDw+cHRyIGV4cGVjdHMgbnVtYmVyIChOVUxMIHwgUHRyKSwgZ290ICR7dHlwZW9mIGZ9OyB1c2UgPEJZVEU+cHRyIHdpdGggYSBQdHJBcnJheUJ1ZmZlciAobmV3IFB0ckFycmF5QnVmZmVyKG4pKSwgb3IgZmZpLmJ1ZmZlclB0cihidWYpIGZvciBhbiBhZGRyZXNzYDpgZmZpLWJpbmQ6IHVua25vd24gbGF5b3V0ICI8JHtsfT5wdHIiIChhdmFpbGFibGU6ICR7T2JqZWN0LmtleXMoaSkuam9pbigiLCAiKXx8Im5vbmUifSlgKTtpZighSS5lbmNvZGUpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogPCR7bH0+cHRyIGhhcyBubyBlbmNvZGVyIChvdXQtb25seSBjb2RlYylgKTtsZXQgTD1JLmVuY29kZShmKTtULnB1c2goTCk7bGV0IEE9TC5wdHI7aWYodHlwZW9mIEEhPSJudW1iZXIiKXRocm93IG5ldyBFcnJvcigiZmZpLWJpbmQ6IGNvZGVjLmVuY29kZSBtdXN0IHJldHVybiBhIFB0ckFycmF5QnVmZmVyLCBnb3QgcGxhaW4gQXJyYXlCdWZmZXIiKTtpZihtJiZBPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke259OiBhcmcjJHthKzF9IDwke2x9PnB0ciEgZW5jb2RlIHByb2R1Y2VkIDAgKG51bGwgcG9pbnRlciBmb3JiaWRkZW4gaGVyZSlgKTtfKGcsRSx7azoicHRyIix2OkF9KX19ZWxzZSBpZih5KGQpKXtsZXQgbD1XKGQpLEk9cShsLGkpO2lmKCFJKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6ICR7bn06IGFyZyMke2ErMX0gPCR7bH0+IGJ5LXZhbHVlIHBvc2l0aW9uIGhhcyBubyByZWdpc3RlcmVkIGxheW91dGApO2lmKGY9PW51bGwpdGhyb3cgbmV3IEVycm9yKGBmZmktYmluZDogPCR7bH0+IHZhbHVlIHBvc2l0aW9uIGdvdCAke1N0cmluZyhmKX07IHBhc3MgYSBzdHJ1Y3Qgb2JqZWN0ICh1c2UgPCR7bH0+cHRyIHRvIHBhc3MgYSBwb2ludGVyKWApO2xldCBMPUkuc2l6ZTtpZighc3x8TDw9OCYmKEwmTC0xKT09PTApSS5lbmNvZGUoZixGLEUpO2Vsc2V7bGV0IEE9bmV3IEFycmF5QnVmZmVyKEwrMTUpLG90PUMuYnVmZmVyUHRyKEEpLGl0PSgxNi1vdCUxNiklMTY7SS5lbmNvZGUoZixBLGl0KSxULnB1c2goQSksXyhnLEUse2s6InB0ciIsdjpvdCtpdH0pfX1lbHNlIF8oZyxFLHtrOmQsdjpmfSk7RSs9cChkKX1sZXQgUD1uZXcgQXJyYXlCdWZmZXIoOCk7Qy5mZmlDYWxsKHQsRixQLHI9PT0iZjMyInx8cj09PSJmNjQiPzE6MCk7bGV0IFM9JHQoYXQociksUCk7aWYoci5lbmRzV2l0aCgiISIpJiZTPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1iaW5kOiAke259OiByZXR1cm4gJHtyfSBnb3QgMCAodGhlIHRva2VuIHByb21pc2VzIEMgbmV2ZXIgcmV0dXJucyBudWxsIGhlcmUpYCk7aWYoTihyKSYmUyE9PTApe2xldCBhPVgocik7aWYoYSE9PSIiKXtsZXQgZD1jW2FdO2lmKGQ/LmRlY29kZSlyZXR1cm4gZC5kZWNvZGUoUyl9fXJldHVybiBTfWZ1bmN0aW9uICR0KHQsZSl7aWYodCE9PSJ2b2lkIilyZXR1cm4geihuZXcgRGF0YVZpZXcoZSksMCx0KX12YXIgRz17ZW5jb2RlOnQ9PntsZXQgZT1uZXcgVGV4dEVuY29kZXIoInV0Zi0xNmxlIikuZW5jb2RlKHQrIlwwIikscj1uZXcgeChlLmJ5dGVMZW5ndGgpO3JldHVybiBuZXcgVWludDhBcnJheShyKS5zZXQoZSkscn0sZGVjb2RlOnQ9PntpZih0eXBlb2YgdD09Im51bWJlciIpe2xldCBvPSIiLGk9dCxjPWk7Zm9yKDs7KXtsZXQgcz1DLnJlYWRCeXRlKGkpLHU9Qy5yZWFkQnl0ZShpKzEpO2lmKHM9PT0wJiZ1PT09MClyZXR1cm4gbztpZihvKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHN8dTw8OCksaSs9MixpLWM+MTw8MjEpdGhyb3cgbmV3IEVycm9yKCJmZmktYmluZDogV0NIQVIgZGVjb2RlIGV4Y2VlZGVkIDRNaUIgd2l0aG91dCBOVUwiKX19bGV0IGU9bmV3IFVpbnQ4QXJyYXkodCkscj1lLmxlbmd0aCYtMixuPSIiO2ZvcihsZXQgbz0wO288cjtvKz0yKXtsZXQgaT1lW29dfGVbbysxXTw8ODtpZihpPT09MClyZXR1cm4gbjtuKz1TdHJpbmcuZnJvbUNoYXJDb2RlKGkpfXJldHVybiBufSxhbGxvYzoodD0yNTYpPT5uZXcgeCh0KjIpfSxHdD17ZW5jb2RlOnQ9PntpZighKHQgaW5zdGFuY2VvZiB4KSl0aHJvdyBuZXcgRXJyb3IoImZmaS1iaW5kOiA8QllURT5wdHIgd2FudHMgYSBQdHJBcnJheUJ1ZmZlciAobmV3IFB0ckFycmF5QnVmZmVyKG4pIC8gQllURS5hbGxvYyAvIHN0cnVjdC5lbmNvZGUpLCBub3QgYSBwbGFpbiBBcnJheUJ1ZmZlciIpO3JldHVybiB0fSxhbGxvYzp0PT5uZXcgeCh0KX0sbHQ9e1dDSEFSOkcsQllURTpHdH07ZnVuY3Rpb24gRXQodCxlLHIsbixvKXtsZXQgaT0kLkdldFByb2NBZGRyZXNzKF90KHQpLGUpO2lmKCFpKXRocm93IG5ldyBFcnJvcihgZmZpLWJpbmQ6IHByb2MgIiR7ZX0iIG5vdCBmb3VuZCBpbiAke3R9YCk7bGV0IGM9bz8/bjtyZXR1cm4gQnQoaSxyLHsuLi5sdCwuLi5ufSx7Li4ubHQsLi4uYz8/e319KX12YXIgZmU9bmV3IEZpbmFsaXphdGlvblJlZ2lzdHJ5KHQ9PnttdC5wcmludGYoYFtmZmldIGNsb3N1cmUgbGVha2VkIChHQ2VkIHdpdGhvdXQgZGlzcG9zZSk6IHNpZz0iJXMiIHB0cj0weCV4CmAsdC5zaWcsdC5wdHIpfSk7aW1wb3J0KmFzIGh0IGZyb20iZmZpIjtmdW5jdGlvbiBVKHQsZSl7cmV0dXJuIHQrZS0xJn4oZS0xKX12YXIgeHQ9dD0+Ult0XSE9PXZvaWQgMDtmdW5jdGlvbiBLKHQpe2lmKHR5cGVvZiB0PT0ic3RyaW5nIil7bGV0IGU9L14odTh8dTE2KVxbKFxkKylcXUAodXRmLTh8dXRmLTE2bGUpJC8uZXhlYyh0KTtpZihlKXtsZXQgYz1OdW1iZXIoZVsyXSk7aWYoIU51bWJlci5pc0ludGVnZXIoYyl8fGM8MSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IHN0cmluZyBsZW5ndGggbXVzdCBiZSBhbiBpbnRlZ2VyID49IDEsIGdvdCAke2N9YCk7bGV0IHM9ZVsxXT09PSJ1OCI/MToyO3JldHVybntzaXplOnMqYyxhbGlnbjpzLHR5cGU6e3RhZzoic3RyaW5nIixlbmNvZGluZzplWzNdfX19bGV0IHI9L14oW15cW1xdXSspXFsoXGQrKVxdJC8uZXhlYyh0KTtpZihyKXtsZXQgYz1OdW1iZXIoclsyXSk7aWYoIU51bWJlci5pc0ludGVnZXIoYyl8fGM8MSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGFycmF5IGxlbmd0aCBtdXN0IGJlIGFuIGludGVnZXIgPj0gMSwgZ290ICR7Y31gKTtsZXQgcz1LKHJbMV0pO2lmKHMudHlwZS50YWc9PT0iYml0ZmllbGQiKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGRzIGNhbm5vdCBiZSBhcnJheSBlbGVtZW50cyIpO3JldHVybntzaXplOnMuc2l6ZSpjLGFsaWduOnMuYWxpZ24sdHlwZTp7dGFnOiJhcnJheSIsZWxlbWVudFR5cGU6cy50eXBlLGVsZW1lbnRTaXplOnMuc2l6ZX19fWxldCBuPS9eKFtBLVphLXpfXVx3Kik6KFxkKykkLy5leGVjKHQpO2lmKG4pe2xldCBjPW5bMV0scz1rKGMpO2lmKCF4dChzKXx8cz09PSJmMzIifHxzPT09ImY2NCIpdGhyb3cgbmV3IEVycm9yKGBmZmktc3RydWN0OiBiaXRmaWVsZCB1bml0IG11c3QgYmUgYW4gaW50ZWdlciB0eXBlLCBnb3QgIiR7Y30iYCk7bGV0IHU9TnVtYmVyKG5bMl0pLHA9UltzXSxoPXAqODtpZighTnVtYmVyLmlzSW50ZWdlcih1KXx8dTwxKXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYml0ZmllbGQgd2lkdGggbXVzdCBiZSBhbiBpbnRlZ2VyID49IDEsIGdvdCAke3V9YCk7aWYodT5oKXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYml0ZmllbGQgd2lkdGggJHt1fSBleGNlZWRzIHVuaXQgd2lkdGggJHtofWApO3JldHVybntzaXplOnAsYWxpZ246cCx0eXBlOnt0YWc6ImJpdGZpZWxkIix1bml0OnMsYml0OjAsd2lkdGg6dX19fWxldCBvPWsodCk7aWYoTihvKSlyZXR1cm57c2l6ZTpELGFsaWduOkQsdHlwZTp7dGFnOiJiYXNpYyIsa2luZDoicHRyIn19O2lmKCF4dChvKSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IHVua25vd24ga2luZCAiJHt0fSJgKTtsZXQgaT1SW29dO3JldHVybntzaXplOmksYWxpZ246aSx0eXBlOnt0YWc6ImJhc2ljIixraW5kOm99fX1pZih0JiZ0eXBlb2YgdD09Im9iamVjdCIpe2xldCBlPXQscj1lWyIjIl07aWYocj09PXZvaWQgMCl0aHJvdyBuZXcgRXJyb3IoImZmaS1zdHJ1Y3Q6IG5lc3RlZCBvYmplY3QgdmFsdWUgcmVxdWlyZXMgYSAnIycga2V5ICgnc3RydWN0JyB8ICd1bmlvbicgfCAnYXJyYXknKSIpO2lmKHI9PT0iYXJyYXkiJiYiI3BhY2siaW4gZSl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6ICcjcGFjaycgaXMgb25seSBhbGxvd2VkIG9uIHN0cnVjdC91bmlvbiwgZ290ICcke3J9J2ApO2lmKHI9PT0iYXJyYXkiKXtsZXQgbj1lLmxlbmd0aDtpZighTnVtYmVyLmlzSW50ZWdlcihuKXx8bjwxKXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogYXJyYXkgbGVuZ3RoIG11c3QgYmUgYW4gaW50ZWdlciA+PSAxLCBnb3QgJHtTdHJpbmcobil9YCk7bGV0IG89SyhlLmVsZW1lbnQpO2lmKG8udHlwZS50YWc9PT0iYml0ZmllbGQiKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGRzIGNhbm5vdCBiZSBhcnJheSBlbGVtZW50cyIpO3JldHVybntzaXplOm8uc2l6ZSpuLGFsaWduOm8uYWxpZ24sdHlwZTp7dGFnOiJhcnJheSIsZWxlbWVudFR5cGU6by50eXBlLGVsZW1lbnRTaXplOm8uc2l6ZX19fWlmKHI9PT0ic3RydWN0Inx8cj09PSJ1bmlvbiIpe2xldCBuPXd0KHQpO3JldHVybntzaXplOm4uc2l6ZSxhbGlnbjpuLm1heEVmZmVjdGl2ZUFsaWduLHR5cGU6e3RhZzpyLGZpZWxkczpuLmZpZWxkc319fXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogdW5rbm93biAnIycgZGVjbGFyYXRpb24gJHtKU09OLnN0cmluZ2lmeShTdHJpbmcocikpfWApfXRocm93IG5ldyBFcnJvcihgZmZpLXN0cnVjdDogaW52YWxpZCBtZW1iZXIgdmFsdWU6ICR7U3RyaW5nKHQpfWApfWZ1bmN0aW9uIHd0KHQpe2xldCBlPXRbIiMiXT09PSJzdHJ1Y3QiLHI9dFsiI3BhY2siXT8/OCxuPTEsbz0wLGk9W10sYz0wLHM9LTEsdT0wLHA9MCxoPSgpPT57czwwfHwoYz1VKHMrTWF0aC5jZWlsKHUvOCkscCkscz0tMSl9O2ZvcihsZXRbRixnXW9mIE9iamVjdC5lbnRyaWVzKHQpKXtpZihGLnN0YXJ0c1dpdGgoIiMiKSljb250aW51ZTtsZXQgVD0vXihbXkBdKylAKFxkKykkLy5leGVjKEYpLEU9VD9UWzFdOkYsUD1UP051bWJlcihUWzJdKTowLHtzaXplOncsYWxpZ246Uyx0eXBlOmF9PUsoZyksZD10eXBlb2YgZz09InN0cmluZyImJmcuZW5kc1dpdGgoIiEiKSxtPVM7aWYocj4wJiYobT1NYXRoLm1pbihyLG0pKSxQJiYobT1NYXRoLm1heChtLFApKSxhLnRhZz09PSJiaXRmaWVsZCIpe2lmKEUuc3RhcnRzV2l0aCgiJCIpKXRocm93IG5ldyBFcnJvcigiZmZpLXN0cnVjdDogYml0ZmllbGQgbWVtYmVycyBtdXN0IGJlIG5hbWVkIik7aWYoIWUpe2kucHVzaCh7bmFtZTpFLG9mZnNldDowLHNpemU6dyx0eXBlOnsuLi5hLGJpdDowfX0pLG49TWF0aC5tYXgobixtKSxvPU1hdGgubWF4KG8sdyk7Y29udGludWV9bGV0IGw9YS53aWR0aDsoczwwfHx3IT09cHx8dStsPnAqOCkmJihzPj0wJiZoKCkscz1VKGMsbSksdT0wLHA9dyksaS5wdXNoKHtuYW1lOkUsb2Zmc2V0OnMsc2l6ZTp3LHR5cGU6ey4uLmEsYml0OnV9fSksdSs9bCxuPU1hdGgubWF4KG4sbSksbz1NYXRoLm1heChvLHcpO2NvbnRpbnVlfWgoKTtsZXQgZj1VKGMsbSk7aWYoIUUuc3RhcnRzV2l0aCgiJCIpKWkucHVzaCh7bmFtZTpFLG9mZnNldDpmLHNpemU6dyx0eXBlOmEsLi4uZD97bm9ubnVsbDohMH06e319KTtlbHNle2lmKGEudGFnIT09InN0cnVjdCImJmEudGFnIT09InVuaW9uIil0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGFub255bW91cyBtZW1iZXIgIiR7RX0iIG11c3QgYmUgYSBzdHJ1Y3QvdW5pb25gKTtmb3IobGV0IGwgb2YgYS5maWVsZHMpaS5wdXNoKHsuLi5sLG9mZnNldDpsLm9mZnNldCtmfSl9ZSYmKGM9Zit3KSxuPU1hdGgubWF4KG4sbSksbz1NYXRoLm1heChvLHcpfXJldHVybiBoKCkse3NpemU6VShlP2M6byxuKSxtYXhFZmZlY3RpdmVBbGlnbjpuLGZpZWxkczppfX1mdW5jdGlvbiBndCh0LGUscil7bGV0IG49UltyXTtyZXR1cm4gbj09PTE/QmlnSW50KHQuZ2V0VWludDgoZSkpOm49PT0yP0JpZ0ludCh0LmdldFVpbnQxNihlLCEwKSk6bj09PTQ/QmlnSW50KHQuZ2V0VWludDMyKGUsITApKTp0LmdldEJpZ1VpbnQ2NChlLCEwKX1mdW5jdGlvbiBZdCh0LGUscixuKXtsZXQgbz1SW3JdO2lmKG89PT0xKXt0LnNldFVpbnQ4KGUsTnVtYmVyKG4mMHhmZm4pKTtyZXR1cm59aWYobz09PTIpe3Quc2V0VWludDE2KGUsTnVtYmVyKG4mMHhmZmZmbiksITApO3JldHVybn1pZihvPT09NCl7dC5zZXRVaW50MzIoZSxOdW1iZXIobiYweGZmZmZmZmZmbiksITApO3JldHVybn10LnNldEJpZ1VpbnQ2NChlLG4mMHhmZmZmZmZmZmZmZmZmZmZmbiwhMCl9ZnVuY3Rpb24gVnQodCxlLHIpe2xldCBuPUJpZ0ludChyLndpZHRoKSxvPWd0KHQsZSxyLnVuaXQpPj5CaWdJbnQoci5iaXQpJigxbjw8biktMW47cmV0dXJuIHIudW5pdFswXT09PSJpIiYmbyYxbjw8bi0xbiYmKG8tPTFuPDxuKSxyLndpZHRoPjUzP286TnVtYmVyKG8pfWZ1bmN0aW9uIHZ0KHQsZSxyLG4pe2xldCBvPUJpZ0ludChyLndpZHRoKSxpPUJpZ0ludChyLmJpdCksYz0oMW48PG8pLTFuLHM9Yzw8aSx1PWd0KHQsZSxyLnVuaXQpLHA9KHR5cGVvZiBuPT0iYmlnaW50Ij9uOkJpZ0ludChNYXRoLnRydW5jKG4pKSkmYztZdCh0LGUsci51bml0LHUmfnN8cDw8aSl9dmFyIGp0PXsidXRmLTgiOm5ldyBUZXh0RW5jb2RlcigidXRmLTgiKSwidXRmLTE2bGUiOm5ldyBUZXh0RW5jb2RlcigidXRmLTE2bGUiKX0sWHQ9eyJ1dGYtOCI6bmV3IFRleHREZWNvZGVyKCJ1dGYtOCIse2lnbm9yZUJPTTohMH0pLCJ1dGYtMTZsZSI6bmV3IFRleHREZWNvZGVyKCJ1dGYtMTZsZSIse2lnbm9yZUJPTTohMH0pfTtmdW5jdGlvbiBadCh0LGUscixuKXtsZXQgbz1uZXcgVWludDhBcnJheSh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQrZSxyKSxpPW49PT0idXRmLTE2bGUiPzI6MSxjPXI7Zm9yKGxldCBzPTA7cytpPD1yO3MrPWkpaWYob1tzXT09PTAmJihpPT09MXx8b1tzKzFdPT09MCkpe2M9czticmVha31yZXR1cm4gWHRbbl0uZGVjb2RlKG8uc3ViYXJyYXkoMCxjKSl9ZnVuY3Rpb24gcXQodCxlLHIsbixvKXtsZXQgaT1uZXcgVWludDhBcnJheSh0LmJ1ZmZlcix0LmJ5dGVPZmZzZXQrZSxyKTtpLmZpbGwoMCk7bGV0IHM9ci0obj09PSJ1dGYtMTZsZSI/MjoxKTtpZihzPD0wKXJldHVybjtsZXQgdT1qdFtuXS5lbmNvZGUoU3RyaW5nKG8/PyIiKSk7aS5zZXQodS5zdWJhcnJheSgwLE1hdGgubWluKHUubGVuZ3RoLHMpKSl9ZnVuY3Rpb24gS3QodCxlLHIsbil7bGV0IG89bi5lbGVtZW50U2l6ZT4wP3Ivbi5lbGVtZW50U2l6ZTowLGk9W107Zm9yKGxldCBjPTA7YzxvO2MrKylpLnB1c2goVHQodCxlK2Mqbi5lbGVtZW50U2l6ZSxuLmVsZW1lbnRUeXBlLG4uZWxlbWVudFNpemUpKTtyZXR1cm4gaX1mdW5jdGlvbiBRdCh0LGUscixuLG8pe2xldCBpPW4uZWxlbWVudFNpemU+MD9yL24uZWxlbWVudFNpemU6MCxjPW8/P1tdO2ZvcihsZXQgcz0wO3M8aTtzKyspRnQodCxlK3Mqbi5lbGVtZW50U2l6ZSxuLmVsZW1lbnRUeXBlLG4uZWxlbWVudFNpemUsY1tzXSl9ZnVuY3Rpb24gVHQodCxlLHIsbil7c3dpdGNoKHIudGFnKXtjYXNlImJhc2ljIjpyZXR1cm4geih0LGUsci5raW5kKTtjYXNlImJpdGZpZWxkIjpyZXR1cm4gVnQodCxlLHIpO2Nhc2Uic3RyaW5nIjpyZXR1cm4gWnQodCxlLG4sci5lbmNvZGluZyk7Y2FzZSJzdHJ1Y3QiOmNhc2UidW5pb24iOnJldHVybiBRKHQsZSxyLmZpZWxkcyk7Y2FzZSJhcnJheSI6cmV0dXJuIEt0KHQsZSxuLHIpfX1mdW5jdGlvbiBGdCh0LGUscixuLG8pe3N3aXRjaChyLnRhZyl7Y2FzZSJiYXNpYyI6Wih0LGUse2s6ci5raW5kLHY6b30pO2JyZWFrO2Nhc2UiYml0ZmllbGQiOnZ0KHQsZSxyLG8/PzApO2JyZWFrO2Nhc2Uic3RyaW5nIjpxdCh0LGUsbixyLmVuY29kaW5nLG8pO2JyZWFrO2Nhc2Uic3RydWN0IjpjYXNlInVuaW9uIjpTdCh0LGUsci5maWVsZHMsbz8/e30pO2JyZWFrO2Nhc2UiYXJyYXkiOlF0KHQsZSxuLHIsbyk7YnJlYWt9fWZ1bmN0aW9uIFEodCxlLHIpe2xldCBuPXt9O2ZvcihsZXQgbyBvZiByKXtsZXQgaT1UdCh0LGUrby5vZmZzZXQsby50eXBlLG8uc2l6ZSk7aWYoby5ub25udWxsJiZpPT09MCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IGRlY29kZTogJyEnIGZpZWxkICIke28ubmFtZX0iIGdvdCAwIChDIGRpZCBub3QgZmlsbCBpdCwgb3IgZGVjb2RlIHdhcyBjYWxsZWQgb24gYW4gdW5maWxsZWQgc2xvdClgKTtuW28ubmFtZV09aX1yZXR1cm4gbn1mdW5jdGlvbiBTdCh0LGUscixuKXtmb3IobGV0IG8gb2YgciluW28ubmFtZV0hPT12b2lkIDAmJkZ0KHQsZStvLm9mZnNldCxvLnR5cGUsby5zaXplLG5bby5uYW1lXSl9ZnVuY3Rpb24gSnQodCl7bGV0e2ZpZWxkczplLHNpemU6cixtYXhFZmZlY3RpdmVBbGlnbjpufT13dCh0KTtyZXR1cm57ZmllbGRzOmUsc2l6ZTpyLHN0cnVjdEFsaWduOm4sZGVjb2RlOm89PlEodHlwZW9mIG89PSJudW1iZXIiP25ldyBEYXRhVmlldyhodC5yZWFkQnl0ZXMobyxyKSk6bmV3IERhdGFWaWV3KG8pLDAsZSksYWxsb2M6KG89PntpZihvIT09dm9pZCAwJiYoIU51bWJlci5pc0ludGVnZXIobyl8fG88MSkpdGhyb3cgbmV3IEVycm9yKCJmZmktc3RydWN0OiBhbGxvYyhuKSByZXF1aXJlcyBhbiBpbnRlZ2VyIG4gPj0gMSAoUEFCKDApIG5ldmVyIGVzY2FwZXMgXHUyMDE0IHBhc3MgTlVMTCBmb3IgYW4gZW1wdHkgcG9pbnRlciBwb3NpdGlvbikiKTtyZXR1cm4gbmV3IHgocioobz8/MSkpfSksZW5jb2RlOigobyxpLGMpPT57aWYobz09bnVsbCl0aHJvdyBuZXcgRXJyb3IoImZmaS1zdHJ1Y3Q6IGVuY29kZSh2KSByZXF1aXJlcyBhbiBhcmd1bWVudDsgdXNlIGFsbG9jKCkgZm9yIGEgemVyb2VkIG91dC1wYXJhbSBzbG90Iik7bGV0IHM9aT8/bmV3IHgocik7cmV0dXJuIFN0KG5ldyBEYXRhVmlldyhzKSxjPz8wLGUsbyksc30pLG9mZnNldE9mOm89Pntmb3IobGV0IGkgb2YgZSlpZihpLm5hbWU9PT1vKXJldHVybiBpLm9mZnNldDt0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6IG5vIGZpZWxkICIke299ImApfX19ZnVuY3Rpb24gdGUodCxlLHIpe2xldCBuPWVbIiMiXTtpZihuIT09dm9pZCAwJiZuIT09dCl0aHJvdyBuZXcgRXJyb3IoYGZmaS1zdHJ1Y3Q6ICR7dH0oKSByZWNlaXZlZCBhICcke1N0cmluZyhuKX0nIGRlY2xhcmF0aW9uIChraW5kIG1pc21hdGNoIFx1MjAxNCB1c2UgJHtufSgpIGZvciBpdClgKTtsZXQgbz1lWyIjcGFjayJdO2lmKHI9PT12b2lkIDAmJm8hPT12b2lkIDApcj1vO2Vsc2UgaWYociE9PXZvaWQgMCYmbyE9PXZvaWQgMCYmciE9PW8pdGhyb3cgbmV3IEVycm9yKGBmZmktc3RydWN0OiAjcGFjayBjb25mbGljdDogb3B0cy5wYWNrPSR7cn0gdnMgZGVjbGFyYXRpb24gJHtTdHJpbmcobyl9YCk7bGV0IGk9eyIjIjp0fTtyIT09dm9pZCAwJiYoaVsiI3BhY2siXT1yKTtmb3IobGV0W2Msc11vZiBPYmplY3QuZW50cmllcyhlKSljLnN0YXJ0c1dpdGgoIiMiKXx8KGlbY109cyk7cmV0dXJuIGl9ZnVuY3Rpb24gQih0LGUscil7bGV0IG49dHlwZW9mIHQ9PSJzdHJpbmciO3JldHVybiBKdCh0ZSgic3RydWN0IixuP2U6dCwobj9yOmUpPy5wYWNrKSl9dmFyIGVlPXsiIyI6InN0cnVjdCIsY2I6InUzMiIsbHBSZXNlcnZlZDoiPD5wdHIiLGxwRGVza3RvcDoiPD5wdHIiLGxwVGl0bGU6Ijw+cHRyIixkd1g6InUzMiIsZHdZOiJ1MzIiLGR3WFNpemU6InUzMiIsZHdZU2l6ZToidTMyIixkd1hDb3VudENoYXJzOiJ1MzIiLGR3WUNvdW50Q2hhcnM6InUzMiIsZHdGaWxsQXR0cmlidXRlOiJ1MzIiLGR3RmxhZ3M6InUzMiIsd1Nob3dXaW5kb3c6InUxNkBTaG93V2luZG93Q21kIixjYlJlc2VydmVkMjoidTE2IixscFJlc2VydmVkMjoiPD5wdHIiLGhTdGRJbnB1dDoiPEhGSUxFPnB0ciIsaFN0ZE91dHB1dDoiPEhGSUxFPnB0ciIsaFN0ZEVycm9yOiI8SEZJTEU+cHRyIn0sWT1CKCJTVEFSVFVQSU5GT1ciLGVlKSxyZT17IiMiOiJzdHJ1Y3QiLGhQcm9jZXNzOiI8SFBST0NFU1M+cHRyISIsaFRocmVhZDoiPEhUSFJFQUQ+cHRyISIsZHdQcm9jZXNzSWQ6InUzMiIsZHdUaHJlYWRJZDoidTMyIn0sSj1CKCJQUk9DRVNTX0lORk9STUFUSU9OIixyZSk7dmFyIGI9KHQsZSxyKT0+RXQoImtlcm5lbDMyLmRsbCIsdCxlLHIpLEl0PWIoIkNyZWF0ZVBpcGUiLCI8PnB0ciA8PnB0ciA8PnB0ciB1MzIgLT4gaTMyIiksdHQ9YigiU2V0SGFuZGxlSW5mb3JtYXRpb24iLCI8SEZJTEU+cHRyISB1MzIgdTMyIC0+IGkzMiIpLEN0PWIoIkNyZWF0ZVByb2Nlc3NXIiwiPFdDSEFSPnB0ciA8V0NIQVI+cHRyIDw+cHRyIDw+cHRyIGkzMiB1MzIgPD5wdHIgPFdDSEFSPnB0ciA8U1RBUlRVUElORk9XPnB0ciA8UFJPQ0VTU19JTkZPUk1BVElPTj5wdHIgLT4gaTMyIix7U1RBUlRVUElORk9XOll9KSxidD1iKCJXYWl0Rm9yU2luZ2xlT2JqZWN0IiwiPD5wdHIgdTMyIC0+IHUzMiIpLE50PWIoIkdldEV4aXRDb2RlUHJvY2VzcyIsIjxIUFJPQ0VTUz5wdHIhIDxCWVRFPnB0ciAtPiBpMzIiKSxNPWIoIkNsb3NlSGFuZGxlIiwiPD5wdHIgLT4gaTMyIik7dmFyIHl0PWIoIlJlYWRGaWxlIiwiPEhGSUxFPnB0ciEgPEJZVEU+cHRyIHUzMiA8QllURT5wdHIgPD5wdHIgLT4gaTMyIik7dmFyIGV0PWIoIkdldExhc3RFcnJvciIsIiAtPiB1MzIiKSxEdD1iKCJHZXRTeXN0ZW1EaXJlY3RvcnlXIiwiPEJZVEU+cHRyIHUzMiAtPiB1MzIiKTt2YXIgbmU9dD0+e3RyeXtsZXQgZT1QdC5vcGVuKCJkaWFnLmxvZyIsImEiKTtlJiYoZS5wdXRzKGAke0RhdGUubm93KCl9ICR7dH0KYCksZS5jbG9zZSgpKX1jYXRjaHt9fSxydD0xLG9lPTI1NixpZT00Mjk0OTY3Mjk1LEg9T3QuV29ya2VyLnBhcmVudCxMdD0iQzpcXFdpbmRvd3NcXFN5c3RlbTMyIjt0cnl7bGV0IHQ9Ry5hbGxvYygyNTYpLHI9RHQodCwyNTYpPjA/Ry5kZWNvZGUodCk6IiI7ciYmKEx0PXIpfWNhdGNoKHQpe25lKCJTWVMtRElSLUZBSUw6ICIrU3RyaW5nKHQpKX12YXIgbnQ9QigiUElQRV9IQU5ETEVTIix7aFJlYWQ6IjxIRklMRT5wdHIhIixoV3JpdGU6IjxIRklMRT5wdHIhIn0pO2Z1bmN0aW9uIHNlKHQsZSl7bGV0IHI9bnQuYWxsb2MoKTtpZighSXQoci5wdHIsci5wdHIrbnQub2Zmc2V0T2YoImhXcml0ZSIpLE8sMCkpdGhyb3cgbmV3IEVycm9yKCJDcmVhdGVQaXBlIGVycj0iK2V0KCkpO2xldHtoUmVhZDpuLGhXcml0ZTpvfT1udC5kZWNvZGUocik7dHQobyxydCxydCksdHQobixydCwwKTtsZXQgaT1KLmFsbG9jKCksYz1gJHtMdH1cXGNtZC5leGUgL3UgL2MgJHtlfWA7aWYoIUN0KE8sYyxPLE8sMSwwLE8sTyx7Y2I6WS5zaXplLGR3RmxhZ3M6b2UsaFN0ZE91dHB1dDpvLGhTdGRFcnJvcjpvfSxpLnB0cikpdGhyb3cgTShuKSxNKG8pLG5ldyBFcnJvcigiQ3JlYXRlUHJvY2Vzc1cgZXJyPSIrZXQoKSsiIGNtZD0iK2MpO2xldHtoUHJvY2VzczpzLGhUaHJlYWQ6dSxkd1Byb2Nlc3NJZDpwfT1KLmRlY29kZShpKTtNKHUpLE0obyksSC5wb3N0TWVzc2FnZSh7dHlwZToiaW5mbyIsaWQ6dCxwaWQ6cH0pO2xldCBoPW5ldyB4KDQwOTYpLEY9bmV3IFVpbnQ4QXJyYXkoaCksZz1uZXcgeCg0KSxUPW5ldyBVaW50MzJBcnJheShnKTtmb3IoO1RbMF09MCwhIXl0KG4saCw0MDk2LGcsTyk7KXtsZXQgUz1UWzBdO2lmKFM9PT0wKWJyZWFrO0gucG9zdE1lc3NhZ2Uoe3R5cGU6ImRhdGEiLGlkOnQsY2h1bms6Ri5zbGljZSgwLFMpfSl9YnQocyxpZSk7bGV0IEU9bmV3IHgoNCksUD1uZXcgSW50MzJBcnJheShFKTtOdChzLEUpO2xldCB3PVBbMF07cmV0dXJuIE0obiksTShzKSx3fUgub25tZXNzYWdlPXQ9PntsZXQgZT10LmRhdGE7aWYoZS50eXBlPT09InJ1biImJnR5cGVvZiBlLmNtZD09InN0cmluZyIpe2xldCByPS0xLG49bnVsbDt0cnl7cj1zZShlLmlkLGUuY21kKX1jYXRjaChvKXtuPVN0cmluZyhvKX1ILnBvc3RNZXNzYWdlKHt0eXBlOiJyZXN1bHQiLGlkOmUuaWQsY29kZTpyLGVycm9yOm59KX1ILm9ubWVzc2FnZT1udWxsfTsK");
|
|
22049
22295
|
bumpWorkers(1);
|
|
22050
22296
|
const id = 1;
|
|
22051
22297
|
let innerPid = null;
|
|
@@ -22076,7 +22322,7 @@ function runInWorker(cmd, signal, timeoutMs) {
|
|
|
22076
22322
|
return;
|
|
22077
22323
|
settled = true;
|
|
22078
22324
|
if (timer !== null)
|
|
22079
|
-
|
|
22325
|
+
os7.clearTimeout(timer);
|
|
22080
22326
|
worker.onmessage = null;
|
|
22081
22327
|
bumpWorkers(-1);
|
|
22082
22328
|
fn();
|
|
@@ -22103,7 +22349,7 @@ function runInWorker(cmd, signal, timeoutMs) {
|
|
|
22103
22349
|
killOnAbort();
|
|
22104
22350
|
}
|
|
22105
22351
|
if (timeoutMs != null && timeoutMs > 0) {
|
|
22106
|
-
timer =
|
|
22352
|
+
timer = os7.setTimeout(() => {
|
|
22107
22353
|
finish(() => {
|
|
22108
22354
|
kill();
|
|
22109
22355
|
resolveTrailers({ "X-Exit-Code": "-1" });
|
|
@@ -22382,35 +22628,35 @@ function listWindows() {
|
|
|
22382
22628
|
var DISP_CHANGE_NAME = {
|
|
22383
22629
|
[
|
|
22384
22630
|
0
|
|
22385
|
-
/*
|
|
22631
|
+
/* DisplayChangeResult.SUCCESSFUL */
|
|
22386
22632
|
]: "SUCCESSFUL",
|
|
22387
22633
|
[
|
|
22388
22634
|
1
|
|
22389
|
-
/*
|
|
22635
|
+
/* DisplayChangeResult.RESTART */
|
|
22390
22636
|
]: "RESTART",
|
|
22391
22637
|
[
|
|
22392
22638
|
-1
|
|
22393
|
-
/*
|
|
22639
|
+
/* DisplayChangeResult.FAILED */
|
|
22394
22640
|
]: "FAILED",
|
|
22395
22641
|
[
|
|
22396
22642
|
-2
|
|
22397
|
-
/*
|
|
22643
|
+
/* DisplayChangeResult.BADMODE */
|
|
22398
22644
|
]: "BADMODE",
|
|
22399
22645
|
[
|
|
22400
22646
|
-3
|
|
22401
|
-
/*
|
|
22647
|
+
/* DisplayChangeResult.NOTUPDATED */
|
|
22402
22648
|
]: "NOTUPDATED",
|
|
22403
22649
|
[
|
|
22404
22650
|
-4
|
|
22405
|
-
/*
|
|
22651
|
+
/* DisplayChangeResult.BADFLAGS */
|
|
22406
22652
|
]: "BADFLAGS",
|
|
22407
22653
|
[
|
|
22408
22654
|
-5
|
|
22409
|
-
/*
|
|
22655
|
+
/* DisplayChangeResult.BADPARAM */
|
|
22410
22656
|
]: "BADPARAM",
|
|
22411
22657
|
[
|
|
22412
22658
|
-6
|
|
22413
|
-
/*
|
|
22659
|
+
/* DisplayChangeResult.BADDUALVIEW */
|
|
22414
22660
|
]: "BADDUALVIEW"
|
|
22415
22661
|
};
|
|
22416
22662
|
function dispChangeName(ret) {
|
|
@@ -22419,10 +22665,10 @@ function dispChangeName(ret) {
|
|
|
22419
22665
|
function currentScreen() {
|
|
22420
22666
|
return GetSystemMetrics(
|
|
22421
22667
|
0
|
|
22422
|
-
/*
|
|
22668
|
+
/* SysMetrics.CXSCREEN */
|
|
22423
22669
|
) + "x" + GetSystemMetrics(
|
|
22424
22670
|
1
|
|
22425
|
-
/*
|
|
22671
|
+
/* SysMetrics.CYSCREEN */
|
|
22426
22672
|
);
|
|
22427
22673
|
}
|
|
22428
22674
|
function listModes32() {
|
|
@@ -22456,7 +22702,7 @@ function applyDisplayMode(w2, h2, persist) {
|
|
|
22456
22702
|
const testRet = ChangeDisplaySettings(
|
|
22457
22703
|
dm.ptr,
|
|
22458
22704
|
2
|
|
22459
|
-
/*
|
|
22705
|
+
/* ChangeDisplayFlag.TEST */
|
|
22460
22706
|
);
|
|
22461
22707
|
if (testRet !== 0) {
|
|
22462
22708
|
return {
|
|
@@ -22473,7 +22719,7 @@ function applyDisplayMode(w2, h2, persist) {
|
|
|
22473
22719
|
ret = ChangeDisplaySettings(
|
|
22474
22720
|
dm.ptr,
|
|
22475
22721
|
1
|
|
22476
|
-
/*
|
|
22722
|
+
/* ChangeDisplayFlag.UPDATEREGISTRY */
|
|
22477
22723
|
);
|
|
22478
22724
|
}
|
|
22479
22725
|
return { before, after: currentScreen(), testRet, ret, retName: dispChangeName(ret), modes32: listModes32() };
|
|
@@ -22486,16 +22732,87 @@ API\uFF08\u914D\u7F6E token \u540E\u9700 Authorization: Bearer <token>\uFF0C\u67
|
|
|
22486
22732
|
\uFF08X-Dimensions\uFF1B\u4E0D\u5E26 hwnd = \u6574\u5C4F BitBlt\uFF1B\u5E26 hwnd \u9ED8\u8BA4 mode=print
|
|
22487
22733
|
\u8BA9\u7A97\u53E3\u81EA\u7ED8\u2014\u2014\u906E\u6321/\u6700\u5C0F\u5316/\u8D85\u5C4F\u4E5F\u62FF\u5B8C\u6574\u50CF\u7D20\uFF0Cscreen \u53EA\u622A\u53EF\u89C1\u90E8\u5206\uFF09
|
|
22488
22734
|
GET /window_list \u2192 JSON \u7A97\u53E3\u5217\u8868 [{hwnd,title,className,...}]
|
|
22735
|
+
GET /tray_list \u2192 JSON {icons:[{area,index,hWnd,uID,tooltip,rect}]}\uFF08\u8DE8\u8FDB\u7A0B\u679A\u4E3E
|
|
22736
|
+
explorer toolbar\uFF1A\u53EF\u89C1\u533A Shell_TrayWnd + \u6298\u53E0\u533A NotifyIconOverflowWindow\uFF1B
|
|
22737
|
+
rect \u5C4F\u5E55\u7269\u7406\u50CF\u7D20\uFF0C\u5168 0 \u2192 null\uFF1B\u6298\u53E0\u9762\u677F\u672A\u5C55\u5F00\u65F6 overflow \u533A rect
|
|
22738
|
+
\u4EC5\u5F53\u5C55\u5F00\u540E\u53EF\u9760\uFF09\uFF1B?probe=<hwnd>&uid=<n> \u2192 \u9644 probe {hr,hrName,rect}
|
|
22739
|
+
\uFF08\u5355\u56FE\u6807 Shell_NotifyIconGetRect\uFF0CWin7+\uFF1A0=found \u9644\u5BB9\u5668 rect / 1=hidden
|
|
22740
|
+
/ E_FAIL=\u4E0D\u5B58\u5728\u6216 GUID \u56FE\u6807\uFF1BXP \u65E0\u6B64 API \u2192 unsupported\uFF09
|
|
22489
22741
|
POST /set_resolution ?w=<px>&h=<px>&persist=0|1\uFF08\u9ED8\u8BA4 1 = \u5199\u6CE8\u518C\u8868\u8DE8\u91CD\u542F\uFF09\u2192 JSON
|
|
22490
22742
|
{before,after,testRet,ret,retName,modes32}\uFF1Bmodes32 \u6052\u5E26 32bpp
|
|
22491
|
-
\u53EF\u7528\u6A21\u5F0F\uFF08\u975E\u6CD5\u5BBD\u9AD8\u4F1A\u4EE5 BADMODE \u62D2\u7EDD\u5E76\u7ED9\u672C\u5217\u8868\uFF09
|
|
22743
|
+
\u53EF\u7528\u6A21\u5F0F\uFF08\u975E\u6CD5\u5BBD\u9AD8\u4F1A\u4EE5 BADMODE \u62D2\u7EDD\u5E76\u7ED9\u672C\u5217\u8868\uFF09
|
|
22744
|
+
POST /input body = JSON \u6570\u7EC4\uFF08\u6279\u91CF\u6CE8\u5165\uFF1Bx/y \u7269\u7406\u50CF\u7D20\uFF09\uFF1A
|
|
22745
|
+
{"t":"move","x":,"y":} | {"t":"down|up","btn":"left|right|middle|x1|x2","x":,"y":?} |
|
|
22746
|
+
{"t":"key","key":"a|enter|0x41","up":true?} | {"t":"sleep","ms":0..5000}
|
|
22747
|
+
\u2192 JSON {sent,expected}\uFF1B\u6309 sleep \u5207\u6BB5\uFF0C\u6BB5\u5185\u4E00\u6B21 SendInput \u539F\u5B50\u6CE8\u5165`;
|
|
22492
22748
|
function usageResponse() {
|
|
22493
22749
|
return new Response(USAGE, { headers: { "Content-Type": "text/plain; charset=utf-8" } });
|
|
22494
22750
|
}
|
|
22751
|
+
var INPUT_MOUSE = 0;
|
|
22752
|
+
var INPUT_KEYBOARD = 1;
|
|
22753
|
+
var MOUSEEVENTF_MOVE = 1;
|
|
22754
|
+
var MOUSEEVENTF_ABSOLUTE = 32768;
|
|
22755
|
+
var KEYEVENTF_KEYUP = 2;
|
|
22756
|
+
var MOUSE_BTNS = {
|
|
22757
|
+
left: [2, 4, 0],
|
|
22758
|
+
right: [8, 16, 0],
|
|
22759
|
+
middle: [32, 64, 0],
|
|
22760
|
+
x1: [128, 256, 1],
|
|
22761
|
+
x2: [128, 256, 2]
|
|
22762
|
+
};
|
|
22763
|
+
var VK_NAMES = {
|
|
22764
|
+
backspace: 8,
|
|
22765
|
+
tab: 9,
|
|
22766
|
+
enter: 13,
|
|
22767
|
+
shift: 16,
|
|
22768
|
+
ctrl: 17,
|
|
22769
|
+
alt: 18,
|
|
22770
|
+
caps: 20,
|
|
22771
|
+
esc: 27,
|
|
22772
|
+
space: 32,
|
|
22773
|
+
pageup: 33,
|
|
22774
|
+
pagedown: 34,
|
|
22775
|
+
end: 35,
|
|
22776
|
+
home: 36,
|
|
22777
|
+
left: 37,
|
|
22778
|
+
up: 38,
|
|
22779
|
+
right: 39,
|
|
22780
|
+
down: 40,
|
|
22781
|
+
insert: 45,
|
|
22782
|
+
delete: 46,
|
|
22783
|
+
win: 91,
|
|
22784
|
+
f1: 112,
|
|
22785
|
+
f2: 113,
|
|
22786
|
+
f3: 114,
|
|
22787
|
+
f4: 115,
|
|
22788
|
+
f5: 116,
|
|
22789
|
+
f6: 117,
|
|
22790
|
+
f7: 118,
|
|
22791
|
+
f8: 119,
|
|
22792
|
+
f9: 120,
|
|
22793
|
+
f10: 121,
|
|
22794
|
+
f11: 122,
|
|
22795
|
+
f12: 123
|
|
22796
|
+
};
|
|
22797
|
+
function vkOf(key) {
|
|
22798
|
+
if (typeof key === "number" && Number.isInteger(key) && key >= 0 && key <= 65535)
|
|
22799
|
+
return key;
|
|
22800
|
+
if (typeof key === "string") {
|
|
22801
|
+
if (key.length === 1) {
|
|
22802
|
+
const c2 = key.toUpperCase().charCodeAt(0);
|
|
22803
|
+
if (c2 >= 48 && c2 <= 57 || c2 >= 65 && c2 <= 90)
|
|
22804
|
+
return c2;
|
|
22805
|
+
}
|
|
22806
|
+
const vk = VK_NAMES[key.toLowerCase()];
|
|
22807
|
+
if (vk !== void 0)
|
|
22808
|
+
return vk;
|
|
22809
|
+
}
|
|
22810
|
+
throw new Error("bad key: " + JSON.stringify(key) + " (a-z/0-9|name|0..0xFFFF)");
|
|
22811
|
+
}
|
|
22495
22812
|
var server = createServer(async (req) => {
|
|
22496
22813
|
const t0 = Date.now();
|
|
22497
22814
|
const path = new URL(req.url).pathname;
|
|
22498
|
-
const isApi = req.method === "POST" && (path === "/exec" || path === "/set_resolution") || req.method === "GET" && (path === "/window_list" || path === "/screenshot");
|
|
22815
|
+
const isApi = req.method === "POST" && (path === "/exec" || path === "/set_resolution" || path === "/input") || req.method === "GET" && (path === "/window_list" || path === "/screenshot" || path === "/tray_list");
|
|
22499
22816
|
if (!isApi)
|
|
22500
22817
|
return usageResponse();
|
|
22501
22818
|
const denied = authCheck(req);
|
|
@@ -22514,6 +22831,31 @@ var server = createServer(async (req) => {
|
|
|
22514
22831
|
return jsonError(500, String(ex));
|
|
22515
22832
|
}
|
|
22516
22833
|
}
|
|
22834
|
+
if (req.method === "GET" && path === "/tray_list") {
|
|
22835
|
+
const params = new URL(req.url).searchParams;
|
|
22836
|
+
let probe = null;
|
|
22837
|
+
const ph = params.get("probe");
|
|
22838
|
+
if (ph !== null) {
|
|
22839
|
+
const hh = Number(ph), uid = Number(params.get("uid") ?? "");
|
|
22840
|
+
if (!Number.isInteger(hh) || hh <= 0 || !Number.isInteger(uid) || uid < 0) {
|
|
22841
|
+
logReq(t0, "GET /tray_list", 400, "probe=<hwnd>&uid=<n>");
|
|
22842
|
+
return jsonError(400, "probe needs integer hwnd>0 and uid>=0");
|
|
22843
|
+
}
|
|
22844
|
+
probe = { hWnd: hh, uID: uid };
|
|
22845
|
+
}
|
|
22846
|
+
try {
|
|
22847
|
+
const icons = listTrayIcons();
|
|
22848
|
+
const body = { icons };
|
|
22849
|
+
if (probe)
|
|
22850
|
+
body.probe = probeTrayIcon(probe.hWnd, probe.uID);
|
|
22851
|
+
const nOv = icons.reduce((n2, e2) => n2 + (e2.area === "overflow" ? 1 : 0), 0);
|
|
22852
|
+
logReq(t0, "GET /tray_list", 200, icons.length + " icons \xB7 overflow " + nOv);
|
|
22853
|
+
return new Response(JSON.stringify(body), { headers: { "Content-Type": "application/json" } });
|
|
22854
|
+
} catch (ex) {
|
|
22855
|
+
logReq(t0, "GET /tray_list", 500, String(ex));
|
|
22856
|
+
return jsonError(500, String(ex));
|
|
22857
|
+
}
|
|
22858
|
+
}
|
|
22517
22859
|
if (req.method === "GET" && path === "/screenshot") {
|
|
22518
22860
|
let opts;
|
|
22519
22861
|
try {
|
|
@@ -22555,6 +22897,105 @@ var server = createServer(async (req) => {
|
|
|
22555
22897
|
logReq(t0, "POST /set_resolution " + w2 + "x" + h2 + (persist ? "" : " persist=0"), 200, result.ret !== 0 ? result.retName : void 0);
|
|
22556
22898
|
return resp;
|
|
22557
22899
|
}
|
|
22900
|
+
if (req.method === "POST" && path === "/input") {
|
|
22901
|
+
const bad = (msg) => {
|
|
22902
|
+
logReq(t0, "POST /input", 400, msg);
|
|
22903
|
+
return jsonError(400, msg);
|
|
22904
|
+
};
|
|
22905
|
+
let raw;
|
|
22906
|
+
try {
|
|
22907
|
+
raw = await req.json();
|
|
22908
|
+
} catch (ex) {
|
|
22909
|
+
return bad("bad json: " + String(ex));
|
|
22910
|
+
}
|
|
22911
|
+
if (!Array.isArray(raw) || raw.length === 0)
|
|
22912
|
+
return bad("body must be a non-empty JSON array");
|
|
22913
|
+
if (raw.length > 1e3)
|
|
22914
|
+
return bad("too many events: " + raw.length + " (max 1000)");
|
|
22915
|
+
const sw = GetSystemMetrics(0), sh = GetSystemMetrics(1);
|
|
22916
|
+
const segs = [{ els: [], sleep: 0 }];
|
|
22917
|
+
const cur = () => segs[segs.length - 1];
|
|
22918
|
+
try {
|
|
22919
|
+
for (const e2 of raw) {
|
|
22920
|
+
if (typeof e2 !== "object" || e2 === null || Array.isArray(e2))
|
|
22921
|
+
throw new Error("event must be an object: " + JSON.stringify(e2));
|
|
22922
|
+
const ev = e2;
|
|
22923
|
+
const abs = (required) => {
|
|
22924
|
+
if (ev.x === void 0 && ev.y === void 0) {
|
|
22925
|
+
if (required)
|
|
22926
|
+
throw new Error("x/y required for move");
|
|
22927
|
+
return [0, 0, 0];
|
|
22928
|
+
}
|
|
22929
|
+
const x2 = ev.x, y2 = ev.y;
|
|
22930
|
+
if (typeof x2 !== "number" || typeof y2 !== "number" || !Number.isInteger(x2) || !Number.isInteger(y2))
|
|
22931
|
+
throw new Error("x/y must be integers (physical px)");
|
|
22932
|
+
if (x2 < 0 || x2 >= sw || y2 < 0 || y2 >= sh)
|
|
22933
|
+
throw new Error("x/y out of screen: 0.." + (sw - 1) + " / 0.." + (sh - 1));
|
|
22934
|
+
return [
|
|
22935
|
+
Math.round(x2 * 65535 / (sw - 1)),
|
|
22936
|
+
Math.round(y2 * 65535 / (sh - 1)),
|
|
22937
|
+
MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE
|
|
22938
|
+
];
|
|
22939
|
+
};
|
|
22940
|
+
switch (ev.t) {
|
|
22941
|
+
case "move": {
|
|
22942
|
+
const [dx, dy, f2] = abs(true);
|
|
22943
|
+
cur().els.push({ type: INPUT_MOUSE, data: { mi: { dx, dy, dwFlags: f2 } } });
|
|
22944
|
+
break;
|
|
22945
|
+
}
|
|
22946
|
+
case "down":
|
|
22947
|
+
case "up": {
|
|
22948
|
+
const btn = typeof ev.btn === "string" ? MOUSE_BTNS[ev.btn] : void 0;
|
|
22949
|
+
if (!btn)
|
|
22950
|
+
throw new Error("bad btn: " + JSON.stringify(ev.btn) + " (left|right|middle|x1|x2)");
|
|
22951
|
+
const [downF, upF, mData] = btn;
|
|
22952
|
+
const [dx, dy, f2] = abs(false);
|
|
22953
|
+
const flag = ev.t === "down" ? downF : upF;
|
|
22954
|
+
cur().els.push({ type: INPUT_MOUSE, data: { mi: { dx, dy, mouseData: mData, dwFlags: f2 | flag } } });
|
|
22955
|
+
break;
|
|
22956
|
+
}
|
|
22957
|
+
case "key": {
|
|
22958
|
+
const up = ev.up === true;
|
|
22959
|
+
cur().els.push({ type: INPUT_KEYBOARD, data: { ki: { wVk: vkOf(ev.key), dwFlags: up ? KEYEVENTF_KEYUP : 0 } } });
|
|
22960
|
+
break;
|
|
22961
|
+
}
|
|
22962
|
+
case "sleep": {
|
|
22963
|
+
const ms = ev.ms;
|
|
22964
|
+
if (typeof ms !== "number" || !Number.isFinite(ms) || ms < 0 || ms > 5e3)
|
|
22965
|
+
throw new Error("sleep ms must be a number in 0..5000");
|
|
22966
|
+
segs.push({ els: [], sleep: ms });
|
|
22967
|
+
break;
|
|
22968
|
+
}
|
|
22969
|
+
default:
|
|
22970
|
+
throw new Error("bad t: " + JSON.stringify(ev.t) + " (move|down|up|key|sleep)");
|
|
22971
|
+
}
|
|
22972
|
+
}
|
|
22973
|
+
} catch (ex) {
|
|
22974
|
+
return bad(ex instanceof Error ? ex.message : String(ex));
|
|
22975
|
+
}
|
|
22976
|
+
let expected = 0, sent = 0;
|
|
22977
|
+
for (const s2 of segs)
|
|
22978
|
+
expected += s2.els.length;
|
|
22979
|
+
try {
|
|
22980
|
+
for (const seg of segs) {
|
|
22981
|
+
if (seg.sleep > 0)
|
|
22982
|
+
await new Promise((r2) => {
|
|
22983
|
+
os7.setTimeout(r2, seg.sleep);
|
|
22984
|
+
});
|
|
22985
|
+
if (seg.els.length === 0)
|
|
22986
|
+
continue;
|
|
22987
|
+
const n2 = SendInput(seg.els.length, seg.els, INPUT.size);
|
|
22988
|
+
sent += n2;
|
|
22989
|
+
if (n2 < seg.els.length)
|
|
22990
|
+
break;
|
|
22991
|
+
}
|
|
22992
|
+
} catch (ex) {
|
|
22993
|
+
logReq(t0, "POST /input", 500, String(ex));
|
|
22994
|
+
return jsonError(500, String(ex));
|
|
22995
|
+
}
|
|
22996
|
+
logReq(t0, "POST /input " + raw.length + "ev", 200, sent < expected ? "sent " + sent + "/" + expected : void 0);
|
|
22997
|
+
return new Response(JSON.stringify({ sent, expected }), { headers: { "Content-Type": "application/json" } });
|
|
22998
|
+
}
|
|
22558
22999
|
if (req.method === "POST" && path === "/exec") {
|
|
22559
23000
|
let out;
|
|
22560
23001
|
let cmd;
|