partforge 0.144.0 → 0.145.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "partforge",
3
- "version": "0.144.0",
3
+ "version": "0.145.0",
4
4
  "description": "Turn a declarative part definition into a parametric-CAD web app (three.js + Manifold/Replicad). Requires a Vite-based consumer.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -0,0 +1,118 @@
1
+ // The oracle's triangle BVH and min-wall pass on the native core
2
+ // (native/bvh.cpp) — the same queries and results as oracle/bvh.js and
3
+ // oracle/min-wall.js, bit for bit.
4
+ //
5
+ // A core BVH lives in WebAssembly memory, so unlike the JS one it must be FREED:
6
+ // `dispose()`. The oracle's own callers do that — measure() for the Map it owns,
7
+ // meshGaps() for BVHs it built without one — and a FinalizationRegistry is the
8
+ // backstop for anything else. Only partforge's own call paths get these (see
9
+ // cachedBVH); the public buildBVH() and a caller-supplied bvhCache stay JS.
10
+ //
11
+ // Every query has a JS twin to fall back on — `jsIndex()`, the JS BVH of the
12
+ // same mesh, built on first need. A fault inside the module poisons the instance
13
+ // (core.js) and the query is answered by that twin instead, as is a distanceTo
14
+ // whose other side is not a core BVH of the same instance.
15
+ import { poisonCore, releaseIfIdle } from "./core.js";
16
+
17
+ const registry = typeof FinalizationRegistry === "function"
18
+ ? new FinalizationRegistry(({ c, handle }) => {
19
+ c.live--;
20
+ if (!c.poisoned) c.x.bvh_destroy(handle);
21
+ releaseIfIdle(c);
22
+ })
23
+ : null;
24
+
25
+ const pt = (a, i) => (Number.isNaN(a[i]) ? null : [a[i], a[i + 1], a[i + 2]]);
26
+
27
+ // `verts`: bvh.js's triangleVertices(mesh) — 9 coords per triangle, mesh order.
28
+ // `makeJsIndex`: builds the JS BVH of the same mesh (the fallback), on demand.
29
+ // Throws if the module faults while building; the caller falls back.
30
+ export function buildCoreBVH(c, verts, makeJsIndex) {
31
+ const { x } = c;
32
+ const ptr = c.alloc(verts.byteLength);
33
+ new Uint8Array(x.memory.buffer, ptr, verts.byteLength).set(new Uint8Array(verts.buffer, verts.byteOffset, verts.byteLength));
34
+ // adopt = 1: the C++ index owns the vertex buffer from here (no second copy)
35
+ const handle = x.bvh_build(ptr, verts.length / 9, verts instanceof Float64Array ? 1 : 0, 1);
36
+ x.bvh_root_bounds(handle, c.scratch + 64);
37
+ const rb = c.f64().slice(8, 14);
38
+ c.live++;
39
+ let live = true, js = null;
40
+ const token = {};
41
+ registry?.register(token, { c, handle }, token);
42
+ const jsIndex = () => (js ??= makeJsIndex());
43
+ // Run `fn` on the core, or answer with `fallback` if the instance is (or
44
+ // becomes) unusable.
45
+ const guarded = (fn, fallback) => {
46
+ if (!live) throw new Error("core BVH used after dispose()");
47
+ if (c.poisoned) return fallback();
48
+ try {
49
+ return fn();
50
+ } catch {
51
+ poisonCore(c);
52
+ return fallback();
53
+ }
54
+ };
55
+ const self = {
56
+ core: c,
57
+ triangleCount: verts.length / 9,
58
+ rootBounds: [rb[0], rb[1], rb[2], rb[3], rb[4], rb[5]],
59
+ get handle() { return handle; },
60
+ jsIndex,
61
+ raycast(origin, dir, opts = {}) {
62
+ const { tMin = 1e-6, tMax = Infinity, skipTri = -1 } = opts;
63
+ return guarded(() => {
64
+ const s = c.f64();
65
+ s[0] = origin[0]; s[1] = origin[1]; s[2] = origin[2]; s[3] = dir[0]; s[4] = dir[1]; s[5] = dir[2];
66
+ const tri = x.bvh_raycast(handle, c.scratch, c.scratch + 24, tMin, tMax, skipTri, c.scratch + 64);
67
+ return tri === -1 ? null : { t: c.f64()[8], tri };
68
+ }, () => jsIndex().raycast(origin, dir, opts));
69
+ },
70
+ closestPoint(p) {
71
+ return guarded(() => {
72
+ const s = c.f64();
73
+ s[0] = p[0]; s[1] = p[1]; s[2] = p[2];
74
+ const tri = x.bvh_closest_point(handle, c.scratch, c.scratch + 64);
75
+ const o = c.f64();
76
+ return { point: tri === -1 ? null : [o[8], o[9], o[10]], dist: o[11], tri };
77
+ }, () => jsIndex().closestPoint(p));
78
+ },
79
+ // Exact minimum surface-to-surface distance. Two core BVHs of the same live
80
+ // instance meet in C++; anything else (a JS index, another instance) meets
81
+ // through the JS twins.
82
+ distanceTo(other) {
83
+ const viaJs = () => jsIndex().distanceTo(other?.jsIndex ? other.jsIndex() : other);
84
+ if (other?.core !== c || other.core.poisoned) return viaJs();
85
+ return guarded(() => {
86
+ const ok = x.bvh_distance_to(handle, other.handle, c.scratch + 64);
87
+ if (!ok) return { distance: Infinity, at: null, pointA: null, pointB: null };
88
+ const r = c.f64();
89
+ return { distance: r[8], at: [r[9], r[10], r[11]], pointA: [r[12], r[13], r[14]], pointB: [r[15], r[16], r[17]] };
90
+ }, viaJs);
91
+ },
92
+ // minWall over this index, min-wall.js's result shape exactly. min-wall.js
93
+ // dispatches here with its own resolved options; `undefined` means "the core
94
+ // could not answer — run the JS pass" (null is a real answer: empty mesh).
95
+ minWall({ maxThickness, maxSamples, band = null }) {
96
+ return guarded(() => {
97
+ const ok = x.bvh_min_wall(handle, maxThickness == null ? 0 : 1, maxThickness == null ? 0 : maxThickness,
98
+ maxSamples, band ? 1 : 0, band ? band.min : 0, band ? band.max : 0, c.scratch + 64);
99
+ if (!ok) return null;
100
+ const r = c.f64().slice(8, 20);
101
+ return {
102
+ value: Number.isNaN(r[0]) ? null : r[0], location: pt(r, 1), sampled: r[4] === 1,
103
+ sampledTriangles: r[5], totalTriangles: r[6],
104
+ band: band ? { value: Number.isNaN(r[7]) ? null : r[7], location: pt(r, 8), members: r[11] } : null,
105
+ };
106
+ }, () => undefined);
107
+ },
108
+ dispose() {
109
+ if (!live) return;
110
+ live = false;
111
+ registry?.unregister(token);
112
+ c.live--;
113
+ if (!c.poisoned) x.bvh_destroy(handle);
114
+ releaseIfIdle(c);
115
+ },
116
+ };
117
+ return self;
118
+ }
@@ -0,0 +1,6 @@
1
+ // GENERATED by scripts/build-core-wasm.mjs from native/ — do not edit by hand.
2
+ // emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 6.0.10-git
3
+ // 64176 bytes of WebAssembly. test/core-wasm.test.js checks the hash below
4
+ // against native/ so a C++ change without a rebuild fails.
5
+ export const CORE_SOURCE_HASH = "1192dae0d7f327873d13d953ff8011be87313260719c05f5a5ba9a569f7eb867";
6
+ export const CORE_WASM_BASE64 = "AGFzbQEAAAABwgEYYAF/AX9gAX8AYAN/f38Bf2ACf38AYAR/f39/AX9gAABgA39/fwBgAn9/AX9gBX9/f39/AGAEf39/fwBgB39/f3x8f38Bf2AEf35/fwF/YAZ/f39/f38AYAV/f39/fwF8YAh/f3x8f3x8fwF/YAh/f39/f39/fwBgC39/f39/f39/f39/AX9gDX9/f39/f3x8f39/f38AYAN/fn8BfmACfH8BfGAFf39/f38Bf2ACfn8Bf2AHf3x/f39/fwF/YAABfwKMAQQDZW52H2Vtc2NyaXB0ZW5fbm90aWZ5X21lbW9yeV9ncm93dGgAARZ3YXNpX3NuYXBzaG90X3ByZXZpZXcxCGZkX2Nsb3NlAAAWd2FzaV9zbmFwc2hvdF9wcmV2aWV3MQhmZF93cml0ZQAEFndhc2lfc25hcHNob3RfcHJldmlldzEHZmRfc2VlawALA0dGBQMFBQQJBgABAQEDBAMHAQwIAAMKCgECDQIJDgEIDxARBAAAAAAAAAABAAEAAAACBwAAAAISAAcTFAYABhUIFgMBAwEXAwQFAXABDAwFBwEBgAKAgAIGCAF/AUGwlwQLB6MDGgZtZW1vcnkCABlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQAJYnZoX2J1aWxkABAGbWFsbG9jAC4SYnZoX3RyaWFuZ2xlX2NvdW50ABYPYnZoX3Jvb3RfYm91bmRzABcLYnZoX3JheWNhc3QAGBFidmhfY2xvc2VzdF9wb2ludAAbD2J2aF9kaXN0YW5jZV90bwAdDGJ2aF9taW5fd2FsbAAfC2J2aF9kZXN0cm95ACAEZnJlZQAvCWNuX2NyZWF0ZQAjCWNuX2ZpbmlzaAAkDGNuX3Bvc2l0aW9ucwAmCmNuX25vcm1hbHMAJwhjbl9lZGdlcwAoDmNuX2VkZ2VfZmxvYXRzACkOY25fZmVhdHVyZV9pZHMAKhBjbl9mZWF0dXJlX2NvdW50ACsRY25fZmVhdHVyZV9sYWJlbHMALApjbl9kZXN0cm95AC0LX2luaXRpYWxpemUABAhzZXRUaHJldwBJGV9lbXNjcmlwdGVuX3N0YWNrX3Jlc3RvcmUARxxlbXNjcmlwdGVuX3N0YWNrX2dldF9jdXJyZW50AEgJEQEAQQELCwsMDTQOBDc4OUNEDAEWCsbmA0YqAEGQFkGwlwQ2AgBB+BVBKjYCAEGUFkGAgAQ2AgBBmBZB1BAoAgA2AgALrwIBBn8CQAJAAkAgACgCBCICIAAoAgAiBGsiBUEYbSIDIAFJBEAgACgCCCAEa0EYbSIGIAFPBEAgASADa0EYbEEYayIBIAFBGHBrQRhqIgEEQCACQQAgAfwLAAsgACABIAJqNgIEDwsgAUGr1arVAE8NAkGq1arVACAGQQF0IgIgASABIAJJGyAGQdWq1SpPGyICQavVqtUATw0DIAJBGGwiBhA1IgcgBWohAiABIANrQRhsQRhrIgEgAUEYcGtBGGoiAQRAIAJBACAB/AsACyACIAVBaG1BGGxqIQMgBQRAIAMgBCAF/AoAAAsgACAGIAdqNgIIIAAgASACajYCBCAAIAM2AgAgBEUNASAEEC8PCyABIANPDQAgACAEIAFBGGxqNgIECw8LEAYACxAHAAsdAQF/IwBBEGsiACQAIABBnQg2AgBB9QggABBGAAsKAEGsCEEAEEYAC/0bAw58FH8DfiMAQfAAayISJAAgEiABNgJUIBIgACgCqAEiASAAKAKkASIXa0EYbSIdNgJQIAEgF0YEf0EABSASIB0gAC0ABEEBcyIBayIaNgJMIBJCfzcDQCASQgA3AzggEkKAgICAgICA+P8ANwMwIBJCADcDKCASIABBpAFqNgIMIBIgEkE4ajYCJCASIBJBQGs2AiAgEiASQTBqNgIcIBIgEkEoajYCGCASIBJB1ABqNgIUIBIgEkHQAGo2AhAgEiASQcwAajYCCAJAIBpBEE8EQAJAIAAoAuABIhsNAEHAABA1IhNCADcDKCATQgA3AzAgE0IANwM4IBNCADcDGCATQcAJNgIAIBNCADcCBCATQgA3AyAgE0IANwIsIBNCADcCNCATQYCAgPwDNgIoIAEgHUciFgRAQQAhAQNAIAFBGGwhFSAEIBcgAUEBaiIBIB1wQRhsaiIUKwMAIBUgF2oiFSsDAKEiBCAEoiAUKwMIIBUrAwihIgQgBKKgIBQrAxAgFSsDEKEiBCAEoqCfoCEEIAEgGkcNAAsLIAAtAKABBEAgACsDiAGZIAArA5ABmaAhBgsgE0EQaiEbRAAAAAAAAPh/IQkgAC0AoQFBAUYEQCAGIAArA5gBoCEGCwJAIAREAAAAAAAA8D8gGrgiBCAERAAAAAAAAPA/YxujIgQgBGIgBiAGYnINAAJ8AkAgBEQAAAAAAAAAAGINACAGRAAAAAAAAAAAYg0AIAYgBCAEvUIAUxsMAQsgBCAGIAQgBmQbCyIEIARiDQAgBESN7bWg98awPiAERI3ttaD3xrA+ZBshCQsgEyAJOQMQIBYEQCATQRhqIRlBACEBA0AgACgCpAEiFSABQRhsaiIUKwMIIQQgFSABQQFqIhcgHXBBGGxqIhUrAwghCEQAAAAAAAD4fyEGRAAAAAAAAPh/IQoCfEQAAAAAAAD4fyAUKwMAIgUgBWIgFSsDACIHIAdicg0AGgJAIAVEAAAAAAAAAABiDQAgB0QAAAAAAAAAAGINACAHIAUgBb1CAFMiFhshCiAFIAcgFhsgCaOcDAELIAUgByAFIAdkGyEKIAUgByAFIAdjGyAJo5wLIQsgFCsDECEFIBUrAxAhByAKIAmjIQ1EAAAAAAAA+H8hCgJAIAQgBGIgCCAIYnINACAERAAAAAAAAAAAYSAIRAAAAAAAAAAAYXFFBEAgBCAIIAQgCGQbIQogBCAIIAQgCGMbIAmjnCEGDAELIAggBCAEvUIAUyIUGyEKIAQgCCAUGyAJo5whBgsgDZwhDQJ8IAUgBWIgByAHYnIEQEQAAAAAAAD4fyEERAAAAAAAAPh/DAELIAVEAAAAAAAAAABhIAdEAAAAAAAAAABhcUUEQCAFIAcgBSAHZBshBCAFIAcgBSAHYxsgCaOcDAELIAcgBSAFvUIAUyIUGyEEIAUgByAUGyAJo5wLIQggCyANZQRAIAogCaOcIQcgBCAJo5whCgNAAkAgBiAHZUUNACALnSIEIAREAAAAAAAA8D2inUQAAAAAAADwQaKhIASmIgREAAAAAAAA8EGgIAQgBEQAAAAAAAAAAGMb/ANB3eibI2xBACALvUIBhkKAgICAgICAcFQbISAgBiEFAkADQAJAIAggCmUEQCAFnSIEIAREAAAAAAAA8D2inUQAAAAAAADwQaKhIASmIgREAAAAAAAA8EGgIAQgBEQAAAAAAAAAAGMb/ANBn4GdCWxBACAFvUIBhkKAgICAgICAcFQbICBzIR4gCCEEA0AgEiAEvUIBhkL/////////b1gEfyAEnSIMIAxEAAAAAAAA8D2inUQAAAAAAADwQaKhIAymIgxEAAAAAAAA8EGgIAwgDEQAAAAAAAAAAGMb/ANBt//nJ2wgHnMFIB4LNgJYIBIgEkHYAGoiFDYCYCASIBk2AmwgEkHkAGogEkHsAGogFCASQeAAahAJAkAgEigCZCIVKAIQIhQgFSgCFCIcSQRAIBQgATYCACAUQQRqIRQMAQsgFCAVKAIMIhZrIhRBAnUiIUEBaiIYQYCAgIAETw0DQf////8DIBwgFmsiHEEBdSIfIBggGCAfSRsgHEH8////B08bIhhBgICAgARPDQUgGEECdCIfEDUiIiAUaiIYIAE2AgAgGCAhQQJ0ayEcIBQEQCAcIBYgFPwKAAALIBUgHyAiajYCFCAVIBhBBGoiFDYCECAVIBw2AgwgFkUNACAWEC8LIBUgFDYCECAERAAAAAAAAPA/oCIEIAplDQALCyAFRAAAAAAAAPA/oCIFIAdlDQEMAwsLEAYACxAHAAsgC0QAAAAAAADwP6AiCyANZQ0ACwsgFyIBIBpHDQALCyASQQA2AmQgE0EsaiAaIBJB5ABqEAogEyATKAIEQQFqNgIEIAAgGzYC4AEgACgC5AEhASAAIBM2AuQBAkAgAUUNACABIAEoAgQiF0EBazYCBCAXDQAgASABKAIAKAIIEQEAAkAgASgCCCIXBEAgASAXQQFrNgIIIBcNAQsgASABKAIAKAIQEQEACwsgEyATKAIEIgFBAWs2AgQgAQ0AIBMgEygCACgCCBEBAAJAIBMoAggiAQRAIBMgAUEBazYCCCABDQELIBMgEygCACgCEBEBAAsLIBsgGygCKEEBaiIgNgIoIBIoAlQiHCsDECIHIBsrAwAiBqOcIQsgHCsDCCIKIAajnCENIBwrAwAgBqOcIQwgEikDQCEmQQEhHkEAIQEDQCAmQgBZBEAgEisDMJ8gBiABQQFrt6JjDQMLQQAhIUEAIAEiGmsiFyEYA0AgDCAYt6AiBZ0iBCAERAAAAAAAAPA9op1EAAAAAAAA8EGioSAEpiIERAAAAAAAAPBBoCAEIAREAAAAAAAAAABjG/wDQd3omyNsQQAgBb1CAYZCgICAgICAgHBUGyEkIBggGEEfdSIBcyABayEfIBchFQNAICQgDSAVt6AiBZ0iBCAERAAAAAAAAPA9op1EAAAAAAAA8EGioSAEpiIERAAAAAAAAPBBoCAEIAREAAAAAAAAAABjG/wDQZ+BnQlsQQAgBb1CAYZCgICAgICAgHBUG3MhHSAVIBVBH3UiAXMgAWshIiAXIRQDQAJAIB8gIiAUIBRBH3UiAXMgAWsiASABICJJGyIBIAEgH0kbIBpHDQAgHSETIAsgFLegIgS9QgGGQv////////9vWARAIBMgBJ0iBCAERAAAAAAAAPA9op1EAAAAAAAA8EGioSAEpiIERAAAAAAAAPBBoCAEIAREAAAAAAAAAABjG/wDQbf/5ydscyETCyAbKAIMIhZFDQAgGygCFEUNACAbKAIIAn8gFkEBayATcSAWaUEBSyIZRQ0AGiATIBMgFkkNABogEyAWcAsiI0ECdGooAgAiAUUNACABKAIAIgFFDQACQCAZRQRAIBZBAWshFgNAAkAgEyABKAIEIhlHBEAgFiAZcSAjRg0BDAULIAEoAgggE0YNAwsgASgCACIBDQALDAILA0ACQCATIAEoAgQiGUcEQCAWIBlNBH8gGSAWcAUgGQsgI0YNAQwECyABKAIIIBNGDQILIAEoAgAiAQ0ACwwBC0EBISEgASgCDCITIAEoAhAiI0YNACAbKAIcISUDQAJAICUgEygCACIWQQJ0aiIBKAIAICBGDQAgASAgNgIARAAAAAAAAAAAIQQgACgCpAEiASAWQQFqIBIoAlBwQRhsaiIZKwMAIAEgFkEYbGoiASsDACIOoSIFIAWiIBkrAwggASsDCCIPoSIIIAiioCAZKwMQIAErAxAiEKEiCSAJoqAiEUQR6i2BmZdxPWQEQCAFIBwrAwAgDqGiIAggCiAPoaKgIAkgByAQoaKgIBGjIQQLIBJEAAAAAAAAAABEAAAAAAAA8D8gBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIgQ5AyggHCsDACABKwMAoSAFIASioSIFIAWiIAogASsDCKEgCCAEoqEiBSAFoqAgByABKwMQoSAJIASioSIFIAWioCIFIBIrAzBjRQ0AIBIgBTkDMCASIAQ5AzggEiAWrTcDQAsgE0EEaiITICNHDQALCyAUQQFqIhQgHkcNAAsgFUEBaiIVIB5HDQALIBhBAWoiGCAeRw0ACyAeQQFqIR4gGkEBaiEBIBIpA0AiJkIAWSAhcg0AIBpBA0kNAAsLQgAhJiASKAIIKAIAIgAEQCAArSEnIBIoAiQhGiASKAIgIR0gEigCHCEXIBIoAhghEyASKAIUKAIAIQAgEigCECgCACEbIBIoAgwoAgAhFANARAAAAAAAAAAAIQQgFCAmQgF8IiinIBtwQRhsaiIVKwMAIBQgJqdBGGxqIgErAwAiCaEiBiAGoiAVKwMIIAErAwgiB6EiBSAFoqAgFSsDECABKwMQIgqhIgggCKKgIgtEEeotgZmXcT1kBEAgBiAAKwMAIAmhoiAFIAArAwggB6GioCAIIAArAxAgCqGioCALoyEECyATRAAAAAAAAAAARAAAAAAAAPA/IAQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyIEOQMAIAArAwAgASsDAKEgBiAEoqEiBiAGoiAAKwMIIAErAwihIAUgBKKhIgYgBqKgIAArAxAgASsDEKEgCCAEoqEiBCAEoqAiBCAXKwMAYwRAIBcgBDkDACAdICY3AwAgGiATKwMAOQMACyAoIiYgJ1INAAsLCyASKQNAIiZCAFkEQCACICY+AgAgAyASKwM4OQMACyAmQgBZCyEAIBJB8ABqJAAgAAvUBQIFfwJ9IAIoAgAhBSAAAn8CQCABKAIAIgYoAgQiAUUNACAGKAIAAn8gAUEBayAFcSABaSIHQQFNDQAaIAUgASAFSw0AGiAFIAFwCyIEQQJ0aigCACICRQ0AIAIoAgAiAkUNACAHQQFNBEAgAUEBayEHA0ACQCAFIAIoAgQiCEcEQCAHIAhxIARHDQQMAQsgAigCCCAFRw0AQQAMBAsgAigCACICDQALDAELA0ACQCAFIAIoAgQiB0cEQCABIAdNBH8gByABcAUgBwsgBEcNAwwBCyACKAIIIAVHDQBBAAwDCyACKAIAIgINAAsLQRgQNSICIAU2AgQgAkEANgIAIAMoAgAoAgAhAyACQQA2AhQgAkIANwIMIAIgAzYCCAJAIAYoAgxBAWqzIgkgBioCECIKIAGzlF5FDQBBAiEEAkAgASABQQFrcUEARyABQQNJciABQQF0ciIDIAkgCpWN/AEiByADIAdLGyIDQQFGDQAgAyADQQFrcUUEQCADIQQMAQsgAxAyIQQgBigCBCEBCwJAIAEgBE8EQCABIARNDQEgBigCDLMgBioCEJWN/AEhAyABIAQCfwJAIAFBA0kNACABaUEBSw0AIANBAUEgIANBAWtna3QgA0ECSRsMAQsgAxAyCyIBIAEgBEkbIgRNDQELIAYgBBAPCyAGKAIEIgEgAUEBayIDcUUEQCADIAVxIQQMAQsgASAFSwRAIAUhBAwBCyAFIAFwIQQLAkAgBigCACIFIARBAnRqIgQoAgAiA0UEQCACIAYoAgg2AgAgBiACNgIIIAQgBkEIajYCACACKAIAIgNFDQEgAygCBCEDAkAgASABQQFrIgRxRQRAIAMgBHEhAwwBCyABIANLDQAgAyABcCEDCyAFIANBAnRqIAI2AgAMAQsgAiADKAIANgIAIAMgAjYCAAsgBiAGKAIMQQFqNgIMQQELOgAEIAAgAjYCAAunBAEJfyAAKAIIIgMgACgCACIEa0ECdSABTwRAAkAgACgCBCIGIARrQQJ1IgkgASABIAlLGyIIRQ0AIAIoAgAhBSAEIQMgCCIHQQdxIgoEQANAIAMgBTYCACAHQQFrIQcgA0EEaiEDIAtBAWoiCyAKRw0ACwsgCEEISQ0AA0AgAyAFNgIcIAMgBTYCGCADIAU2AhQgAyAFNgIQIAMgBTYCDCADIAU2AgggAyAFNgIEIAMgBTYCACADQSBqIQMgB0EIayIHDQALCyABIAlLBEAgBiABIAlrQQJ0aiEBIAIoAgAhAgNAIAYgAjYCACAGQQRqIgYgAUcNAAsgACABNgIEDwsgACAEIAFBAnRqNgIEDwsgBARAIAAgBDYCBCAEEC8gAEEANgIIIABCADcCAEEAIQMLAkAgAUGAgICABE8NAEH/////AyADQQF1IgQgASABIARJGyADQfz///8HTxsiA0GAgICABE8NACAAIANBAnQiAxA1IgQ2AgAgACADIARqNgIIIAIoAgAhAiAEIQMgAUECdCIBQQRrIgdBAnZBAWpBB3EiCARAA0AgAyACNgIAIANBBGohAyAGQQFqIgYgCEcNAAsLIAEgBGohASAHQRxPBEADQCADIAI2AhwgAyACNgIYIAMgAjYCFCADIAI2AhAgAyACNgIMIAMgAjYCCCADIAI2AgQgAyACNgIAIANBIGoiAyABRw0ACwsgACABNgIEDwsQBgALDAAgAEHACTYCACAACw4AIABBwAk2AgAgABAvC3UBA38gACgCLCIBBEAgACABNgIwIAAoAjQaIAEQLwsgACgCICICBEADQCACKAIAIQEgAigCDCIDBEAgAiADNgIQIAIoAhQaIAMQLwsgAhAvIAEiAg0ACwsgACgCGCEBIABBADYCGCABBEAgACgCHBogARAvCwsGACAAEC8LrQMBBX8CQAJAAkAgAQR/IAFBgICAgARPDQEgAUECdBA1BUEACyEDIAAoAgAhAiAAIAM2AgAgAgRAIAAoAgQaIAIQLwsgACABNgIEIAFFDQIgACgCACEFIAFBAnQiAgRAIAVBACAC/AsACyAAKAIIIgJFDQIgAEEIaiEAIAIoAgQhBCABIAFBAWsiA3FFDQEgASAETQRAIAQgAXAhBAsgBSAEQQJ0aiAANgIAA0AgAigCACIDRQ0DIAEgAygCBCIATQRAIAAgAXAhAAsgACAERgRAIAMhAgwBCyAFIABBAnRqIgYoAgAEQCACIAMoAgA2AgAgAyAGKAIAKAIANgIAIAYoAgAgAzYCAAUgBiACNgIAIAMhAiAAIQQLDAALAAsQBwALIAUgAyAEcSIEQQJ0aiAANgIAIAIoAgAiAEUNACABQQFrIQYDQAJAIAQgACgCBCAGcSIBRgRAIAAhAgwBCyAFIAFBAnRqIgMoAgAEQCACIAAoAgA2AgAgACADKAIAKAIANgIAIAMoAgAgADYCAAwBCyADIAI2AgAgACECIAEhBAsgAigCACIADQALCwujGQMJfAp/A30jAEHgAGsiDSQAQTAQNSIOQgA3AgggDkIANwIAIA5CADcCKCAOQgA3AiAgDkIANwIYIA5CADcCECAOIAE2AgggDiACQQBHOgAEAkAgAwRAIA4gADYCAAwBCyAOQQFByABBJCACGyABbCICIAJBAU0bEC4iAzYCACACRSIRDQAgEQ0AIAMgACAC/AoAAAsgDkEMaiABEBEgDUEANgJIIA1CADcCQAJAAkAgAUUNACABQQNsIgJBgICAgAJPDQEgDSABQRhsIgAQNSIRNgJAIA0gESACQQN0ajYCSCAABEAgEUEAIAD8CwALIA0gACARajYCRCAOKAIAIQAgDigCDCEQIA4tAARFBEAgAEEIaiESIABBBGohFEEAIQMDQCAQIANBAnRqIAM2AgAgESADQRhsaiIPIAAgA0EkbCITaiICKgIAIhe7IgYgAioCGCIYuyIEIBcgGF0bIAIqAgwiGbsiBSAEIBggGV4bIBcgGV0bIAYgBCAXIBheGyAFIAQgGCAZXRsgFyAZXhugRAAAAAAAAOA/ojkDACAPIBMgFGoqAgAiF7siBiACKgIcIhi7IgQgFyAYXRsgAioCECIZuyIFIAQgGCAZXhsgFyAZXRsgBiAEIBcgGF4bIAUgBCAYIBldGyAXIBleG6BEAAAAAAAA4D+iOQMIIA8gEiATaioCACIXuyIGIAIqAiAiGLsiBCAXIBhdGyACKgIUIhm7IgUgBCAYIBleGyAXIBldGyAGIAQgFyAYXhsgBSAEIBggGV0bIBcgGV4boEQAAAAAAADgP6I5AxAgA0EBaiIDIAFHDQALDAELIABBEGohEiAAQQhqIRRBACEDA0AgECADQQJ0aiADNgIAIBEgA0EYbGoiDyAAIANByABsIhNqIgIrAwAiBiACKwMwIgQgBCAGZBsgAisDGCIFIAQgBCAFZBsgBSAGZBsgBiAEIAQgBmMbIAUgBCAEIAVjGyAFIAZjG6BEAAAAAAAA4D+iOQMAIA8gEyAUaisDACIGIAIrAzgiBCAEIAZkGyACKwMgIgUgBCAEIAVkGyAFIAZkGyAGIAQgBCAGYxsgBSAEIAQgBWMbIAUgBmMboEQAAAAAAADgP6I5AwggDyASIBNqKwMAIgYgAkFAaysDACIEIAQgBmQbIAIrAygiBSAEIAQgBWQbIAUgBmQbIAYgBCAEIAZjGyAFIAQgBCAFYxsgBSAGYxugRAAAAAAAAOA/ojkDECADQQFqIgMgAUcNAAsLIA1CADcDMCANQgA3AyggDUGAgID8AzYCOCABIA1BKGoQEiEUIA1CADcDCCANQQhqIRNBACEPAkAgFEEGbCIQIA4oAiAiACAOKAIYIgJrQQN1TQRAAkAgDigCHCIPIAJrQQN1IhIgECAQIBJLGyIRRQ0AIBMrAwAhBCACIQAgESIDQQdxIhUEQANAIAAgBDkDACADQQFrIQMgAEEIaiEAIBZBAWoiFiAVRw0ACwsgEUEISQ0AA0AgACAEOQM4IAAgBDkDMCAAIAQ5AyggACAEOQMgIAAgBDkDGCAAIAQ5AxAgACAEOQMIIAAgBDkDACAAQUBrIQAgA0EIayIDDQALCyAQIBJLBEAgDyAQIBJrQQN0aiEAIBMrAwAhBANAIA8gBDkDACAPQQhqIg8gAEcNAAsgDiAANgIcDAILIA4gAiAQQQN0ajYCHAwBCyACBEAgDiACNgIcIAIQLyAOQQA2AiAgDkIANwIYQQAhAAsCQCAQQYCAgIACTw0AQf////8BIABBAnUiAiAQIAIgEEsbIABB+P///wdPGyIAQYCAgIACTw0AIA4gAEEDdCIAEDUiAjYCGCAOIAAgAmo2AiAgEysDACEEIAIhACAQQQN0IgNBCGsiEUEDdkEBakEHcSIQBEADQCAAIAQ5AwAgAEEIaiEAIA9BAWoiDyAQRw0ACwsgAiADaiECIBFBOE8EQANAIAAgBDkDOCAAIAQ5AzAgACAEOQMoIAAgBDkDICAAIAQ5AxggACAEOQMQIAAgBDkDCCAAIAQ5AwAgAEFAayIAIAJHDQALCyAOIAI2AhwMAQsQBgALIA1BADYCCCAOQSRqIBRBAXQgExAKQRAQNSICQgA3AgggAiABNgIEIAJBADYCACANIAJBEGoiADYCJCANIAI2AhwgDSAANgIgQQAhEQNAIABBEGshEAJAAkACQAJAAkACQCAAQQRrIhMoAgAOAgABAgsgECgCACEPIABBDGsiFSgCACIBRQRARAAAAAAAAPD/IQREAAAAAAAA8H8hBkQAAAAAAADwfyEFRAAAAAAAAPB/IQpEAAAAAAAA8P8hC0QAAAAAAADw/yEMDAQLIA4oAgwgD0ECdGohEiAOKAIAIRREAAAAAAAA8H8hCkQAAAAAAADw/yEMQQAhA0QAAAAAAADw/yELRAAAAAAAAPD/IQREAAAAAAAA8H8hBUQAAAAAAADwfyEGIA4tAARBAUcNAgNAIBQgEiADQQJ0aigCAEHIAGxqIgIrAzAiByACKwMYIgggAisDACIJIAQgBCAJYxsiBCAEIAhjGyIEIAQgB2MbIQQgByAIIAkgBiAGIAlkGyIGIAYgCGQbIgYgBiAHZBshBiACQUBrKwMAIgcgAisDKCIIIAIrAxAiCSAMIAkgDGQbIgwgCCAMZBsiDCAHIAxkGyEMIAcgCCAJIAogCSAKYxsiCiAIIApjGyIKIAcgCmMbIQogAisDOCIHIAIrAyAiCCACKwMIIgkgCyAJIAtkGyILIAggC2QbIgsgByALZBshCyAHIAggCSAFIAUgCWQbIgUgBSAIZBsiBSAFIAdkGyEFIANBAWoiAyABRw0ACwwDCyATQQI2AgAgAEEMayIBKAIAIQIgDigCJCIDIABBCGsiDygCAEEDdGogETYCACADIA8oAgBBA3RqQQA2AgQgASgCACEBIBAoAgAhAyANQgA3AhAgDSABIAJBAXYiAWs2AgwgDSABIANqNgIIIA0gADYCTCANKAIkIQEgDSANQRxqNgJYIA0gDUEIajYCVCANIA1BzABqNgJQIAAgAUkEQCAAIA0pAhA3AgggACANKQIINwIAIA0gAEEQaiIANgIgDAQLIA1B0ABqEBMgDSANKAJMIgA2AiAMAwsgDSAQNgIgIBAhAAwCCwNAIBQgEiADQQJ0aigCAEEkbGoiAioCGLsiByACKgIMuyIIIAIqAgC7IgkgBCAEIAljGyIEIAQgCGMbIgQgBCAHYxshBCAHIAggCSAGIAYgCWQbIgYgBiAIZBsiBiAGIAdkGyEGIAIqAiC7IgcgAioCFLsiCCACKgIIuyIJIAwgCSAMZBsiDCAIIAxkGyIMIAcgDGQbIQwgByAIIAkgCiAJIApjGyIKIAggCmMbIgogByAKYxshCiACKgIcuyIHIAIqAhC7IgggAioCBLsiCSALIAkgC2QbIgsgCCALZBsiCyAHIAtkGyELIAcgCCAJIAUgBSAJZBsiBSAFIAhkGyIFIAUgB2QbIQUgA0EBaiIDIAFHDQALCyAOKAIYIBFBMGxqIgIgBTkDCCACIAY5AwAgAiAMOQMoIAIgCzkDICACIAQ5AxggAiAKOQMQAkAgAUEFSQRAIA4oAiQgEUEDdGoiAiABQQFqNgIEIAIgDzYCAAwBCyANQQBBAUECIAsgBaEiBSAMIAqhIgpmGyICIAQgBqEiBCAKZhsgAiAEIAVmGzYCUCAOKAIMIA9BAnRqIgMgAUECdGohDyANIA1B0ABqNgIMIA0gDUFAazYCCAJAIAEiAkGBAU4EQANAIAJBAnQQNiISDQIgAkEBdiICDQALCyADIA8gDUEIaiABQQBBABAUDAELIAMgDyANQQhqIAEgEiACEBQgEhAvCyARQQFqIQEgAEEIayARNgIAIA0CfyAVKAIAIgBBBE0EQCANKAIgQRBrDAELIBNBATYCACAQKAIAIQIgDUIANwIQIA0gAEEBdjYCDCANIAI2AgggDSANKAIgIgA2AkwgDSgCJCECIA0gDUEcajYCWCANIA1BCGo2AlQgDSANQcwAajYCUCAAIAJJBEAgACANKQIQNwIIIAAgDSkCCDcCACAAQRBqDAELIA1B0ABqEBMgDSgCTAsiADYCICABIRELIA0oAhwiASAARw0ACyABBEAgDSABNgIgIA0oAiQaIAEQLwsgDSgCMCICBEADQCACKAIAIQAgAhAvIAAiAg0ACwsgDSgCKCEAIA1BADYCKCAABEAgDSgCLBogABAvCyANKAJAIgAEQCANIAA2AkQgDSgCSBogABAvCyANQeAAaiQAIA4PCxAGAAuRAgEGfwJAAkACQCAAKAIEIgIgACgCACIEayIGQQJ1IgMgAUkEQCAAKAIIIARrIgVBAnUgAU8EQCABIANrQQJ0IgEEQCACQQAgAfwLAAsgACABIAJqNgIEDwsgAUGAgICABE8NAkH/////AyAFQQF1IgIgASABIAJJGyAFQfz///8HTxsiAkGAgICABE8NAyACQQJ0IgUQNSIHIAZqIQIgASADa0ECdCIBBEAgAkEAIAH8CwALIAIgA0ECdGshAyAGBEAgAyAEIAb8CgAACyAAIAUgB2o2AgggACABIAJqNgIEIAAgAzYCACAERQ0BIAQQLw8LIAEgA08NACAAIAQgAUECdGo2AgQLDwsQBgALEAcAC9ICAQV/IwBBIGsiAyQAIAMgADYCEAJ/QQEgAEEFSQ0AGgJAIAEoAgQiBEUNACABKAIMRQ0AIAEoAgACfyAEQQFrIABxIARpIgVBAU0NABogACAAIARJDQAaIAAgBHALIgZBAnRqKAIAIgJFDQAgAigCACICRQ0AAkAgBUEBTQRAIARBAWshBANAAkAgACACKAIEIgVHBEAgBCAFcSAGRg0BDAULIAIoAgggAEYNAwsgAigCACICDQALDAILA0ACQCAAIAIoAgQiBUcEQCAEIAVNBH8gBSAEcAUgBQsgBkYNAQwECyACKAIIIABGDQILIAIoAgAiAg0ACwwBCyACKAIMDAELIAMgAEEBdiIGIAEQEiAAIAZrIAEQEmpBAWo2AgwgAyABNgIcIANBFGogA0EcaiADQRBqIgAgACADQQxqEBUgAygCDAshAiADQSBqJAAgAgvaAQEIfwJAIAAoAggiAygCBCADKAIAIgVrIgRBBHUiB0EBaiIBQYCAgIABSQRAQf////8AIAMoAgggBWsiAkEDdSIGIAEgASAGSRsgAkHw////B08bIgFBgICAgAFPDQEgACgCBCECIAFBBHQiBhA1IgggBGoiASACKQIINwIIIAEgAikCADcCACABIAdBBHRrIQIgBARAIAIgBSAE/AoAAAsgAyAGIAhqNgIIIAMgAUEQaiIENgIEIAMgAjYCACAFBEAgBRAvCyAAKAIAIAQ2AgAPCxAGAAsQBwALkQUBBX8CQAJAAkAgAw4DAgIAAQsgAigCBCgCAEEDdCIDIAIoAgAoAgAiAiABQQRrIgEoAgAiBEEYbGpqKwMAIAMgAiAAKAIAIgNBGGxqaisDAGNFDQEgACAENgIAIAEgAzYCAA8LIANBgAFMBEAgACABRg0BIABBBGoiAyABRg0BIAIoAgQhBiACKAIAKAIAIQUgACEEA0AgAyECIAUgBCgCBCIHQRhsaiIIIAYoAgBBA3QiA2orAwAgAyAFIAQoAgAiA0EYbGpqKwMAYwRAIAQgAzYCBAJ/IAAiAyADIARGDQAaAkADQCAIIAYoAgBBA3QiA2orAwAgAyAFIARBBGsiAygCACIJQRhsamorAwBjRQ0BIAQgCTYCACADIgQgAEcNAAsgAAwBCyAECyAHNgIACyACIgRBBGoiAyABRw0ACwwBCyADIANBAXYiB2shCCAAIAdBAnQiCWohBgJAIAMgBUwEQCAAIAYgAiAHIAQQISAGIAEgAiAIIAQgCWoiARAhIAQgA0ECdGohBSACKAIEIQYgAigCACEHIAEhAwNAIAMgBUcEQCAAIAMoAgAiAiAEKAIAIgggBigCAEEDdCIJIAcoAgAiCiACQRhsamorAwAgCiAIQRhsaiAJaisDAGMiAhs2AgAgA0EEQQAgAhtqIQMgAEEEaiEAIAEgBEEAQQQgAhtqIgRHDQEMAwsLIAEgBEYNAgNAIAAgBCgCADYCACAAQQRqIQAgBEEEaiIEIAFHDQALDAILIAAgBiACIAcgBCAFEBQgBiABIAIgCCAEIAUQFCAAIAYgASACIAcgCCAEIAUQIg8LIAMgBUYNAANAIAAgAygCADYCACAAQQRqIQAgA0EEaiIDIAVHDQALCwvJBQIFfwJ9IAIoAgAhByAAAn8CQCABKAIAIgYoAgQiAUUNACAGKAIAAn8gAUEBayAHcSABaSIIQQFNDQAaIAcgASAHSw0AGiAHIAFwCyIFQQJ0aigCACICRQ0AIAIoAgAiAkUNACAIQQFNBEAgAUEBayEIA0ACQCAHIAIoAgQiCUcEQCAIIAlxIAVHDQQMAQsgAigCCCAHRw0AQQAMBAsgAigCACICDQALDAELA0ACQCAHIAIoAgQiCEcEQCABIAhNBH8gCCABcAUgCAsgBUcNAwwBCyACKAIIIAdHDQBBAAwDCyACKAIAIgINAAsLQRAQNSICIAc2AgQgAkEANgIAIAIgAygCADYCCCACIAQoAgA2AgwCQCAGKAIMQQFqsyIKIAYqAhAiCyABs5ReRQ0AQQIhBQJAIAEgAUEBa3FBAEcgAUEDSXIgAUEBdHIiAyAKIAuVjfwBIgQgAyAESxsiA0EBRg0AIAMgA0EBa3FFBEAgAyEFDAELIAMQMiEFIAYoAgQhAQsCQCABIAVPBEAgASAFTQ0BIAYoAgyzIAYqAhCVjfwBIQMgBQJ/AkAgAUEDSQ0AIAFpQQFLDQAgA0EBQSAgA0EBa2drdCADQQJJGwwBCyADEDILIgggBSAISxsiBSABTw0BCyAGIAUQDwsgBigCBCIBIAFBAWsiA3FFBEAgAyAHcSEFDAELIAEgB0sEQCAHIQUMAQsgByABcCEFCwJAIAYoAgAiBCAFQQJ0aiIFKAIAIgNFBEAgAiAGKAIINgIAIAYgAjYCCCAFIAZBCGo2AgAgAigCACIDRQ0BIAMoAgQhAwJAIAEgAUEBayIFcUUEQCADIAVxIQMMAQsgASADSw0AIAMgAXAhAwsgBCADQQJ0aiACNgIADAELIAIgAygCADYCACADIAI2AgALIAYgBigCDEEBajYCDEEBCzoABCAAIAI2AgALBwAgACgCCAtDACABIAAoAhgiACsDADkDACABIAArAwg5AwggASAAKwMQOQMQIAEgACsDGDkDGCABIAArAyA5AyAgASAAKwMoOQMoC7IBAgF/BnwjAEHwAGsiByQAIAcgASsDACIIOQNQIAcgASsDCCIJOQNYIAcgASsDECIKOQNgIAcgAisDACILOQM4IAcgAisDCCIMOQNAIAcgAisDECINOQNIIAcgCDkDICAHIAk5AyggByAKOQMwIAcgCzkDCCAHIAw5AxAgByANOQMYIAAgB0EgaiAHQQhqIAMgBCAFIAdB6ABqEBkhACAGIAcrA2g5AwAgB0HwAGokACAAC/gJAgl/F3wjAEEwayIIJAAgAisDACEQIAIrAwghESACKwMQIRIgCEEEEDUiCTYCECAIIAlBBGoiBzYCGCAJQQA2AgBEAAAAAAAA8D8gEqMhIkQAAAAAAADwPyARoyEjRAAAAAAAAPA/IBCjISQgASsDECEaIAErAwghGyABKwMAIRxBfyENA0AgB0EEayIKKAIAIQsgCCAKNgIUAkAgJCAAKAIYIAtBMGxqIgErAxggHKGiIhAgJCABKwMAIByhoiIRIBAgEWMiDBsiEiADIAMgEmMbIhIgESAQIAwbIhAgBCAEIBBkGyIQZARAIAohBwwBCyAjIAErAyAgG6GiIhEgIyABKwMIIBuhoiITIBEgE2MiDBsiFCASIBIgFGMbIhIgEyARIAwbIhEgECAQIBFkGyIQZARAIAohBwwBCyAiIAErAyggGqGiIhEgIiABKwMQIBqhoiITIBEgE2MiARsiFCASIBIgFGMbIBMgESABGyIRIBAgECARZBtlRQRAIAohBwwBCyAAKAIkIAtBA3RqIgEoAgQiDARAIAxBAWsiDkUEQCAKIQcMAgsgACgCDCABKAIAQQJ0aiEPIAIrAxAhHSACKwMIIR4gAisDACEfQQAhAQNAIAUgDyABQQJ0aigCACILRwRAIAtBCWwhByAAKAIAIQxEAAAAAAAA8H8hIAJAAnwgAC0ABEEBRgRAIAwgB0EDdGoiBysDOCAHKwMIIhChIREgBysDMCAHKwMAIhKhIRMgBysDICAQoSEUIAcrAxggEqEhFyAHQUBrKwMAIRYgBysDKCAHKwMQIhWhDAELIAwgB0ECdGoiByoCHLsgByoCBLsiEKEhESAHKgIYuyAHKgIAuyISoSETIAcqAhC7IBChIRQgByoCDLsgEqEhFyAHKgIguyEWIAcqAhS7IAcqAgi7IhWhCyIlIB8gEaIgHiAToqEiGKIgFyAeIBYgFaEiFqIgHSARoqEiGaIgFCAdIBOiIB8gFqKhIiGioKAiJplEEeotgZmXcT1jDQAgGiAVoSIVIBiiIBwgEqEiEiAZoiAbIBChIhAgIaKgoEQAAAAAAADwPyAmoyIYoiIZRAAAAAAAAAAAYw0AIBlEAAAAAAAA8D9kDQAgHSASIBSiIBcgEKKhIiGiIB8gJSAQoiAVIBSioSIQoiAeIBcgFaIgJSASoqEiEqKgoCAYoiIURAAAAAAAAAAAYw0AIBkgFKBEAAAAAAAA8D9kDQAgEyAQoiARIBKioCAhIBaioCAYoiIQRAAAAAAAAPB/IAMgEGMbISALIAsgDSAEICBkIgcbIQ0gICAEIAcbIQQLIAFBAWoiASAORw0ACyAKIQcMAQsgC0EBdCEBIAggC0EBaiIJNgIMIAggCjYCHCAIKAIYIQsgCCAIQRBqNgIoIAggCEEMajYCJCAIIAhBHGo2AiACQCAKIAtJBEAgCiAJNgIADAELIAhBIGoQGiAIKAIcIQcLIAggBzYCFCAAKAIkIQogCCAHNgIcIAgoAhghCSAIIAogAUECdGoiATYCJCAIIAhBEGo2AiggCCAIQRxqNgIgIAgCfyAHIAlJBEAgByABKAIANgIAIAdBBGoMAQsgCEEgahAaIAgoAhwLIgc2AhQgCCgCECEJCyAHIAlHDQALIAYgBDkDACAJBEAgCCAJNgIUIAgoAhgaIAkQLwsgCEEwaiQAIA0L0AEBCH8CQCAAKAIIIgIoAgQgAigCACIEayIDQQJ1IgVBAWoiAUGAgICABEkEQEH/////AyACKAIIIARrIgZBAXUiByABIAEgB0kbIAZB/P///wdPGyIBQYCAgIAETw0BIAAoAgQhBiABQQJ0IgcQNSIIIANqIgEgBigCADYCACABIAVBAnRrIQUgAwRAIAUgBCAD/AoAAAsgAiAHIAhqNgIIIAIgAUEEaiIDNgIEIAIgBTYCACAEBEAgBBAvCyAAKAIAIAM2AgAPCxAGAAsQBwALtAoCCn8IfCMAQeAAayIDJAAgASsDECEOIAErAwghDyABKwMAIRAgA0EEEDUiBjYCUCADIAZBBGoiATYCWCAGQQA2AgAgACgCGCEIRAAAAAAAAPB/IRFEAAAAAAAA+H8hEkF/IQpEAAAAAAAA+H8hE0QAAAAAAAD4fyEUA0AgAUEEayIFKAIAIQcgAyAFNgJUAkAgEQJ8IAggB0EwbGoiBCsDACINIBBkBEAgDSAQoQwBCyAQIAQrAxgiDaFEAAAAAAAAAAAgDSAQYxsLIg0gDaICfCAEKwMIIg0gD2QEQCANIA+hDAELIA8gBCsDICINoUQAAAAAAAAAACANIA9jGwsiDSANoqACfCAEKwMQIg0gDmQEQCANIA6hDAELIA4gBCsDKCINoUQAAAAAAAAAACANIA5jGwsiDSANoqBjBEAgBSEBDAELIAAoAiQgB0EDdGoiBCgCBCIJBEAgCUEBayIHRQRAIAUhAQwCCyAAKAIMIQEgBCgCACEEIAMgDjkDMCADIA85AyggAyAQOQMgIAEgBEECdGohCSAALQAEIQsgACgCACEMQQAhAQNAIAkgAUECdGooAgAhBCADIAMpAyA3AwAgAyADKQMoNwMIIAMgAykDMDcDECARIAMgDCALIARBCWwgA0E4ahAcIg1kBEAgAysDSCEUIAMrA0AhEyADKwM4IRIgBCEKIA0hEQsgAUEBaiIBIAdHDQALIAUhAQwBCyADIAdBAWoiBjYCHCADIAQoAgAiBzYCGCADAn8CQAJ8IAggBkEwbGoiBCsDACINIBBkBEAgDSAQoQwBCyAQIAQrAxgiDaFEAAAAAAAAAAAgDSAQYxsLIg0gDaICfCAEKwMIIg0gD2QEQCANIA+hDAELIA8gBCsDICINoUQAAAAAAAAAACANIA9jGwsiDSANoqACfCAEKwMQIg0gDmQEQCANIA6hDAELIA4gBCsDKCINoUQAAAAAAAAAACANIA5jGwsiDSANoqACfCAIIAdBMGxqIgQrAwAiDSAQZARAIA0gEKEMAQsgECAEKwMYIg2hRAAAAAAAAAAAIA0gEGMbCyINIA2iAnwgBCsDCCINIA9kBEAgDSAPoQwBCyAPIAQrAyAiDaFEAAAAAAAAAAAgDSAPYxsLIg0gDaKgAnwgBCsDECINIA5kBEAgDSAOoQwBCyAOIAQrAygiDaFEAAAAAAAAAAAgDSAOYxsLIg0gDaKgYwRAIAMgBTYCXCADKAJYIQQgAyADQdAAajYCQCADIANBGGo2AjwgAyADQdwAajYCOAJAIAQgBUsEQCAFIAc2AgAMAQsgA0E4ahAaIAMoAlwhAQsgAyABNgJUIAMgATYCXCADKAJYIQUgAyADQdAAajYCQCADIANBHGo2AjwgAyADQdwAajYCOCABIAVJBEAgASADKAIcNgIAIAFBBGoMAwsMAQsgAyAFNgJcIAMoAlghBCADIANB0ABqNgJAIAMgA0EcajYCPCADIANB3ABqNgI4AkAgBCAFSwRAIAUgBjYCAAwBCyADQThqEBogAygCXCEBCyADIAE2AlQgAyABNgJcIAMoAlghBSADIANB0ABqNgJAIAMgA0EYajYCPCADIANB3ABqNgI4IAEgBUkEQCABIAMoAhg2AgAgAUEEagwCCwsgA0E4ahAaIAMoAlwLIgE2AlQgAygCUCEGCyABIAZHDQALIAIgFDkDECACIBM5AwggAiASOQMAIAIgEZ85AxggBgRAIAMgBjYCVCADKAJYGiAGEC8LIANB4ABqJAAgCgueBwEbfAJ8IAJBAXEEQCABIANBA3RqIgErAwAhBSABQUBrKwMAIRAgASsDOCERIAErAzAhEiABKwMoIQYgASsDICELIAErAxghDiABKwMIIQcgASsDEAwBCyABIANBAnRqIgEqAgC7IQUgASoCILshECABKgIcuyERIAEqAhi7IRIgASoCFLshBiABKgIQuyELIAEqAgy7IQ4gASoCBLshByABKgIIuwshCCASIAWhIhMgACsDACIaIAWhIgmiIBEgB6EiFCAAKwMIIhsgB6EiCqKgIBAgCKEiFSAAKwMQIhwgCKEiDKKgIQ0CQCAOIAWhIhYgCaIgCyAHoSIXIAqioCAGIAihIhggDKKgIgxEAAAAAAAAAABlIA1EAAAAAAAAAABlcQ0AIBMgGiAOoSIJoiAUIBsgC6EiCqKgIBUgHCAGoSIPoqAhGQJAIBYgCaIgFyAKoqAgGCAPoqAiCUQAAAAAAAAAAGZFDQAgCSAZZkUNACAOIQUgCyEHIAYhCAwBCyAMIBmiIAkgDaKhIR0CQCAJRAAAAAAAAAAAZUUNACAMRAAAAAAAAAAAZkUNACAdRAAAAAAAAAAAZUUNACAIIBggDCAMIAmhoyIGoqAhCCAHIBcgBqKgIQcgBSAWIAaioCEFDAELIBYgGiASoSIKoiAXIBsgEaEiHqKgIBggHCAQoSIfoqAhDwJAIBMgCqIgFCAeoqAgFSAfoqAiCkQAAAAAAAAAAGZFDQAgCiAPZkUNACASIQUgESEHIBAhCAwBCyAPIA2iIAwgCqKhIQwCQCAKRAAAAAAAAAAAZUUNACANRAAAAAAAAAAAZkUNACAMRAAAAAAAAAAAZUUNACAIIBUgDSANIAqhoyIGoqAhCCAHIBQgBqKgIQcgBSATIAaioCEFDAELAkAgCSAKoiAPIBmioSIeRAAAAAAAAAAAZUUNACAZIAmhIg1EAAAAAAAAAABmRQ0AIA8gCqEiCUQAAAAAAAAAAGZFDQAgBiAQIAahIA0gDSAJoKMiBaKgIQggCyARIAuhIAWioCEHIA4gEiAOoSAFoqAhBQwBCyAVIB1EAAAAAAAA8D8gHSAeIAygoKMiC6IiBqIgCCAYIAwgC6IiC6KgoCEIIBQgBqIgByAXIAuioKAhByATIAaiIAUgFiALoqCgIQULIAQgCDkDECAEIAc5AwggBCAFOQMAIBogBaEiBSAFoiAbIAehIgUgBaKgIBwgCKEiBSAFoqALhj8CM3wZfyMAQaACayI2JAAgNkEIEDUiOTYClAEgNiA5QQhqIjg2ApwBIDlCADcCACA2QeABaiFEIAEoAhghSSAAKAIYIUpEAAAAAAAA8H8hLwNAIDhBBGsoAgAhPyA4QQhrIkIoAgAhQCA2IEI2ApgBAkACfCBKIEBBMGxqIjwrAwAiBCBJID9BMGxqIj0rAxgiCWQEQCAEIAmhDAELID0rAwAiBSA8KwMYIgOhRAAAAAAAAAAAIAMgBWMbCyIDIAOiAnwgPCsDCCIKID0rAyAiCGRFBEAgPSsDCCIFIDwrAyAiA6FEAAAAAAAAAAAgAyAFYxsMAQsgCiAIoQsiAyADoqACfCA8KwMQIgYgPSsDKCIHZEUEQCA9KwMQIgUgPCsDKCIDoUQAAAAAAAAAACADIAVjGwwBCyAGIAehCyIDIAOioCAvZg0AIAEoAiQgP0EDdGoiOCgCBCE+AkAgACgCJCBAQQN0aiI3KAIEIjlFDQAgPkUNACA5QQFrIj1FDQEgPkEBayI/RQ0BIAEoAgwgOCgCAEECdGohQCAAKAIMIDcoAgBBAnRqIUIgAS0ABCFFIAEoAgAhQSAAKAIAIUNBACFLIAAtAAQiTEEBcSFGA0AgQyBCIEtBAnRqKAIAQQlsIkdBA3RqIjtBQGshSCBDIEdBAnRqITpBACFNA0AgQCBNQQJ0aigCACE5AnwgRkUEQCA6KgIguyEeIDoqAhy7IR8gOioCGLshICA6KgIUuyEWIDoqAhC7IQsgOioCDLshDCA6KgIEuyEOIDoqAgC7IQ8gOioCCLsMAQsgSCsDACEeIDsrAzghHyA7KwMwISAgOysDKCEWIDsrAyAhCyA7KwMYIQwgOysDCCEOIDsrAwAhDyA7KwMQCyEEIDlBCWwhPiA2IB45A5ACIDYgHzkDiAIgNiAgOQOAAiA2IBY5A/gBIDYgCzkD8AEgNiAMOQPoASA2IAQ5A+ABIDYgDjkD2AEgNiAPOQPQAQJ8IEVBAXEiOUUEQCBBID5BAnRqIjcqAhy7IiQgNyoCBLsiG6EhAyA3KgIYuyIlIDcqAgC7IhyhIRUgNyoCFLsiJiA3KgIIuyIdoSESIDcqAhC7IicgG6EhFCA3KgIguyEjIDcqAgy7IiggHKEMAQsgQSA+QQN0aiI3KwM4IiQgNysDCCIboSEDIDcrAzAiJSA3KwMAIhyhIRUgNysDKCImIDcrAxAiHaEhEiA3KwMgIicgG6EhFCA3QUBrKwMAISMgNysDGCIoIByhCyEZAkACQAJAAkACQCASIAwgD6EiCSADoiALIA6hIg0gFaKhIgiiIBkgDSAjIB2hIheiIBYgBKEiESADoqEiBqIgFCARIBWiIAkgF6KhIgeioKAiBZlEEeotgZmXcT1jDQAgBCAdoSIYIAiiIA8gHKEiEyAGoiAOIBuhIgYgB6KgoEQAAAAAAADwPyAFoyIQoiIKRAAAAAAAAAAAYw0AIApEAAAAAAAA8D9kDQAgESATIBSiIBkgBqKhIgiiIAkgEiAGoiAYIBSioSIGoiANIBkgGKIgEiAToqEiB6KgoCAQoiIFRAAAAAAAAAAAYw0AIAogBaBEAAAAAAAA8D9kDQAgFSAGoiADIAeioCAIIBeioCAQoiIDRAAAAAAAAAAAZEUNACADRAAAAAAAAPA/ZQ0BCyAeIBahIREgHyALoSENICAgDKEhCQJAAnwgOUUEQCBBID5BAnRqIjcqAhy7IDcqAgS7IhKhIQMgNyoCGLsgNyoCALsiFKEhFSA3KgIQuyASoSEIIDcqAgy7IBShIQogNyoCILshBiA3KgIUuyA3KgIIuyIFoQwBCyBBID5BA3RqIjcrAzggNysDCCISoSEDIDcrAzAgNysDACIUoSEVIDcrAyAgEqEhCCA3KwMYIBShIQogN0FAaysDACEGIDcrAyggNysDECIFoQsiGSAJIAOiIA0gFaKhIhOiIAogDSAGIAWhIheiIBEgA6KhIhCiIAggESAVoiAJIBeioSIGoqCgIgeZRBHqLYGZl3E9Yw0AIBYgBaEiGCAToiAMIBShIhMgEKIgCyASoSIFIAaioKBEAAAAAAAA8D8gB6MiEKIiEkQAAAAAAAAAAGMNACASRAAAAAAAAPA/ZA0AIBEgEyAIoiAKIAWioSIUoiAJIBkgBaIgGCAIoqEiBqIgDSAKIBiiIBkgE6KhIgeioKAgEKIiBUQAAAAAAAAAAGMNACASIAWgRAAAAAAAAPA/ZA0AIBUgBqIgAyAHoqAgFCAXoqAgEKIiA0QAAAAAAAAAAGRFDQAgA0QAAAAAAADwP2VFDQAgDCEPIAshDiAWIQQMAQsgBCAeoSERIA4gH6EhDSAPICChIQkCfCA5RQRAIEEgPkECdGoiOSoCHLsgOSoCBLsiEqEhAyA5KgIYuyA5KgIAuyIUoSEVIDkqAhC7IBKhIQggOSoCDLsgFKEhCiA5KgIguyEGIDkqAhS7IDkqAgi7IgWhDAELIEEgPkEDdGoiOSsDOCA5KwMIIhKhIQMgOSsDMCA5KwMAIhShIRUgOSsDICASoSEIIDkrAxggFKEhCiA5QUBrKwMAIQYgOSsDKCA5KwMQIgWhCyIZIAkgA6IgDSAVoqEiE6IgCiANIAYgBaEiF6IgESADoqEiEKIgCCARIBWiIAkgF6KhIgaioKAiB5lEEeotgZmXcT1jDQEgHiAFoSIYIBOiICAgFKEiEyAQoiAfIBKhIgUgBqKgoEQAAAAAAADwPyAHoyIQoiISRAAAAAAAAAAAYw0BIBJEAAAAAAAA8D9kDQEgESATIAiiIAogBaKhIhSiIAkgGSAFoiAYIAiioSIGoiANIAogGKIgGSAToqEiB6KgoCAQoiIFRAAAAAAAAAAAYw0BIBIgBaBEAAAAAAAA8D9kDQEgFSAGoiADIAeioCAUIBeioCAQoiIDRAAAAAAAAAAAZEUNASADRAAAAAAAAPA/ZUUNASAgIQ8gHyEOIB4hBAsgBCARIAOioCEFIA4gDSADoqAhByAPIAkgA6KgIQoMAQsgJiAdoSEVICcgG6EhEiAoIByhIRQCQAJAAkACfCBGRQRAIDoqAhy7IDoqAgS7IhGhIQkgOioCELsgEaEhByA6KgIYuyA6KgIAuyIIoSENIDoqAgy7IAihIQogOioCILshBiA6KgIUuyA6KgIIuyIDoQwBCyA7KwM4IDsrAwgiEaEhCSA7KwMgIBGhIQcgOysDMCA7KwMAIgihIQ0gOysDGCAIoSEKIEgrAwAhBiA7KwMoIDsrAxAiA6ELIhkgFCAJoiASIA2ioSIToiAKIBIgBiADoSIXoiAVIAmioSIQoiAHIBUgDaIgFCAXoqEiBqKgoCIFmUQR6i2BmZdxPWMNACAdIAOhIhggE6IgHCAIoSITIBCiIBsgEaEiAyAGoqCgRAAAAAAAAPA/IAWjIhCiIghEAAAAAAAAAABjDQAgCEQAAAAAAADwP2QNACAVIBMgB6IgCiADoqEiBqIgFCAZIAOiIBggB6KhIgeiIBIgCiAYoiAZIBOioSIFoqCgIBCiIgNEAAAAAAAAAABjDQAgCCADoEQAAAAAAADwP2QNACANIAeiIAkgBaKgIAYgF6KgIBCiIglEAAAAAAAAAABkRQ0AIAlEAAAAAAAA8D9lDQELICMgJqEhLCAkICehIS0gJSAooSEZAnwgRkUEQCA6KgIcuyA6KgIEuyIRoSEJIDoqAhS7IDoqAgi7IgOhIQogOioCELsgEaEhBiA6KgIYuyA6KgIAuyIIoSENIDoqAiC7IQcgOioCDLsgCKEMAQsgOysDOCA7KwMIIhGhIQkgOysDKCA7KwMQIgOhIQogOysDICARoSEGIDsrAzAgOysDACIIoSENIEgrAwAhByA7KwMYIAihCyEiAkAgCiAZIAmiIC0gDaKhIhOiICIgLSAHIAOhIiGiICwgCaKhIhCiIAYgLCANoiAZICGioSIHoqCgIgWZRBHqLYGZl3E9Yw0AICYgA6EiFyAToiAoIAihIhggEKIgJyARoSIDIAeioKBEAAAAAAAA8D8gBaMiE6IiEEQAAAAAAAAAAGMNACAQRAAAAAAAAPA/ZA0AICwgGCAGoiAiIAOioSIIoiAZIAogA6IgFyAGoqEiB6IgLSAiIBeiIAogGKKhIgWioKAgE6IiA0QAAAAAAAAAAGMNACAQIAOgRAAAAAAAAPA/ZA0AIA0gB6IgCSAFoqAgCCAhoqAgE6IiCUQAAAAAAAAAAGRFDQAgCUQAAAAAAADwP2VFDQAgKCEcICchGyAmIR0gGSEUIC0hEiAsIRUMAQsgHSAjoSEXIBsgJKEhGCAcICWhIRMCfCBGRQRAIDoqAhy7IDoqAgS7IgehIQkgOioCFLsgOioCCLsiCqEhESA6KgIYuyA6KgIAuyIIoSENIDoqAgy7IAihIQUgOioCILshBiA6KgIQuyAHoQwBCyA7KwM4IDsrAwgiB6EhCSA7KwMoIDsrAxAiCqEhESA7KwMwIDsrAwAiCKEhDSA7KwMYIAihIQUgSCsDACEGIDsrAyAgB6ELISkgESATIAmiIBggDaKhIiGiIAUgGCAGIAqhIi6iIBcgCaKhIhCiICkgFyANoiATIC6ioSIGoqCgIgOZRBHqLYGZl3E9Yw0BICMgCqEiIiAhoiAlIAihIiEgEKIgJCAHoSIHIAaioKBEAAAAAAAA8D8gA6MiCqIiCEQAAAAAAAAAAGMNASAIRAAAAAAAAPA/ZA0BIBcgISApoiAFIAeioSIGoiATIBEgB6IgIiApoqEiB6IgGCAFICKiIBEgIaKhIgWioKAgCqIiA0QAAAAAAAAAAGMNASAIIAOgRAAAAAAAAPA/ZA0BIA0gB6IgCSAFoqAgBiAuoqAgCqIiCUQAAAAAAAAAAGRFDQEgCUQAAAAAAADwP2VFDQEgJSEcICQhGyAjIR0gEyEUIBghEiAXIRULIB0gFSAJoqAhBSAbIBIgCaKgIQcgHCAUIAmioCEKDAELIDYgHTkDsAEgNiAbOQOoASA2IBw5A6ABIDYgHDkDeCA2IBs5A4ABIDYgHTkDiAFEAAAAAAAA8H8hAwJ8IDZB+ABqIEMgTCBHIDZBuAFqEBwiBUQAAAAAAADwf2QgBUQAAAAAAADwf2MiOHJFBEBEAAAAAAAAAAAhCkQAAAAAAAAAACEHRAAAAAAAAAAAIQhEAAAAAAAAAAAhBkQAAAAAAAAAACEJRAAAAAAAAAAADAELIDYrA8ABIQcgNisDuAEhCiAcIQggGyEGIB0hCSAFIQMgNisDyAELIQUgNiAmOQOwASA2ICc5A6gBIDYgKDkDoAEgNiAoOQNgIDYgJzkDaCA2ICY5A3AgAyA2QeAAaiBDIEwgRyA2QbgBahAcIhBkBEBBASE4IDYrA8gBIQUgNisDwAEhByA2KwO4ASEKICghCCAnIQYgJiEJIBAhAwsgNiAjOQOwASA2ICQ5A6gBIDYgJTkDoAEgNiAlOQNIIDYgJDkDUCA2ICM5A1ggAyA2QcgAaiBDIEwgRyA2QbgBahAcIhBkBEBBASE4IDYrA8gBIQUgNisDwAEhByA2KwO4ASEKICUhCCAkIQYgIyEJIBAhAwsgNiA2KQPQATcDMCA2IDYpA9gBNwM4IDYgNikD4AE3A0AgAyA2QTBqIEEgRSA+IDZBuAFqEBwiEGQEQEEBITggNisDyAEhCSA2KwPAASEGIDYrA7gBIQggDyEKIA4hByAEIQUgECEDCyA2IDYpA+gBNwMYIDYgNikD8AE3AyAgNiA2KQP4ATcDKCADIDZBGGogQSBFID4gNkG4AWoQHCIEZARAQQEhOCA2KwPIASEJIDYrA8ABIQYgNisDuAEhCCAMIQogCyEHIBYhBSAEIQMLIDYgNikDgAI3AwAgNiA2KQOIAjcDCCA2IDYpA5ACNwMQIAMgNiBBIEUgPiA2QbgBahAcIgRkBEBBASE4IDYrA8gBIQkgNisDwAEhBiA2KwO4ASEIICAhCiAfIQcgHiEFIAQhAwsgEyAToiAYIBiioCAXIBeioCEiIBkgGaIgLSAtoqAgLCAsoqAhISAUIBSiIBIgEqKgIBUgFaKgIRBBACE3A0AgNkHQAWoiPiA3QQFqIjlBACA5QQNHG0EYbGoiPCsDACA3QRhsID5qIjcrAwAiEaEiKiAqoiA8KwMIIDcrAwgiKaEiKyAroqAgPCsDECA3KwMQIi6hIg0gDaKgIRoCQCAQRBHqLYGZl3E9ZSI3BEBEAAAAAAAAAAAhDEQAAAAAAAAAACELIBpEEeotgZmXcT1lDQELIBQgESAcoSIOoiASICkgG6EiD6KgIBUgLiAdoSIEoqAhFiAaRBHqLYGZl3E9ZUUEQCAOICqiIA8gK6KgIAQgDaKgIQ4gN0UEQEQAAAAAAAAAACELIBAgGqIgFCAqoiASICuioCAVIA2ioCIPIA+ioSIERAAAAAAAAAAAYgRARAAAAAAAAAAARAAAAAAAAPA/IBYgD6IgECAOoqEgBKMiBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIQsLIBYgDyALoqAgEKMiDEQAAAAAAAAAAGNFBEAgDEQAAAAAAADwP2RFDQNEAAAAAAAA8D8hDEQAAAAAAAAAAEQAAAAAAADwPyAPIA6hIBqjIgQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyELDAMLRAAAAAAAAAAAIQxEAAAAAAAAAABEAAAAAAAA8D8gDpogGqMiBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIQsMAgtEAAAAAAAAAAAhDEQAAAAAAAAAAEQAAAAAAADwPyAOmiAaoyIEIAREAAAAAAAA8D9kGyAERAAAAAAAAAAAYxshCwwBC0QAAAAAAAAAACELRAAAAAAAAAAARAAAAAAAAPA/IBYgEKMiBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIQwLIAMgLiANIAuioCIeIB0gFSAMoqAiH6EiBCAEoiARICogC6KgIiAgHCAUIAyioCIWoSIEIASiICkgKyALoqAiDiAbIBIgDKKgIg+hIgQgBKKgoCIEZARAQQEhOCAgIQogDiEHIB4hBSAWIQggDyEGIB8hCSAEIQMLAkAgIUQR6i2BmZdxPWUiNwRARAAAAAAAAAAAIQxEAAAAAAAAAAAhCyAaRBHqLYGZl3E9ZQ0BCyAZIBEgKKEiDqIgLSApICehIg+ioCAsIC4gJqEiBKKgIRYgGkQR6i2BmZdxPWVFBEAgDiAqoiAPICuioCAEIA2ioCEOIDdFBEBEAAAAAAAAAAAhCyAhIBqiIBkgKqIgLSAroqAgLCANoqAiDyAPoqEiBEQAAAAAAAAAAGIEQEQAAAAAAAAAAEQAAAAAAADwPyAWIA+iICEgDqKhIASjIgQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyELCyAWIA8gC6KgICGjIgxEAAAAAAAAAABjRQRAIAxEAAAAAAAA8D9kRQ0DRAAAAAAAAPA/IQxEAAAAAAAAAABEAAAAAAAA8D8gDyAOoSAaoyIEIAREAAAAAAAA8D9kGyAERAAAAAAAAAAAYxshCwwDC0QAAAAAAAAAACEMRAAAAAAAAAAARAAAAAAAAPA/IA6aIBqjIgQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyELDAILRAAAAAAAAAAAIQxEAAAAAAAAAABEAAAAAAAA8D8gDpogGqMiBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIQsMAQtEAAAAAAAAAAAhC0QAAAAAAAAAAEQAAAAAAADwPyAWICGjIgQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyEMCyADIC4gDSALoqAiHiAmICwgDKKgIh+hIgQgBKIgESAqIAuioCIgICggGSAMoqAiFqEiBCAEoiApICsgC6KgIg4gJyAtIAyioCIPoSIEIASioKAiBGQEQEEBITggICEKIA4hByAeIQUgFiEIIA8hBiAfIQkgBCEDCwJAICJEEeotgZmXcT1lIjcEQEQAAAAAAAAAACEMRAAAAAAAAAAAIQsgGkQR6i2BmZdxPWUNAQsgEyARICWhIg6iIBggKSAkoSIPoqAgFyAuICOhIgSioCEWIBpEEeotgZmXcT1lRQRAIA4gKqIgDyAroqAgBCANoqAhDiA3RQRARAAAAAAAAAAAIQsgIiAaoiATICqiIBggK6KgIBcgDaKgIg8gD6KhIgREAAAAAAAAAABiBEBEAAAAAAAAAABEAAAAAAAA8D8gFiAPoiAiIA6ioSAEoyIEIAREAAAAAAAA8D9kGyAERAAAAAAAAAAAYxshCwsgFiAPIAuioCAioyIMRAAAAAAAAAAAY0UEQCAMRAAAAAAAAPA/ZEUNA0QAAAAAAADwPyEMRAAAAAAAAAAARAAAAAAAAPA/IA8gDqEgGqMiBCAERAAAAAAAAPA/ZBsgBEQAAAAAAAAAAGMbIQsMAwtEAAAAAAAAAAAhDEQAAAAAAAAAAEQAAAAAAADwPyAOmiAaoyIEIAREAAAAAAAA8D9kGyAERAAAAAAAAAAAYxshCwwCC0QAAAAAAAAAACEMRAAAAAAAAAAARAAAAAAAAPA/IA6aIBqjIgQgBEQAAAAAAADwP2QbIAREAAAAAAAAAABjGyELDAELRAAAAAAAAAAAIQtEAAAAAAAAAABEAAAAAAAA8D8gFiAioyIEIAREAAAAAAAA8D9kGyAERAAAAAAAAAAAYxshDAsgAyAuIA0gC6KgIh4gIyAXIAyioCIfoSIEIASiIBEgKiALoqAiICAlIBMgDKKgIhahIgQgBKIgKSArIAuioCIOICQgGCAMoqAiD6EiBCAEoqCgIgRkBEBBASE4ICAhCiAOIQcgHiEFIBYhCCAPIQYgHyEJIAQhAwsgOSI3QQNHDQALDAELRAAAAAAAAAAAIQNBASE4IAohCCAHIQYgBSEJCyADIC9jBEAgCSEwIAYhMSAIITIgBSEzIAchNCAKITUgAyEvIDghTgsgTUEBaiJNID9HDQALIEtBAWoiSyA9Rw0ACwwBCwJAIDkNACA+RQRAIDwrAxggBKEgPCsDICAKoaAgPCsDKCAGoaAgCSA9KwMAoSAIID0rAwihoCAHID0rAxChoGZFDQELIDcoAgAhNwJ8IAkgSiBAQQFqIjlBMGxqIjgrAwAiA2MEQCADIAmhDAELID0rAwAiBSA4KwMYIgOhRAAAAAAAAAAAIAMgBWMbCyIDIAOiAnwgOCsDCCIDIAhkRQRAID0rAwgiBSA4KwMgIgOhRAAAAAAAAAAAIAMgBWMbDAELIAMgCKELIgMgA6KgAnwgOCsDECIDIAdkRQRAID0rAxAiBSA4KwMoIgOhRAAAAAAAAAAAIAMgBWMbDAELIAMgB6ELIgMgA6KgAnwgCSBKIDdBMGxqIjgrAwAiA2MEQCADIAmhDAELID0rAwAiBSA4KwMYIgOhRAAAAAAAAAAAIAMgBWMbCyIDIAOiAnwgOCsDCCIDIAhkRQRAID0rAwgiBSA4KwMgIgOhRAAAAAAAAAAAIAMgBWMbDAELIAMgCKELIgMgA6KgAnwgOCsDECIDIAdkRQRAID0rAxAiBSA4KwMoIgOhRAAAAAAAAAAAIAMgBWMbDAELIAMgB6ELIgMgA6KgYwRAIDYgPzYC3AEgNiA5NgLYASA2ID82AtQBIDYgNzYC0AEgNkGUAWogQiA2QdABaiBEEB4MAgsgNiA/NgLcASA2IDc2AtgBIDYgPzYC1AEgNiA5NgLQASA2QZQBaiBCIDZB0AFqIEQQHgwBCyA4KAIAITcCfCBJID9BAWoiOUEwbGoiOCsDGCIDIARjBEAgBCADoQwBCyA4KwMAIgUgPCsDGCIDoUQAAAAAAAAAACADIAVjGwsiAyADogJ8IAogOCsDICIDZEUEQCA4KwMIIgUgPCsDICIDoUQAAAAAAAAAACADIAVjGwwBCyAKIAOhCyIDIAOioAJ8IAYgOCsDKCIDZEUEQCA4KwMQIgUgPCsDKCIDoUQAAAAAAAAAACADIAVjGwwBCyAGIAOhCyIDIAOioAJ8IEkgN0EwbGoiOCsDGCIDIARjBEAgBCADoQwBCyA4KwMAIgUgPCsDGCIDoUQAAAAAAAAAACADIAVjGwsiAyADogJ8IAogOCsDICIDZEUEQCA4KwMIIgUgPCsDICIDoUQAAAAAAAAAACADIAVjGwwBCyAKIAOhCyIDIAOioAJ8IAYgOCsDKCIDZEUEQCA4KwMQIgUgPCsDKCIDoUQAAAAAAAAAACADIAVjGwwBCyAGIAOhCyIDIAOioGMEQCA2IDk2AtwBIDYgQDYC2AEgNiA3NgLUASA2IEA2AtABIDZBlAFqIEIgNkHQAWogRBAeDAELIDYgNzYC3AEgNiBANgLYASA2IDk2AtQBIDYgQDYC0AEgNkGUAWogQiA2QdABaiBEEB4LIDYoApQBIjkgNigCmAEiOEcgL0QAAAAAAAAAAGRxDQALQQEhOCACAnwgTkEBcUUEQEEAIThEAAAAAAAA8H8MAQsgAiAwOQNIIAIgMTkDQCACIDI5AzggAiAzOQMwIAIgNDkDKCACIDU5AyAgAiAwIDOgRAAAAAAAAOA/ojkDGCACIDEgNKBEAAAAAAAA4D+iOQMQIAIgMiA1oEQAAAAAAADgP6I5AwggL58LOQMAIDkEQCA2IDk2ApgBIDYoApwBGiA5EC8LIDZBoAJqJAAgOAuqBAEFfwJAAkACQCAAKAIIIgUgACgCBCIGa0ECdUEETgRAIAYgAWsiB0ECdSIIQQRIBEACQCADIAIgB2oiBUYEQCAGIQQMAQsgBiEEA0AgBCAFKAIANgIAIARBBGohBCAFQQRqIgUgA0cNAAsLIAAgBDYCBCAIQQBMDQIgBCABQRBqayEIAkAgBiAEQRBrIgNNBEAgBCEFDAELIAQhBQNAIAUgAygCADYCACAFQQRqIQUgA0EEaiIDIAZJDQALCyAAIAU2AgQgCARAIAQgCGsgASAI/AoAAAsgB0UNAiABIAIgB/wKAAAPCyAGIgQgBEEQayIFSwRAQQAhAwNAIAQgBSgCADYCACAEQQRqIQQgBUEEaiEFIANBAWoiA0EERw0ACwsgACAENgIEIAYgAUEQamsiAARAIAYgAGsgASAA/AoAAAsgASACQRD8CgAADwsgBiAAKAIAIgNrQQJ1QQRqIgRBgICAgARPDQFB/////wMgBSADayIFQQF1IgcgBCAEIAdJGyAFQfz///8HTxsiBAR/IARBgICAgARPDQMgBEECdBA1BUEACyEHIAcgASADayIFaiIIIAJBEPwKAAAgCEEQaiECIAYgAWsiBgRAIAIgASAG/AoAAAsgACABNgIEIAggBUF8cWshASAFBEAgASADIAX8CgAACyAAIAcgBEECdGo2AgggACACIAZqNgIEIAAgATYCACADBEAgAxAvCwsPCxAGAAsQBwALlgoCB38cfCMAQfAAayIIJAAgACgCCCIJBH8gAUUEQCAAKAIYIgErAxggASsDAKEiAiACoiABKwMgIAErAwihIgIgAqKgIAErAyggASsDEKEiAiACoqCfRAAAAAAAAPA/oCECC0EBIQsCQCADnPwDIAkgAyAJuCIcYxsgCSADRAAAAAAAAAAAZBsiDCAJTw0AQQEgHERQ6S8378bjP6JEAAAAAAAA4D+gnCIDvUL///////////8Ag0KAgICAgICA+P8AWAR8IANEAAAAAAAA8D+lBUQAAAAAAADwPwv8AyAJcCIBIAFBAU0bIQsDQCALIQogCSEBA0AgCiABIgpwIgENAAsgCkEBRg0BQQEgC0EBaiIBIAEgCU8bIQsMAAsAC0QAAAAAAAD4fyEdRAAAAAAAAPh/IR5EAAAAAAAA+H8hH0QAAAAAAAD4fyEgRAAAAAAAAPB/IRREAAAAAAAA+H8hIUQAAAAAAAD4fyEiRAAAAAAAAPh/ISMgByAMBHwgBkQAAAAAAAD4P6IhJSAFRAAAAAAAAOg/oiEmIAUgBqBEAAAAAAAA4D+iIScgBiAFoUSV1iboCy4RPqAhKEQAAAAAAADwvyEkQQAhCgNAIAAoAgAhAQJ8IAAtAARFBEAgASAKQSRsaiIBKgIAuyEDIAEqAiC7IRIgASoCHLshEyABKgIYuyEVIAEqAhS7IRYgASoCELshFyABKgIMuyEaIAEqAgi7IREgASoCBLsMAQsgASAKQcgAbGoiASsDQCESIAErAzghEyABKwMwIRUgASsDKCEWIAErAyAhFyABKwMYIRogASsDECERIAErAwAhAyABKwMICyEbAkAgGiADoSIQIBMgG6EiGaIgFyAboSIPIBUgA6EiKaKhIhggGKIgDyASIBGhIg+iIBYgEaEiKiAZoqEiGSAZoiAqICmiIBAgD6KhIg8gD6KgoJ8iEESV1iboCy4RPmMNACAIIBiaIBCjIhg5A0ggCCAPmiAQoyIPOQNAIAggGZogEKMiEDkDOCAIIBA5AwggCCAPOQMQIAggGDkDGCAIIBEgFqAgEqBEAAAAAAAACECjIhEgGEQtQxzr4jYaP6KgIhY5A2AgCCAbIBegIBOgRAAAAAAAAAhAoyISIA9ELUMc6+I2Gj+ioCIXOQNYIAggAyAaoCAVoEQAAAAAAAAIQKMiEyAQRC1DHOviNho/oqAiAzkDUCAIIAM5AyAgCCAXOQMoIAggFjkDMCAAIAhBIGogCEEIakSN7bWg98awPiACIAogCEHoAGoQGUEASA0AIBQgCCsDaCIDZARAIBEhISASISIgEyEjIAMhFAsgBEUNACADICZmRQ0AIAMgJWVFDQAgDUEBaiENICQCfCADIAahRAAAAAAAAPA/oCADIAZkDQAaIAUgA6FEAAAAAAAA8D+gIAMgBWMNABogAyAnoZkgKKMLIhVjRQ0AIBUhJCADIR0gESEeIBIhHyATISALIAogC2oiASAJQQAgASAJTxtrIQogDkEBaiIOIAxHDQALIA24BUQAAAAAAAAAAAs5A1ggByAeOQNQIAcgHzkDSCAHICA5A0AgByAdOQM4IAcgHDkDMCAHICE5AxggByAiOQMQIAcgIzkDCCAHIAy4OQMoIAdEAAAAAAAA8D9EAAAAAAAAAAAgCSAMSxs5AyAgB0QAAAAAAAD4fyAUIBREAAAAAAAA8H9hGzkDAEEBBUEACyEAIAhB8ABqJAAgAAtlAQF/IAAEQCAAKAIAEC8gACgCJCIBBEAgACABNgIoIAAoAiwaIAEQLwsgACgCGCIBBEAgACABNgIcIAAoAiAaIAEQLwsgACgCDCIBBEAgACABNgIQIAAoAhQaIAEQLwsgABAvCwuRBQEGfwJAAkACQAJAIAMOAwMCAAELIAIoAgQoAgBBA3QiAyACKAIAKAIAIgIgAUEEayIBKAIAIgVBGGxqaisDACADIAIgACgCACIDQRhsamorAwBjBEAgBCAFNgIAIAQgACgCADYCBA8LIAQgAzYCACAEIAEoAgA2AgQPCyADQQhMBEAgACABRg0CIAIoAgQhByACKAIAIQIgBCAAKAIANgIAIABBBGoiBSABRg0CIAIoAgAhBiAEIQADQCAAQQRqIQICQCAHKAIAQQN0IgMgBiAFKAIAIghBGGxqaisDACADIAYgACgCACIDQRhsamorAwBjBEAgACADNgIEAn8gBCAAIARGDQAaA0AgACAHKAIAQQN0IgMgBiAFKAIAQRhsamorAwAgAyAGIABBBGsiAygCACIIQRhsamorAwBjRQ0BGiAAIAg2AgAgAyIAIARHDQALIAQLIAUoAgA2AgAMAQsgAiAINgIACyACIQAgBUEEaiIFIAFHDQALDAILIAAgACADQQF2IgZBAnQiB2oiBSACIAYgBCAGEBQgBSABIAIgAyAGayIDIAQgB2ogAxAUIAIoAgQhBiACKAIAIQcgBSEDAkADQCABIANGDQEgBCADKAIAIgIgACgCACIIIAYoAgBBA3QiCSAHKAIAIgogAkEYbGpqKwMAIAogCEEYbGogCWorAwBjIgIbNgIAIANBBEEAIAIbaiEDIARBBGohBCAAQQBBBCACG2oiACAFRw0ACyABIANGDQIDQCAEIAMoAgA2AgAgBEEEaiEEIANBBGoiAyABRw0ACwwCCyAAIAVGDQEDQCAEIAAoAgA2AgAgBEEEaiEEIABBBGoiACAFRw0ACwwBCyAEIAAoAgA2AgALC+wMAg5/AXwCQCAFRQ0AA0ACQAJAAkAgBSAHTA0AIAQgB0wNACAERQ0EIAMoAgAoAgAiCCADKAIEKAIAQQN0IgxqIgkgASgCACILQRhsaisDACEWA0AgFiAJIAAoAgAiDUEYbGorAwBjDQIgAEEEaiEAIARBAWsiBA0ACwwECyAEIAVKDQEgACABRg0DIAYhCSAAIQgDQCAJIAgoAgA2AgAgCUEEaiEJIAhBBGoiCCABRw0ACyADKAIEIQQgAygCACEFA0AgASACRgRAIAkgBmsiAUUNBSAAIAYgAfwKAAAPCyAAIAEoAgAiAyAGKAIAIgcgBCgCAEEDdCILIAUoAgAiCCADQRhsamorAwAgCCAHQRhsaiALaisDAGMiAxs2AgAgAUEEQQAgAxtqIQEgAEEEaiEAIAZBAEEEIAMbaiIGIAlHDQALDAMLAkAgBCAFSARAIAEgBUECbSIPQQJ0aiENAkAgACABRgRAIAAhCwwBCyAIIA0oAgBBGGxqIAxqKwMAIRYgASAAa0ECdSEIIAAhCwNAIAsgCyAIQQF2IgxBAnRqIgtBBGogFiAJIAsoAgBBGGxqKwMAYyIQGyELIAwgCCAMQX9zaiAQGyIIDQALCyALIABrQQJ1IRAMAQsgBEEBRgRAIAAgCzYCACABIA02AgAPCyAAIARBAm0iEEECdGohCwJAIAEgAkYEQCABIQ0MAQsgCCALKAIAQRhsaiAMaisDACEWIAIgAWtBAnUhCCABIQ0DQCANIAhBAXYiDEECdGoiD0EEaiANIAkgDygCAEEYbGorAwAgFmMiDxshDSAIIAxBf3NqIAwgDxsiCA0ACwsgDSABa0ECdSEPCyAFIA9rIQUgBCAQayEEIA0hCQJAIAEgC0YNACALIQkgASANRg0AIAEgCUEEaiIIRgRAIAkoAgAhDCANIAFrIgEEQCAJIAggAfwKAAALIAEgC2oiCSAMNgIADAELIA0gAUEEakYEQCANQQRrIgEoAgAhCCANIAEgC2siAWshCSABBEAgCSALIAH8CgAACyALIAg2AgAMAQsgDSABayIVQQJ1IgwgASALa0ECdSIBIAEgDEobQQBKBEADQAJ/IAEgDEwEQCABQQJ0IhJBBGsiCEECdkEBakEDcSEOIAhBDEkhEwNAQQAhCiAJIBJqIhEhCCAOBEADQCAJKAIAIRQgCSAIKAIANgIAIAggFDYCACAIQQRqIQggCUEEaiEJIApBAWoiCiAORw0ACwsgE0UEQANAIAkoAgAhCiAJIAgoAgA2AgAgCCAKNgIAIAkoAgQhCiAJIAgoAgQ2AgQgCCAKNgIEIAkoAgghCiAJIAgoAgg2AgggCCAKNgIIIAkoAgwhCiAJIAgoAgw2AgwgCCAKNgIMIAhBEGohCCAJQRBqIgkgEUcNAAsLIBEhCSABIAwgAWsiDEwNAAsgDAwBCyAMQQNxIREgDEEBa0H/////A3FBA0khEgNAIAFBAnQhCiAJIAEgDGsiAUECdGohCEEAIQ4gCSAKaiITIQogEQRAA0AgCCgCACEUIAggCigCADYCACAKIBQ2AgAgCkEEaiEKIAhBBGohCCAOQQFqIg4gEUcNAAsLIBJFBEADQCAIKAIAIQ4gCCAKKAIANgIAIAogDjYCACAIKAIEIQ4gCCAKKAIENgIEIAogDjYCBCAIKAIIIQ4gCCAKKAIINgIIIAogDjYCCCAIKAIMIQ4gCCAKKAIMNgIMIAogDjYCDCAKQRBqIQogCEEQaiIIIBNHDQALCyABIAxKDQALIAELQQBKDQALCyALIBVqIQkLAn8gDyAQaiAEIAVqSARAIAAgCyAJIAMgECAPIAYgBxAiIAkhACANDAELIAkgDSACIAMgBCAFIAYgBxAiIA8hBSAQIQQgCSECIAsLIQEgBQ0BDAILCyABIAJGDQAgBiEJIAEhCANAIAkgCCgCADYCACAJQQRqIQkgCEEEaiIIIAJHDQALIAMoAgQhBCADKAIAIQUDQCAAIAFGBEADQCACQQRrIgIgCUEEayIJKAIANgIAIAYgCUcNAAwDCwALIAJBBGsiAiABQQRrIgcoAgAiAyAJQQRrIgsoAgAiCCAEKAIAQQN0Ig0gBSgCACIMIAhBGGxqaisDACAMIANBGGxqIA1qKwMAYyIDGzYCACAHIAEgAxshASAJIAsgAxsiCSAGRw0ACwsLzh0DE38QfAF9IwBBQGoiDCQAIARBA2whGAJAAkAgBEUNAANAIAIgAyALQQJ0aigCAEsEQCAYIAtBAWoiC0cNAQwCCwsMAQtBACELQbQBEDUiDUEYaiIQQQBBnAH8CwAgDSAKNgIUIA0gBDYCECANIAM2AgwgDSACNgIIIA0gATYCBCANIAA2AgAgECACEBECQCACRQ0AIAJBB3EhEiAQKAIAIQ4gAkEITwRAIAJBeHEhFANAIA4gC0ECdGogCzYCACAOIAtBAXIiD0ECdGogDzYCACAOIAtBAnIiD0ECdGogDzYCACAOIAtBA3IiD0ECdGogDzYCACAOIAtBBHIiD0ECdGogDzYCACAOIAtBBXIiD0ECdGogDzYCACAOIAtBBnIiD0ECdGogDzYCACAOIAtBB3IiD0ECdGogDzYCACALQQhqIQsgEUEIaiIRIBRHDQALIBJFDQELQQAhEQNAIA4gC0ECdGogCzYCACALQQFqIQsgEUEBaiIRIBJHDQALCwJAIAdFDQAgB0EDcSEUIBAoAgAhEEEAIQ5BACELIAdBBE8EQCAHQXxxIQ9BACERA0AgECAFIAtBAnQiEmooAgBBAnRqIAYgEmooAgA2AgAgECAFIBJBBHIiB2ooAgBBAnRqIAYgB2ooAgA2AgAgECAFIBJBCHIiB2ooAgBBAnRqIAYgB2ooAgA2AgAgECAFIBJBDHIiB2ooAgBBAnRqIAYgB2ooAgA2AgAgC0EEaiELIBFBBGoiESAPRw0ACyAURQ0BCwNAIBAgBSALQQJ0IgdqKAIAQQJ0aiAGIAdqKAIANgIAIAtBAWohCyAOQQFqIg4gFEcNAAsLQQAhDiAMQQA2AhAgDUEwaiAEIAxBEGoiBRAKIAxBADYCECANQTxqIAQgBRAKIAoEQCAIKAIAIQUDQCAFQQNuIgsgCCAOIgZBAWoiDkECdGoiEigCACIFQQNuSQRAIAkgBkECdGohFCANKAI8IQ8gDSgCMCEHA0AgByALQQJ0IgVqIBQoAgA2AgAgBSAPaiAGNgIAIAtBAWoiCyASKAIAIgVBA25JDQALCyAKIA5HDQALCyANQcgAaiAYEBEgDUHUAGogBBARIAQEQCANKAJUIQcgDSgCSCEPQQAhCwNAIA8gC0EMbCIFaiAAIAMgBUEEaiIGaigCACABbEECdGoiCioCBLsiJCAAIAMgBWooAgAgAWxBAnRqIgkqAgS7IiKhIiYgACADIAVBCGoiBWooAgAgAWxBAnRqIggqAgi7IiUgCSoCCLsiHqEiJ6IgCioCCLsiKCAeoSIpIAgqAgS7IiogIqEiK6KhIiIgCioCALsiISAJKgIAuyIeoSIsICuiICYgCCoCALsiHyAeoSItoqEiIyAjoiAiICKiICkgLaIgLCAnoqEiICAgoqCgIh6fIiJEAAAAAAAA8D8gHkQAAAAAAAAAAGQbIh6jtjgCACAFIA9qICMgHqO2OAIAIAYgD2ogICAeo7Y4AgBDAAAAACEuAkAgLSAtoiArICuioCAnICeioCIgICBiIB8gIaEiHiAeoiAqICShIh4gHqKgICUgKKEiHiAeoqAiHyAfYnINACAsICyiICYgJqKgICkgKaKgIiEgIWIgICAgIB8gHyAgYxsiHiAfRAAAAAAAAAAAYRsgHiAgRAAAAAAAAAAAYRsiHyAfYnINACAhICEgHyAfICFjGyIeIB9EAAAAAAAAAABhGyAeICFEAAAAAAAAAABhGyIeRAAAAAAAAAAAZEUNACAiIB6fo7YhLgsgByALQQJ0aiAuOAIAIAtBAWoiCyAERw0ACwtBAiEFIA0oAhgiByEKIA0oAhwiBiEJAkAgBiAHa0ECdSIHIA0oAiwiCyANKAIkIghrQQJ1TQRAIAcgDSgCKCAIayIGQQJ1SwRAIAYEQCAIIAogBvwKAAALIA0oAighCCAJIAYgCmoiBmsiBwRAIAggBiAH/AoAAAsgDSAHIAhqNgIoDAILIAkgCmsiBgRAIAggCiAG/AoAAAsgDSAGIAhqNgIoDAELIAgEQCANIAg2AiggCBAvIA1BADYCLCANQgA3AiRBACELCwJAIAdBgICAgARPDQBB/////wMgC0EBdSIGIAcgBiAHSxsgC0H8////B08bIgZBgICAgARPDQAgDSAGQQJ0IgYQNSIHNgIoIA0gBzYCJCANIAYgB2o2AiwgCSAKayIGBEAgByAKIAb8CgAACyANIAYgB2o2AigMAQsQBgALIAxCADcDGCAMQgA3AxAgDEGAgID8AzYCIAJAAkAgArP8ASILQQFGDQBBACEGIAsgC0EBa3EEQCALEDIhCyAMKAIUIQYLIAYgC0kEQCALIQUMAQsgBiALTQ0BIAwoAhyzIAwqAiCVjfwBIQUgCwJ/AkAgBkEDSQ0AIAZpQQFLDQAgBUEBQSAgBUEBa2drdCAFQQJJGwwBCyAFEDILIgUgBSALSRsiBSAGTw0BCyAMQRBqIAUQDwtBACEHIAxBADYCDCACBEADQCAAIAEgB2xBAnRqIgUqAgi7IihEAAAAAABAj0CiISUgBSoCBLsiKkQAAAAAAECPQKIiIZwhI0EAIRZBACEXIAUqAgC7Ih9EAAAAAABAj0CiIiKcIiC9QgGGQv////////9vWARAICAgIEQAAAAAAADwPaKdRAAAAAAAAPBBoqEgIKYiHkQAAAAAAADwQaAgHiAeRAAAAAAAAAAAYxv8AyEXCyAjvUIBhkL/////////b1gEQCAjICNEAAAAAAAA8D2inUQAAAAAAADwQaKhICOmIh5EAAAAAAAA8EGgIB4gHkQAAAAAAAAAAGMb/AMhFgtBACELQQAhDiAlnCIkvUIBhkL/////////b1gEQCAkICREAAAAAAAA8D2inUQAAAAAAADwQaKhICSmIh5EAAAAAAAA8EGgIB4gHkQAAAAAAAAAAGMb/AMhDgsCQAJAIAwoAhQiFUUNACAMKAIcRQ0AICUgJKEiHkRmZmZmZmbuP2QgHkSamZmZmZmpP2MiCHIhEiAhICOhIh5EZmZmZmZm7j9kIB5EmpmZmZmZqT9jIgZyIRQgIiAgoSIeRGZmZmZmZu4/ZCAeRJqZmZmZmak/YyIFciEKQX9BASAIGyEPQX9BASAGGyEJQX9BASAFGyEGIBVBAWshGSAVaSEaIAwoAhAhGwNAIAsgF2pB3eibI2whHEEAIQsgFCEIA0AgCyAWakGfgZ0JbCAccyEdQQAhCyASIREDQCAdIAsgDmpBt//nJ2xzIRACQCAaQQFLIhNFBEAgECAZcSEFDAELIBAiBSAVSQ0AIAUgFXAhBQsCQCAbIAVBAnRqKAIAIgtFDQAgCygCACILRQ0AAkAgE0UEQANAAkAgECALKAIEIhNHBEAgEyAZcSAFRg0BDAULIAsoAgggEEYNAwsgCygCACILDQAMAwsACwNAAkAgECALKAIEIhNHBEAgEyAVTwR/IBMgFXAFIBMLIAVGDQEMBAsgCygCCCAQRg0CCyALKAIAIgsNAAsMAQsgCygCDCIFIAsoAhAiEEYNAANAIAAgBSgCACILIAFsQQJ0aiITKgIAuyAfoSIeIB6iIBMqAgS7ICqhIh4gHqKgIBMqAgi7ICihIh4gHqKgRDqMMOKOeSU+ZUUEQCAQIAVBBGoiBUcNAQwCCwsgDSgCJCIFIAdBAnRqIAUgC0ECdGooAgA2AgAMBQsgEUEBcSEFQQAhESAPIQsgBQ0ACyAIQQFxIQVBACEIIAkhCyAFDQALIAohBUEAIQogBiELIAUNAAsLIAwgDkG3/+cnbCAWQZ+BnQlsIBdB3eibI2xzczYCCCAMIAxBCGoiBTYCKCAMIAxBEGo2AiwgDEEwaiAMQSxqIgYgBSAMQShqEAkgDCAMKAIwIggoAhAiBzYCLCAIKAIUIQUgDCAIQQxqNgI4IAwgDEEMajYCNCAMIAY2AjAgCAJ/IAUgB0sEQCAHIAwoAgw2AgAgB0EEagwBCyAMQTBqEBogDCgCLAs2AhALIAwgDCgCDEEBaiIHNgIMIAIgB0sNAAsLIAwoAhgiCwRAA0AgCygCACEAIAsoAgwiAQRAIAsgATYCECALKAIUGiABEC8LIAsQLyAAIgsNAAsLIAwoAhAhACAMQQA2AhAgAARAIAwoAhQaIAAQLwsgDEEANgIQIA1B4ABqIAJBAWogDEEQahAKIAQEQCANKAJgIQcgDSgCJCEFQQAhBgNAIAcgBSADIAZBDGxqIgEoAgBBAnRqKAIAQQJ0aiIAIAAoAgRBAWo2AgQgByAFIAEoAgRBAnRqKAIAQQJ0aiIAIAAoAgRBAWo2AgQgByAFIAEoAghBAnRqKAIAQQJ0aiIAIAAoAgRBAWo2AgQgBkEBaiIGIARHDQALCwJAIAJFDQAgAkEDcSEFIA0oAmAiBygCACEGQQAhEQJAIAJBBEkEQEEAIQsMAQsgAkF8cSECQQAhC0EAIQ4DQCAHIAtBAnRqIgEgASgCBCAGaiIANgIEIAEgASgCCCAAaiIANgIIIAEgASgCDCAAaiIBNgIMIAcgC0EEaiILQQJ0aiIAIAAoAgAgAWoiBjYCACAOQQRqIg4gAkcNAAsgBUUNAQsDQCAHIAtBAWoiC0ECdGoiACAAKAIAIAZqIgY2AgAgEUEBaiIRIAVHDQALCyANQewAaiAYEBECQAJAAkAgDSgCZEEEayIAIA0oAmAiAUcEQCAAIAFrIgBBAEgNAiAAEDUhBSAABEAgBSABIAD8CgAACyAEDQEMAwtBACEFIARFDQMLIA0oAmwhBiANKAIkIQJBACELA0AgBSACIAMgC0EMbGoiASgCAEECdGooAgBBAnRqIgAgACgCACIAQQFqNgIAIAYgAEECdGogCzYCACAFIAIgASgCBEECdGooAgBBAnRqIgAgACgCACIAQQFqNgIAIAYgAEECdGogCzYCACAFIAIgASgCCEECdGooAgBBAnRqIgAgACgCACIAQQFqNgIAIAYgAEECdGogCzYCACALQQFqIgsgBEcNAAsMAQsQBgALIAUQLwsgDEFAayQAIA0LrkYEEX8RfAF+A30jAEGQAmsiDiQAIA4gBzkDgAIgDiAANgKIAiAOIAAoAgA2AvwBIA4gACgCBDYC+AEgACgCECESIA4gACgCCDYC9AEgACgCDCEcIA5CADcD6AEgDkIANwPgASAOQYCAgPwDNgLwASAOQQA2AkgCQAJAAkAgBUEBSwRAA0AgDiAOQeABajYCMCAOQeAAaiAOQTBqIAEgDUECdGoiDSANIA5ByABqEBUgDiAOKAJIIhRBAWoiDTYCSCAUQQJqIAVJDQALIAVBgICAgAFPDQMMAQsgBQ0ADAELQQAhDSAFQQR0IgEQNSEUIAEEQCAUQQAgAfwLAAsDQCACIA1BA3RqKwMAIQcgAyANai0AACEPIBQgDUEEdGoiASAEIA1BAnRqKAIANgIMIAEgD0EBcToACCABIAc5AwAgASAPQQF2QQFxOgAJIA1BAWoiDSAFRw0ACwsCQCASRQ0AIBJBgICAgARJBEAgEkECdCIBEDUhFSABBEAgFUEAIAH8CwALIAVBAWshAwJAIA4oAuQBIg8EQCAOKALsAQ0BCyASQQdxIQ1BACEBQQAhBSASQQhPBEAgEkH4////A3EhD0EAIQQDQCAVIAVBAnRqIgIgAzYCHCACIAM2AhggAiADNgIUIAIgAzYCECACIAM2AgwgAiADNgIIIAIgAzYCBCACIAM2AgAgBUEIaiEFIARBCGoiBCAPRw0ACyANRQ0DCwNAIBUgBUECdGogAzYCACAFQQFqIQUgAUEBaiIBIA1HDQALDAILIA9BAWshECAOKALgASEWIA4oAogCKAIwIRdBACECIA9pQQFLIREDQCAXIAJBAnQiGGooAgAhBQJAIBFFBEAgBSAQcSEEDAELIAUiBCAPSQ0AIAQgD3AhBAsgAyEBAkAgFiAEQQJ0aigCACINRQ0AIA0oAgAiDUUNAAJAIBFFBEADQAJAIAUgDSgCBCIBRwRAIAEgEHEgBEYNASADIQEMBQsgDSgCCCAFRg0DCyANKAIAIg0NAAsgAyEBDAILA0ACQCAFIA0oAgQiAUcEQCABIA9PBH8gASAPcAUgAQsgBEYNASADIQEMBAsgDSgCCCAFRg0CCyANKAIAIg0NAAsgAyEBDAELIA0oAgwhAQsgFSAYaiABNgIAIBIgAkEBaiICRw0ACwwBCwwBCwJAIAxFDQAgDEGX9+kISQRAQQAhDSAMQegBbCIBEDUhGSABQegBayIBIAFB6AFwa0HoAWoiAQRAIBlBACAB/AsACyABIBlqIRMDQCAKIAsgDUECdGooAgAiAkEDdGohAyALIA1BAWoiAUECdGooAgAgAmtBA08EQCAZIA1B6AFsaiICIAMrAwD8AiIFNgIAIAIgAysDCEQAAAAAAAAAAGI6AAQgAysDEPwDIQQCQAJAAkACQAJAAkACQAJAIAVBAWsOBgABAgMEBQYLIAMrAyAhByADKwMYIR4gAiADKwMoOQMYIAIgBzkDECACIB45AwggAysDOCEHIAMrAzAhHiACIANBQGsrAwA5AzAgAiAHOQMoIAIgHjkDIAwGCyADKwMgIQcgAysDGCEeIAIgAysDKDkDSCACIAc5A0AgAiAeOQM4DAULIAMrAyAhByADKwMYIR4gAiADKwMoOQNIIAIgBzkDQCACIB45AzggAysDOCEHIAMrAzAhHiACIANBQGsrAwA5A2AgAiAHOQNYIAIgHjkDUCACIAMrA0g5A4ABDAQLIAIgAysDGDkDiAEgAysDICEHIAJBAToAoAEgAiAHOQOQASADKwMwIQcgAysDKCEeIAIgAysDODkDeCACIAc5A3AgAiAeOQNoIAJBpAFqIAQQBUEIIQ0gAigCpAEiBSACKAKoASIQRwRAA0AgAyANQQN0aiIPKwMAIQcgDysDCCEeIAUgDysDEDkDECAFIB45AwggBSAHOQMAIA1BA2ohDSAFQRhqIgUgEEcNAAsLIAJBsAFqIAQQBSACKAKwASIFIAIoArQBIgRGDQMDQCADIA1BA3RqIgIrAwAhByACKwMIIR4gBSACKwMQOQMQIAUgHjkDCCAFIAc5AwAgDUEDaiENIAVBGGoiBSAERw0ACwwDCyADKwMYIQcgAkEBOgChASACIAc5A5gBIAJBpAFqIAQQBUEEIQ0gAigCpAEiBSACKAKoASIERg0CA0AgAyANQQN0aiICKwMAIQcgAisDCCEeIAUgAisDEDkDECAFIB45AwggBSAHOQMAIA1BA2ohDSAFQRhqIgUgBEcNAAsMAgsgAiADKwMYOQPYASACQbwBaiAEEAUCQAJAIAIoAswBIhAgAigCyAEiBWsiD0EDdSINIARJBEAgAigC0AEgBWsiEUEDdSAETwRAIAQgDWtBA3QiBQRAIBBBACAF/AsACyACIAUgEGo2AswBDAMLIARBgICAgAJPDQlB/////wEgEUECdSIQIAQgBCAQSRsgEUH4////B08bIhBBgICAgAJPDQEgEEEDdCIWEDUiFyAPaiEQIAQgDWtBA3QiEQRAIBBBACAR/AsACyAQIA1BA3RrIQ0gDwRAIA0gBSAP/AoAAAsgAiAWIBdqNgLQASACIBAgEWo2AswBIAIgDTYCyAEgBUUNAiAFEC8MAgsgBCANTw0BIAIgBSAEQQN0ajYCzAEMAQsQBwALIARFDQEgAigCyAEhBSACKAK8ASEPQQAhAkEEIQ0gBEEBRwRAIARBAXEhFiAEQX5xIRdBACEQA0AgAyANQQN0aiIEKwMAIQcgBCsDCCEeIA8gAkEYbGoiESAEKwMQOQMQIBEgHjkDCCARIAc5AwAgBSACQQN0aiAEKwMYOQMAIAQrAyAhByAEKwMoIR4gDyACQQFyIhhBGGxqIhEgBCsDMDkDECARIB45AwggESAHOQMAIAUgGEEDdGogBCsDODkDACACQQJqIQIgDUEIaiENIBBBAmoiECAXRw0ACyAWRQ0CCyADIA1BA3RqIgMrAwAhByADKwMIIR4gDyACQRhsaiIEIAMrAxA5AxAgBCAeOQMIIAQgBzkDACAFIAJBA3RqIAMrAxg5AwAMAQsgAkEANgIACwsgASINIAxHDQALDAELDAELIABByABqIQ9BACEFIA5BADYC3AEgDkIANwLUASAOKAKIAiEBAkAgCEUNACAMRQ0AAkACQCABKAIUIgEgDigC2AEiCiAOKALUASICayIDQfAAbSIESwRAIA4oAtwBIAJrQfAAbSILIAFPBEAgASAEa0HwAGxB8ABrIgEgAUHwAHBrQfAAaiIBBEAgCkEAIAH8CwALIA4gASAKajYC2AEMAwsgAUGTyaQSTw0EQZLJpBIgC0EBdCIKIAEgASAKSRsgC0HJpJIJTxsiCkGTyaQSTw0BIApB8ABsIgsQNSINIANqIQogASAEa0HwAGxB8ABrIgEgAUHwAHBrQfAAaiIBBEAgCkEAIAH8CwALIAogA0GQf21B8ABsaiEEIAMEQCAEIAIgA/wKAAALIA4gCyANajYC3AEgDiABIApqNgLYASAOIAQ2AtQBIAJFDQIgAhAvDAILIAEgBE8NASAOIAIgAUHwAGxqNgLYAQwBCxAHAAsgDigCiAIiASgCFEUNAEEAIQ0DQAJAIAggDUECdGooAgAiAkEASA0AIAIgDE8NACAOQeAAaiIBIBkgAkHoAWxqNgIAIAFBADoAaCAJIA1B4ABsaiICKwMQIh4gAisDGCIhIAIrAzgiIqIgAisDICIjIAIrAzAiJKKhIgeiIAIrAwAiICAjIAIrA0AiJaIgAisDKCImICKioSIpoiACKwMIIh8gJiAkoiAhICWioSIqoqCgIiuZRBHqLYGZl3E9ZARAIAIrA1ghJyACKwNIISggAisDUCEsIAFBAToAaCABIAdEAAAAAAAA8D8gK6MiB6IiKzkDOCABICogB6IiKjkDICABICkgB6IiKTkDCCABICAgI6IgHyAhoqEgB6IiLTkDSCABIB8gJKIgICAioqEgB6IiLjkDQCABIB4gIaIgICAmoqEgB6IiITkDMCABICAgJaIgHiAkoqEgB6IiIDkDKCABIB8gJqIgHiAjoqEgB6IiIzkDGCABIB4gIqIgHyAloqEgB6IiBzkDECABICkgKKIgKiAsoqAgKyAnoqCaOQNQIAEgIyAooiAhICyioCAtICeioJo5A2AgASAHICiiICAgLKKgIC4gJ6KgmjkDWAsgDigC1AEgDUHwAGxqIgIgAUHpAPwKAAAgAi0AaCAFQQFxckEARyEFIA4oAogCIQELIA1BAWoiDSABKAIUSQ0ACwsgDkIANwNQIA5CADcDSCAOQYCAgPwDNgJYIA4gDzYCeCAOIA5BgAJqNgJ8IA4gDkH8AWo2AnQgDiAOQfgBajYCcCAOIA5ByABqNgJsIA4gDkH0AWo2AmggDiAOQdQBajYCZCAOIA5BiAJqNgJgIAFB+ABqIBJBCWwiARARIA4oAogCQYQBaiABEBEgDigCiAIhDSASBEAgDSgChAEhAiANKAJ4IQEgBUEBcSEPA0AgACgCSCAaQQNsIhtBAnRqIgMqAgAhMCAUIBUgGkECdCIQaigCAEEEdGohESADKgIIITEgAyoCBCEyQQAhDCAPBEAgACgCVCAQaioCALtEexSuR+F6pD9jIQwLIDC7ISwgESsDACEpIDG7ISogMrshK0EAIQsDQCALIBtqIgRBA2whAyAcIARBAnRqKAIAIgQgDigC+AFsIRYgACgCJCAEQQJ0aigCACEIAnwCQCAMRQ0ARAAAAAAAAAAAIQdBACEERAAAAAAAAAAAIR9EAAAAAAAAAAAhHiAIQQJ0IgkgDSgCYGoiCigCACIFIAooAgRJBEADQCAAKAJUIA0oAmwgBUECdGooAgAiCkECdGoqAgC7RHsUrkfheqQ/Y0UEQCAOQeAAaiAKIAggDkEwahAlBEAgHiAOKwNAoCEeIB8gDisDOKAhHyAHIA4rAzCgIQdBASEECyAOKAKIAiENCyAFQQFqIgUgDSgCYCAJaigCBEkNAAsLIARBAXFFDQAgByAHoiAfIB+ioCAeIB6ioJ8iIESV1iboCy4RPmRFDQAgASADQQJ0IgRqIA4oAvwBIBZBAnRqIggqAgA4AgAgASAEQQRqIglqIAgqAgQ4AgAgASADQQJqIgVBAnRqIAgqAgg4AgAgAiAJaiAfICCjtjgCACACIARqIAcgIKO2OAIAIB4gIKMMAQtEAAAAAAAAAAAhHkEAIQpBACEJRAAAAAAAAAAAISBEAAAAAAAAAAAhIUQAAAAAAAAAACEiRAAAAAAAAAAAISNEAAAAAAAAAAAhJEQAAAAAAAAAACElRAAAAAAAAAAAIR9EAAAAAAAAAAAhBwJAIAhBAnQiHSANKAJgaiIEKAIAIgUgBCgCBE8NAANAAkACQCANKAIwIhggDSgCbCAFQQJ0aigCACIEQQJ0IhdqKAIAIBAgGGooAgBGDQAgFCAVIBdqKAIAQQR0ai0ACA0AIBEtAAhBAUcNAQsgLCAAKAJIIARBDGxqIhgqAgC7IiaiICsgGCoCBLsiJ6KgICogGCoCCLsiKKKgICljDQACQCAAKAJUIBdqKgIAu0T8qfHSTWJQP2MEQCAgICigISAgByAnoCEHIB8gJqAhHwwBCyAjICigISMgJCAnoCEkICUgJqAhJUEBIQoLIA9FDQAgDkHgAGogBCAIIA5BMGoQJQRAIB4gDisDQKAhHiAhIA4rAzigISEgIiAOKwMwoCEiQQEhCQsgDigCiAIhDQsgBUEBaiIFIA0oAmAgHWooAgRJDQALICQgByAKQQFxIgQbIQcgJSAfIAQbIR8gIyAgIAQbISAgCUEBcUUEQCAgIR4MAQsgIiAioiAhICGioCAeIB6ioJ9EldYm6AsuET5kRQRAICAhHgwBCyAiIR8gISEHCyABIANBAnQiBGogDigC/AEgFkECdGoiCCoCADgCACABIARBBGoiCWogCCoCBDgCACABIANBAmoiBUECdGogCCoCCDgCACACIAlqIAcgHyAfoiAHIAeioCAeIB6ioCIHn0QAAAAAAADwPyAHRAAAAAAAAAAAZBsiB6O2OAIAIAIgBGogHyAHo7Y4AgAgHiAHowshByACIAVBAnRqIAe2OAIAIAtBAWoiC0EDRw0ACyAaQQFqIhogEkcNAAsLIA0gDSgCkAE2ApQBIA5CADcDICAOQgA3AxggDkGAgID8AzYCKAJAAkAgEkEBdCIPs/wBIg1BAUYEQEECIQ0MAQtBACEFIA0gDUEBa3EEQCANEDIhDSAOKAIcIQULIAUgDUkNACAFIA1NDQEgDigCJLMgDioCKJWN/AEhASANAn8CQCAFQQNJDQAgBWlBAUsNACABQQFBICABQQFrZ2t0IAFBAkkbDAELIAEQMgsiASABIA1JGyINIAVPDQELIA5BGGogDRAPCyAOKAKIAiEXIA5BADYCFCASBEAgDkHIAGohECAOQSBqIRhBACEFA0ACQAJAIBcoAhgiASAcIA4oAhRBDGxqIgIgBUECdGooAgBBAnRqKAIAIgkgASACQQAgBUEBaiIFIAVBA0YiGhtBAnRqKAIAQQJ0aigCACIKRg0AIA4gCSAKIAkgCksbrSAONQL0ASAJIAogCSAKSRutfnwiLzcDCAJAAkAgDigCHCIIRQ0AIA4oAiQiG0UNACAOIC83AzAgDkEwahAxIQQgDigCGCIRAn8gBCAIQQFrcSAIaUEBSyILRQ0AGiAEIAQgCEkNABogBCAIcAsiAkECdGooAgAiAUUNACABKAIAIg1FDQAgCEEBayEMIAtFBEADQAJAIAQgDSgCBCIBRwRAIAEgDHEgAkYNAQwECyANKQMIIC9RDQQLIA0oAgAiDQ0ADAILAAsDQAJAIAQgDSgCBCIBRwRAIAEgCE8EfyABIAhwBSABCyACRg0BDAMLIA0pAwggL1ENAwsgDSgCACINDQALCyAOIA5BGGo2AowCQQAhASMAQRBrIgkkACAOKAKMAiEEIAkgDikDCCIvNwMIIAlBCGoQMSECIA4CfwJAIAQoAgQiCkUNACAEKAIAAn8gCkEBayACcSAKaSIDQQFNDQAaIAIgAiAKSQ0AGiACIApwCyIBQQJ0aigCACIIRQ0AIAgoAgAiCEUNACADQQFNBEAgCkEBayEDA0ACQCACIAgoAgQiC0cEQCADIAtxIAFHDQQMAQsgCCkDCCAvUg0AQQAMBAsgCCgCACIIDQALDAELA0ACQCACIAgoAgQiA0cEQCADIApPBH8gAyAKcAUgAwsgAUcNAwwBCyAIKQMIIC9SDQBBAAwDCyAIKAIAIggNAAsLQRgQNSIIIAI2AgQgCEEANgIAIAggDikDCDcDCCAIIA4oAhQ2AhACQCAEKAIMQQFqsyIwIAQqAhAiMSAKs5ReRQ0AQQIhAQJAIAogCkEBa3FBAEcgCkEDSXIgCkEBdHIiAyAwIDGVjfwBIgsgAyALSxsiA0EBRg0AIAMgA0EBa3FFBEAgAyEBDAELIAMQMiEBIAQoAgQhCgsCQCABIApNBEAgASAKTw0BIAQoAgyzIAQqAhCVjfwBIQMgAQJ/AkAgCkEDSQ0AIAppQQFLDQAgA0EBQSAgA0EBa2drdCADQQJJGwwBCyADEDILIgMgASADSxsiASAKTw0BCyAEIAEQDwsgBCgCBCIKIApBAWsiAXFFBEAgASACcSEBDAELIAIgCkkEQCACIQEMAQsgAiAKcCEBCwJAIAQoAgAiAiABQQJ0aiIDKAIAIgFFBEAgCCAEKAIINgIAIAQgCDYCCCADIARBCGo2AgAgCCgCACIBRQ0BIAEoAgQhAwJAIAogCkEBayIBcUUEQCABIANxIQMMAQsgAyAKSQ0AIAMgCnAhAwsgAiADQQJ0aiAINgIADAELIAggASgCADYCACABIAg2AgALIAQgBCgCDEEBajYCDEEBCzoANCAOIAg2AjAgCUEQaiQAIBoNAgwDCyANKAIQIRYCQCALRQRAIAQgDHEhBAwBCyAEIAhJDQAgBCAIcCEECyARIARBAnRqIgIoAgAhAwNAIAMiASgCACIDIA1HDQALAkAgASAYRwRAIAEoAgQhAwJAIAtFBEAgAyAMcSEDDAELIAMgCEkNACADIAhwIQMLIAMgBEYNAQsgDSgCACIDBEAgAygCBCEDAkAgC0UEQCADIAxxIQMMAQsgAyAISQ0AIAMgCHAhAwsgAyAERg0BCyACQQA2AgALAkAgDSgCACIDRQRAQQAhAwwBCyADKAIEIQICQCALRQRAIAIgDHEhAgwBCyACIAhJDQAgAiAIcCECCyACIARGDQAgESACQQJ0aiABNgIAIA0oAgAhAwsgASADNgIAIA4gG0EBazYCJCANEC8gFCAVIBZBAnQiAmooAgBBBHRqIQMgFCAVIA4oAhQiC0ECdCIEaigCAEEEdGohAQJ/AkAgDigCiAIiCCgCMCIMIAJqKAIAIAQgDGooAgBGIgwNACADLQAIIAEtAAhGDQBBAQwBCyACIAAoAlQiDWoqAgC7RHsUrkfheqQ/Yw0BIAQgDWoqAgC7RHsUrkfheqQ/Yw0BQQALIQIgACgCSCINIBZBDGxqIgQqAgC7IA0gC0EMbGoiCyoCALuiIAQqAgS7IAsqAgS7oqAgBCoCCLsgCyoCCLuioCIemSEHQQAhDQJAIAxFBEAgAy0ACEUEQCAGIAdkIAJyDQIMAwsgAS0ACEEBcyENCwJAIAIgBiAHZEVyIgMNACANQQFxDQAgAS0ACUEBRw0CIB4gASsDAGMNAQwCCyACIANBAXNyQQFHDQELIA4oAvwBIgIgDigC+AEiAyAJbEECdGoiASoCALsgAiADIApsQQJ0aiICKgIAu6EiByAHoiABKgIEuyACKgIEu6EiByAHoqAgASoCCLsgAioCCLuhIgcgB6KgRC1DHOviNho/ZkUNACAOIAEqAgA4AjAgDiABKgIEOAI0IA4gASoCCDgCOCAOIAIqAgA4AjwgDiACKgIEOAJAIA4gAioCCDgCRCAOQTBqIQQCQCAIKAKYASIJIAgoApQBIgJrQQJ1QQZOBEBBACEKAkAgECAEIgNGBEAgAiEBDAELIAIhAQNAIAEgAyoCADgCACABQQRqIQEgA0EEaiIDIBBHDQALCyAIIAE2ApQBDAELAkAgAiAIKAKQASIBa0ECdUEGaiIDQYCAgIAESQRAQf////8DIAkgAWsiCUEBdSIKIAMgAyAKSRsgCUH8////B08bIgMEfyADQYCAgIAETw0CIANBAnQQNQVBAAshCiAKIAIgAWsiCWoiCyAEQRj8CgAAIAtBGGohBCAIIAI2ApQBIAsgCUF8cWshAiAJBEAgAiABIAn8CgAACyAIIAogA0ECdGo2ApgBIAggBDYClAEgCCACNgKQASABBEAgARAvCwwCCwwGCxAHAAsLIBpFDQELIA4gDigCFEEBaiIBNgIUQQAhBSABIBJJDQALCyAOKAIgIg0EQANAIA0oAgAhACANEC8gACINDQALCyAOKAIYIQBBACELIA5BADYCGCAABEAgDigCHBogABAvCyAOKAKIAiINIA0oApwBNgKgASANIA0oAqgBNgKsASAOQgA3AzggDkIANwMwIA5BgICA/AM2AkBBACECQQAhAyASBEBBACEBIA8QNSELIA8EQCALQQAgD/wLAAsgCyAPaiECIAsgEkEBdGohAwNAIA4gFCAVIAFBAnRqKAIAQQR0aigCDCIENgKMAiAEQQBOBEAgCyABQQF0agJ/AkACQCAOKAI0IgVFDQAgDigCPEUNAAJAIAVpQQFLIghFBEAgBUH/////B2ogBHEhAAwBCyAFIAQiAEsNACAEIAVwIQALIA4oAjAgAEECdGooAgAiCUUNACAJKAIAIg1FDQAgCEUEQCAFQQFrIQUDQAJAIAQgDSgCBCIIRwRAIAUgCHEgAEYNAQwECyANKAIIIARGDQQLIA0oAgAiDQ0ACwwBCwNAAkAgBCANKAIEIghHBEAgBSAITQR/IAggBXAFIAgLIABGDQEMAwsgDSgCCCAERg0DCyANKAIAIg0NAAsLIA4gDigCiAIiACgCrAEiBTYCCCAAKAKwASEIIA4gAEGoAWo2AiAgDiAOQYwCajYCHCAOIA5BCGo2AhggAAJ/IAUgCEkEQCAFIAQ2AgAgBUEEagwBCyAOQRhqEBogDigCCAs2AqwBIA4gDigCiAIiACgCrAEgACgCqAFrQQJ2OwEUIA4gDkEwajYCCCAOQRRqIQpBACEAIA4oAowCIQQgDgJ/AkAgDigCCCIJKAIEIghFDQAgCSgCAAJ/IAhBAWsgBHEgCGkiBUEBTQ0AGiAEIAQgCEkNABogBCAIcAsiAEECdGooAgAiDEUNACAMKAIAIg1FDQAgBUEBTQRAIAhBAWshBQNAAkAgBCANKAIEIgxHBEAgBSAMcSAARw0EDAELIA0oAgggBEcNAEEADAQLIA0oAgAiDQ0ACwwBCwNAAkAgBCANKAIEIgVHBEAgBSAITwR/IAUgCHAFIAULIABHDQMMAQsgDSgCCCAERw0AQQAMAwsgDSgCACINDQALC0EQEDUiDSAENgIEIA1BADYCACANIA4oAowCNgIIIA0gCi8BADsBDAJAIAkoAgxBAWqzIjAgCSoCECIxIAizlF5FDQBBAiEAAkAgCCAIQQFrcUEARyAIQQNJciAIQQF0ciIFIDAgMZWN/AEiDCAFIAxLGyIFQQFGDQAgBSAFQQFrcUUEQCAFIQAMAQsgBRAyIQAgCSgCBCEICwJAIAAgCE0EQCAAIAhPDQEgCSgCDLMgCSoCEJWN/AEhBSAAAn8CQCAIQQNJDQAgCGlBAUsNACAFQQFBICAFQQFrZ2t0IAVBAkkbDAELIAUQMgsiBSAAIAVLGyIAIAhPDQELIAkgABAPCyAJKAIEIgggCEEBayIAcUUEQCAAIARxIQAMAQsgBCAISQRAIAQhAAwBCyAEIAhwIQALAkAgCSgCACIEIABBAnRqIgUoAgAiAEUEQCANIAkoAgg2AgAgCSANNgIIIAUgCUEIajYCACANKAIAIgBFDQEgACgCBCEFAkAgCCAIQQFrIgBxRQRAIAAgBXEhBQwBCyAFIAhJDQAgBSAIcCEFCyAEIAVBAnRqIA02AgAMAQsgDSAAKAIANgIAIAAgDTYCAAsgCSAJKAIMQQFqNgIMQQELOgAcIA4gDTYCGCAKDAELIA1BDGoLLwEAOwEACyASIAFBAWoiAUcNAAsgDigCiAIhDQsCQCANKAKoASANKAKsAUYEQCALIQUMAQsgDSACNgKgASANKAKcASEFIA0gCzYCnAEgDSgCpAEaIA0gAzYCpAELIAUEQCAFEC8LIA4oAjgiDQRAA0AgDSgCACEAIA0QLyAAIg0NAAsLIA4oAjAhACAOQQA2AjAgAARAIA4oAjQaIAAQLwsgDigCUCINBEADQCANKAIAIQAgDRAvIAAiDQ0ACwsgDigCSCEAIA5BADYCSCAABEAgDigCTBogABAvCyAOKALUASIABEAgDiAANgLYASAOKALcARogABAvCyAZBEAgEyAZRwRAA0ACQCATQegBayITKALkASIARQ0AIAAgACgCBCIBQQFrNgIEIAENACAAIAAoAgAoAggRAQACQCAAKAIIIgEEQCAAIAFBAWs2AgggAQ0BCyAAIAAoAgAoAhARAQALCyATKALIASIABEAgEyAANgLMASATKALQARogABAvCyATKAK8ASIABEAgEyAANgLAASATKALEARogABAvCyATKAKwASIABEAgEyAANgK0ASATKAK4ARogABAvCyATKAKkASIABEAgEyAANgKoASATKAKsARogABAvCyATIBlHDQALCyAZEC8LIBUEQCAVEC8LIBQEQCAUEC8LIA4oAugBIg0EQANAIA0oAgAhACANEC8gACINDQALCyAOKALgASEAIA5BADYC4AEgAARAIA4oAuQBGiAAEC8LIA5BkAJqJAAPCxAGAAuFHAQMfxN8AX4CfSMAQUBqIgokAAJAIAAoAgQoAgAgACgCACgCACgCPCABQQJ0aigCACIFQfAAbGoiCy0AaEEBRw0AIAKtIAAoAgg1AgAgBa1+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ACAKIA4QPiAAQSAgASAHIAVBgMAAcxBCDAELCwtBACELDAMLQT0hCAtB7BEgCDYCAAtBfyELCyAGQUBrJAAgCwvHAQEDfyAALQAAQSBxRQRAAkAgACgCECIDBH8gAwUgABA6DQEgACgCEAsgACgCFCIEayACSQRAIAAgASACIAAoAiQRAgAaDAELAkACQCAAKAJQQQBIDQAgAkUNACACIQMDQCABIANqIgVBAWstAABBCkcEQCADQQFrIgMNAQwCCwsgACABIAMgACgCJBECACADSQ0CIAIgA2shAiAAKAIUIQQMAQsgASEFCyACBEAgBCAFIAL8CgAACyAAIAAoAhQgAmo2AhQLCwtzAQV/IAAoAgAiAywAAEEwayIBQQlLBEBBAA8LA0BBfyEEIAJBzJmz5gBNBEBBfyABIAJBCmwiBWogASAFQf////8Hc0sbIQQLIAAgA0EBaiIFNgIAIAMsAAEhASAEIQIgBSEDIAFBMGsiAUEKSQ0ACyACC7kCAAJAAkACQAJAAkACQAJAAkACQAJAAkAgAUEJaw4SAAgJCggJAQIDBAoJCgoICQUGBwsgAiACKAIAIgFBBGo2AgAgACABKAIANgIADwsgAiACKAIAIgFBBGo2AgAgACABMgEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMwEANwMADwsgAiACKAIAIgFBBGo2AgAgACABMAAANwMADwsgAiACKAIAIgFBBGo2AgAgACABMQAANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKwMAOQMADwsgACACEEQLDwsgAiACKAIAIgFBBGo2AgAgACABNAIANwMADwsgAiACKAIAIgFBBGo2AgAgACABNQIANwMADwsgAiACKAIAQQdqQXhxIgFBCGo2AgAgACABKQMANwMAC4gBAgJ/AX4gAEKAgICAEFoEQANAIAFBAWsiASAAIgQgAEIKgCIAQgp+fadBMHI6AAAgBEL/////nwFWDQALCyAApyECIABCCloEQANAIAFBAWsiASACIgMgAkEKbiICQQpsa0EwcjoAACADQeMASw0ACwsgAgRAIAFBAWsiASACQTByOgAACyABC3IBAX8jAEGAAmsiBSQAAkAgAiADTA0AIARBgMAEcQ0AIAIgA2siA0GAAiADQYACSSICGyIEBEAgBSABIAT8CwAL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ACAFIAitIgeGIARBwAAgCGutiIQhBSAEIAeGIQQLIAAgBDcDECAAIAU3AxggACkDECAAKQMYhEIAUiEJCwJAIAFBwABxBEAgAyABQUBqrYghAkIAIQMMAQsgAUUNACADQcAAIAFrrYYgAiABrSIEiIQhAiADIASIIQMLIAAgAjcDACAAIAM3AwggACkDCEIEhiAAKQMAIgNCPIiEIQICQCAJrSADQv//////////D4OEIgNCgYCAgICAgIAIWgRAIAJCAXwhAgwBCyADQoCAgICAgICACFINACACQgGDIAJ8IQILIAJCgICAgICAgAiFIAIgAkL/////////B1YiARshAiABrQshAyAAQSBqJAAgBkKAgICAgICAgIB/gyADQjSGhCAChL85AwALfAECfyMAQRBrIgEkACABQQo6AA8CQAJAIAAoAhAiAgR/IAIFIAAQOg0CIAAoAhALIAAoAhQiAkYNACAAKAJQQQpGDQAgACACQQFqNgIUIAJBCjoAAAwBCyAAIAFBD2pBASAAKAIkEQIAQQFHDQAgAS0ADxoLIAFBEGokAAvdBAEEfyMAQRBrIgIkACACIAE2AgxB5AwoAgAhAiMAQdABayIDJAAgAyABNgLMASADQaABaiIBQQBBKPwLACADIAMoAswBNgLIAUEAIAAgA0HIAWogA0HQAGogARA9QQBIBH9BfwUgAiACKAIAIgFBX3E2AgACfwJAAkAgAigCMEUEQCACQdAANgIwIAJBADYCHCACQgA3AxAgAigCLCEEIAIgAzYCLAwBCyACKAIQDQELQX8gAhA6DQEaCyACIAAgA0HIAWogA0HQAGogA0GgAWoQPQshBSAEBH8gAkEAQQAgAigCJBECABogAkEANgIwIAIgBDYCLCACQQA2AhwgAigCFBogAkIANwMQQQAFIAULGiACIAIoAgAgAUEgcXI2AgBBAAsaIANB0AFqJAACQCAAIgNBA3EEQANAIAAtAABFDQIgAEEBaiIAQQNxDQALCwNAIAAiAUEEaiEAQYCChAggASgCACIEayAEckGAgYKEeHFBgIGChHhGDQALA0AgASIAQQFqIQEgAC0AAA0ACwsgAyAAIANrakEBay0AAEEKRwRAAkACQCACKAJMIgBBAE4EQCAARQ0BQfgVKAIAIABB/////wNxRw0BCwJAIAIoAlBBCkYNACACKAIUIgAgAigCEEYNACACIABBAWo2AhQgAEEKOgAADAILIAIQRQwBCyACIAIoAkwiAEH/////AyAAGzYCTAJAAkAgAigCUEEKRg0AIAIoAhQiACACKAIQRg0AIAIgAEEBajYCFCAAQQo6AAAMAQsgAhBFCyACKAJMGiACQQA2AkwLCwALBgAgACQACwQAIwALHABBnBcoAgBFBEBBoBcgATYCAEGcFyAANgIACwsL6AcWAEGACAu2AS0rICAgMFgweAAtMFgrMFggMFgtMHgrMHggMHgAdmVjdG9yAG5hbgBpbmYAYmFkX2FycmF5X25ld19sZW5ndGggd2FzIHRocm93biBpbiAtZm5vLWV4Y2VwdGlvbnMgbW9kZQBOQU4ASU5GAC4AKG51bGwpAGxlbmd0aF9lcnJvciB3YXMgdGhyb3duIGluIC1mbm8tZXhjZXB0aW9ucyBtb2RlIHdpdGggbWVzc2FnZSAiJXMiAEHACQsRAQAAAAIAAAADAAAABAAAAAUAQeQJC4IDAgAAAAMAAAAFAAAABwAAAAsAAAANAAAAEQAAABMAAAAXAAAAHQAAAB8AAAAlAAAAKQAAACsAAAAvAAAANQAAADsAAAA9AAAAQwAAAEcAAABJAAAATwAAAFMAAABZAAAAYQAAAGUAAABnAAAAawAAAG0AAABxAAAAfwAAAIMAAACJAAAAiwAAAJUAAACXAAAAnQAAAKMAAACnAAAArQAAALMAAAC1AAAAvwAAAMEAAADFAAAAxwAAANMAAAABAAAACwAAAA0AAAARAAAAEwAAABcAAAAdAAAAHwAAACUAAAApAAAAKwAAAC8AAAA1AAAAOwAAAD0AAABDAAAARwAAAEkAAABPAAAAUwAAAFkAAABhAAAAZQAAAGcAAABrAAAAbQAAAHEAAAB5AAAAfwAAAIMAAACJAAAAiwAAAI8AAACVAAAAlwAAAJ0AAACjAAAApwAAAKkAAACtAAAAswAAALUAAAC7AAAAvwAAAMEAAADFAAAAxwAAANEAAAAAAAAAWAgAQfAMC0EZAAsAGRkZAAAAAAUAAAAAAAAJAAAAAAsAAAAAAAAAABkACgoZGRkDCgcAAQAJCxgAAAkGCwAACwAGGQAAABkZGQBBwQ0LIQ4AAAAAAAAAABkACw0ZGRkADQAAAgAJDgAAAAkADgAADgBB+w0LAQwAQYcOCxUTAAAAABMAAAAACQwAAAAAAAwAAAwAQbUOCwEQAEHBDgsVDwAAAAQPAAAAAAkQAAAAAAAQAAAQAEHvDgsBEgBB+w4LHhEAAAAAEQAAAAAJEgAAAAAAEgAAEgAAGgAAABoaGgBBsg8LDhoAAAAaGhoAAAAAAAAJAEHjDwsBFABB7w8LFRcAAAAAFwAAAAAJFAAAAAAAFAAAFABBnRALARYAQakQCycVAAAAABUAAAAACRYAAAAAABYAABYAADAxMjM0NTY3ODlBQkNERUYAQdAQCwmwCwEAACAAAAUAQeQQCwEHAEH8EAsKCAAAAAkAAABgCwBBlBELAQIAQaQRCwj//////////wBB6BELAoAL";
@@ -0,0 +1,127 @@
1
+ // The native core: native/*.cpp compiled to one WebAssembly module
2
+ // (core-wasm.js, built by scripts/build-core-wasm.mjs), loaded lazily and
3
+ // synchronously the first time a pass asks for it.
4
+ //
5
+ // What it runs — each a bit-exact port of a JS pass, which stays as the
6
+ // fallback:
7
+ // creasedNormals geometry/creased-normals.js (+ blend-surfaces.js)
8
+ // the oracle's BVH oracle/bvh.js, via cachedBVH (+ min-wall.js)
9
+ //
10
+ // Bit-exact is the contract, not an aspiration: test/core-parity.test.js builds
11
+ // the reference parts both ways and requires identical output, so turning the
12
+ // core on or off changes no mesh, normal, edge, reading or verdict — only how
13
+ // long they take (several times faster with a JIT; far more on a host whose JS
14
+ // is interpreted).
15
+ //
16
+ // The switch: on by default wherever WebAssembly exists. `setCoreEnabled(false)`
17
+ // (exported from partforge/oracle and partforge/testing), or
18
+ // `globalThis.PARTFORGE_CORE = false` (read on every use, so it can be set any
19
+ // time), turns it off for that realm — a worker is its own realm, so a host sets
20
+ // it there. If the module cannot be instantiated the passes keep their JS.
21
+ //
22
+ // Failure is contained, never fatal: a failed allocation or a trap inside the
23
+ // module POISONS that instance (poisonCore) — nothing touches it again — and
24
+ // the pass that hit it, and every pass after, runs its JS instead. And because
25
+ // WebAssembly memory only ever grows, an instance whose memory passed
26
+ // RECYCLE_BYTES is dropped once nothing holds it (releaseIfIdle); the next pass
27
+ // boots a fresh one in a few milliseconds and the old memory goes to the GC.
28
+ import { CORE_WASM_BASE64 } from "./core-wasm.js";
29
+
30
+ // What the core may keep holding between passes. Ordinary forges never grow it
31
+ // past its 16 MB start; a preview mesh needs ~145 bytes/triangle at the peak
32
+ // (screw, 210k triangles: 29 MB; a 1M-triangle mesh: 138 MB). Re-booting costs a
33
+ // few milliseconds — the module is 64 KB — so cap the retained memory low.
34
+ export const RECYCLE_BYTES = 64 * 1024 * 1024;
35
+
36
+ let enabled = true;
37
+ let booted; // undefined: not tried yet (or recycled); null: unavailable or poisoned
38
+
39
+ export function setCoreEnabled(on) { enabled = !!on; }
40
+
41
+ const flagOff = () => globalThis.PARTFORGE_CORE === false || globalThis.PARTFORGE_CORE === "off";
42
+
43
+ // The live core, or null when disabled, unavailable or poisoned.
44
+ export function core() {
45
+ if (!enabled || flagOff()) return null;
46
+ if (booted === undefined) booted = boot();
47
+ return booted;
48
+ }
49
+
50
+ // The instance `c` faulted (a trap, or an allocation that failed): never use it
51
+ // again in this realm. Objects still holding it check `c.poisoned` and fall back.
52
+ export function poisonCore(c) {
53
+ if (c) c.poisoned = true;
54
+ if (booted === c || c == null) booted = null;
55
+ }
56
+
57
+ // Drop `c` if its memory grew past RECYCLE_BYTES and nothing holds it (no live
58
+ // BVH); the next core() boots a fresh, small instance.
59
+ export function releaseIfIdle(c) {
60
+ if (booted === c && c.live === 0 && c.x.memory.buffer.byteLength > RECYCLE_BYTES) booted = undefined;
61
+ }
62
+
63
+ // Tests only: install a stand-in instance (or undefined to re-boot).
64
+ export function setCoreForTesting(c) { booted = c; }
65
+
66
+ const B64 = (() => {
67
+ const t = new Uint8Array(128);
68
+ const a = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
69
+ for (let i = 0; i < a.length; i++) t[a.charCodeAt(i)] = i;
70
+ return t;
71
+ })();
72
+ // Not atob: some JS hosts (an app's own JavaScriptCore context) have none.
73
+ function decodeBase64(s) {
74
+ let n = s.length;
75
+ while (n > 0 && s[n - 1] === "=") n--;
76
+ const out = new Uint8Array((n * 3) >> 2);
77
+ let o = 0;
78
+ for (let i = 0; i < n; i += 4) {
79
+ const v = (B64[s.charCodeAt(i)] << 18) | (B64[s.charCodeAt(i + 1)] << 12)
80
+ | (i + 2 < n ? B64[s.charCodeAt(i + 2)] << 6 : 0) | (i + 3 < n ? B64[s.charCodeAt(i + 3)] : 0);
81
+ out[o++] = v >> 16;
82
+ if (i + 2 < n) out[o++] = (v >> 8) & 255;
83
+ if (i + 3 < n) out[o++] = v & 255;
84
+ }
85
+ return out;
86
+ }
87
+
88
+ function boot() {
89
+ if (typeof WebAssembly !== "object") return null;
90
+ try {
91
+ const stub = () => 0;
92
+ // Synchronous on purpose: a pass asks mid-build and must get an answer now.
93
+ // The module is small (well under every engine's synchronous-compile limit).
94
+ const instance = new WebAssembly.Instance(new WebAssembly.Module(decodeBase64(CORE_WASM_BASE64)), {
95
+ env: { emscripten_notify_memory_growth: () => {} },
96
+ wasi_snapshot_preview1: { fd_close: stub, fd_write: stub, fd_seek: stub },
97
+ });
98
+ const x = instance.exports;
99
+ x._initialize?.();
100
+ // One 32-double scratch block for small inputs and outputs.
101
+ const scratch = x.malloc(32 * 8);
102
+ return {
103
+ x,
104
+ scratch,
105
+ live: 0, // core BVHs not yet disposed (they pin this instance)
106
+ poisoned: false,
107
+ // Never hands out 0: a failed malloc (memory exhausted) throws instead, so
108
+ // nothing is ever written over the module's low memory.
109
+ alloc(bytes) {
110
+ const ptr = x.malloc(bytes || 1);
111
+ if (!ptr) throw new Error("partforge core: out of WebAssembly memory");
112
+ return ptr;
113
+ },
114
+ // Views are rebuilt per use: any call that grows memory detaches the old buffer.
115
+ f64: () => new Float64Array(x.memory.buffer, scratch, 32),
116
+ copyIn(arr) {
117
+ if (!arr || arr.length === 0) return 0;
118
+ const ptr = this.alloc(arr.byteLength);
119
+ new Uint8Array(x.memory.buffer, ptr, arr.byteLength).set(new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength));
120
+ return ptr;
121
+ },
122
+ copyOut: (Ctor, ptr, len) => (ptr && len ? new Ctor(x.memory.buffer, ptr, len).slice() : new Ctor(0)),
123
+ };
124
+ } catch {
125
+ return null;
126
+ }
127
+ }
@@ -0,0 +1,143 @@
1
+ // creasedNormals(g, opts) on the native core (native/creased_normals.cpp) —
2
+ // same arguments, same result object, same bits as the JS in
3
+ // geometry/creased-normals.js, which dispatches here when the core is on.
4
+ //
5
+ // JS keeps only per-SURFACE work: the shading-policy table (Map lookups and
6
+ // Math.cos, so no second libm decides a cosine), the feature label strings, and
7
+ // flattening each fillet descriptor (blend-surfaces.js) into numbers once.
8
+ // Everything per vertex or per triangle runs in C++.
9
+ import { SMOOTH, COPLANAR_ANGLE, cosDeg } from "../geometry/shading-policy.js";
10
+ import { releaseIfIdle } from "./core.js";
11
+
12
+ const COPLANAR_COS = cosDeg(COPLANAR_ANGLE);
13
+ const ANALYTIC_COS = cosDeg(25); // creased-normals.js's ANALYTIC_COS
14
+ const EMPTY = new Uint32Array(0);
15
+ const KIND = { line: 1, point: 2, circle: 3, path: 4, spine: 5, planes: 6 };
16
+
17
+ // native/blend_surfaces.h's flat layout: [kind, closed, n, ...kind fields].
18
+ // An unknown kind flattens to 0, which evaluates to "no normal" — exactly what
19
+ // surfaceNormal does with one.
20
+ function flattenDescriptor(desc, out) {
21
+ const kind = KIND[desc.kind] ?? 0;
22
+ const pts = desc.pts ?? [];
23
+ const v = (p) => out.push(p[0], p[1], p[2]);
24
+ if (kind === 6) {
25
+ out.push(kind, 0, desc.planes.length, desc.tol);
26
+ for (const pl of desc.planes) { v(pl.n); out.push(pl.d); }
27
+ return;
28
+ }
29
+ out.push(kind, desc.closed ? 1 : 0, pts.length);
30
+ switch (kind) {
31
+ case 1: v(desc.p); v(desc.d); break;
32
+ case 2: v(desc.c); break;
33
+ case 3: v(desc.c); v(desc.a); out.push(desc.R); break;
34
+ case 4: out.push(desc.kf, desc.kd); v(desc.f); pts.forEach(v); desc.dirs.forEach(v); break;
35
+ case 5: out.push(desc.r); pts.forEach(v); break;
36
+ }
37
+ }
38
+
39
+ // Can the core take this mesh? The C++ reads the arrays' raw bytes and trusts
40
+ // their indices, where the JS tolerated (or simply read undefined from) a
41
+ // malformed mesh — so anything but Manifold's own MeshGL shape, typed exactly
42
+ // and with every index in range, goes to the JS pass instead. Cheap: O(runs +
43
+ // merges), never O(triangles).
44
+ export function coreAccepts(g) {
45
+ const vp = g?.vertProperties, tris = g?.triVerts, ri = g?.runIndex, roid = g?.runOriginalID;
46
+ if (!(vp instanceof Float32Array) || !(tris instanceof Uint32Array)) return false;
47
+ if (!(ri instanceof Uint32Array) || !(roid instanceof Uint32Array) || ri.length !== roid.length + 1) return false;
48
+ if (!(g.numProp >= 3) || tris.length % 3 !== 0) return false;
49
+ const nVert = (vp.length / g.numProp) | 0;
50
+ for (let r = 0; r < roid.length; r++) if (ri[r] > ri[r + 1] || ri[r + 1] > tris.length) return false;
51
+ const mf = g.mergeFromVert, mt = g.mergeToVert;
52
+ if (mf != null || mt != null) {
53
+ if (!(mf instanceof Uint32Array) || !(mt instanceof Uint32Array) || mf.length !== mt.length) return false;
54
+ for (let i = 0; i < mf.length; i++) if (mf[i] >= nVert || mt[i] >= nVert) return false;
55
+ }
56
+ // Triangle indices are range-checked in C++ (one pass it already makes);
57
+ // see cn_create. Here: the cheap structural facts.
58
+ return true;
59
+ }
60
+
61
+ // Returns null when the core refuses the mesh (see cn_create); the caller then
62
+ // runs the JS pass.
63
+ export function creasedNormalsCore(c, g, { policies = null, featureLabels = null, surfaces = null } = {}) {
64
+ const { x } = c;
65
+ const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
66
+ const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
67
+ const roid = g.runOriginalID, ri = g.runIndex;
68
+ const mf = g.mergeFromVert ?? EMPTY, mt = g.mergeToVert ?? EMPTY;
69
+
70
+ // Policy table: every surface id in this mesh, then the SMOOTH default row.
71
+ const oidList = [...new Set(roid)];
72
+ const n = oidList.length + 1;
73
+ const oids = new Uint32Array(n), creaseCos = new Float64Array(n), flags = new Uint8Array(n), labelIds = new Int32Array(n);
74
+ const labelOf = new Map(), labels = [];
75
+ const row = (i, pol, label) => {
76
+ creaseCos[i] = cosDeg(pol.creaseAngle);
77
+ flags[i] = (pol.boundaryLines ? 1 : 0) | (pol.sameSurfaceLines ? 2 : 0);
78
+ if (label === undefined) { labelIds[i] = -1; return; }
79
+ let id = labelOf.get(label);
80
+ if (id === undefined) { id = labels.length; labels.push(label); labelOf.set(label, id); }
81
+ labelIds[i] = id;
82
+ };
83
+ oidList.forEach((oid, i) => {
84
+ oids[i] = oid;
85
+ row(i, (policies && policies.get(oid)) || SMOOTH, featureLabels?.size ? featureLabels.get(oid) : undefined);
86
+ });
87
+ row(n - 1, SMOOTH, undefined);
88
+
89
+ // Fillet surfaces: one flattened copy per distinct descriptor, run → descriptor
90
+ // index, and each run's transform (IDENTITY when the mesh carries none for it).
91
+ let runDesc = null, runXf = null, descData = null, descOffsets = null;
92
+ if (surfaces?.size) {
93
+ const index = new Map(), flat = [], offsets = [0];
94
+ runDesc = new Int32Array(roid.length).fill(-1);
95
+ for (let r = 0; r < roid.length; r++) {
96
+ const desc = surfaces.get(roid[r]);
97
+ if (!desc) continue;
98
+ let di = index.get(desc);
99
+ if (di === undefined) { di = index.size; index.set(desc, di); flattenDescriptor(desc, flat); offsets.push(flat.length); }
100
+ runDesc[r] = di;
101
+ }
102
+ if (index.size) {
103
+ const rt = g.runTransform;
104
+ runXf = new Float64Array(roid.length * 12);
105
+ for (let r = 0; r < roid.length; r++) {
106
+ if (rt && rt.length >= (r + 1) * 12) for (let k = 0; k < 12; k++) runXf[r * 12 + k] = rt[r * 12 + k];
107
+ else runXf.set([1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0], r * 12);
108
+ }
109
+ descData = Float64Array.from(flat);
110
+ descOffsets = Uint32Array.from(offsets);
111
+ } else runDesc = null;
112
+ }
113
+
114
+ // Inputs are borrowed by the state until destroy; free them after.
115
+ const inputs = [c.copyIn(vp), c.copyIn(tris), c.copyIn(mf), c.copyIn(mt), c.copyIn(ri), c.copyIn(roid)];
116
+ const state = x.cn_create(inputs[0], np, nVert, inputs[1], nTri, inputs[2], inputs[3], mf.length, inputs[4], inputs[5], roid.length);
117
+ if (!state) { // a triangle index out of range: not a mesh the core takes
118
+ for (const p of inputs) if (p) x.free(p);
119
+ return null;
120
+ }
121
+ const args = [c.copyIn(oids), c.copyIn(creaseCos), c.copyIn(flags), c.copyIn(labelIds),
122
+ c.copyIn(runDesc), c.copyIn(runXf), c.copyIn(descData), c.copyIn(descOffsets)];
123
+ try {
124
+ x.cn_finish(state, args[0], args[1], args[2], args[3], n, COPLANAR_COS, ANALYTIC_COS,
125
+ args[4], args[5], args[6], args[7], descOffsets ? descOffsets.length - 1 : 0);
126
+ const nf = x.cn_feature_count(state);
127
+ const out = {
128
+ positions: c.copyOut(Float32Array, x.cn_positions(state), nTri * 9),
129
+ normals: c.copyOut(Float32Array, x.cn_normals(state), nTri * 9),
130
+ triangles: nTri,
131
+ edges: c.copyOut(Float32Array, x.cn_edges(state), x.cn_edge_floats(state)),
132
+ };
133
+ if (nf) {
134
+ out.featureIds = c.copyOut(Uint16Array, x.cn_feature_ids(state), nTri);
135
+ out.features = [...c.copyOut(Int32Array, x.cn_feature_labels(state), nf)].map((id) => labels[id]);
136
+ }
137
+ return out;
138
+ } finally {
139
+ x.cn_destroy(state);
140
+ for (const p of [...inputs, ...args]) if (p) x.free(p);
141
+ releaseIfIdle(c);
142
+ }
143
+ }
@@ -22,6 +22,12 @@
22
22
  // { kind: "spine", pts, closed, r }
23
23
  // general chain (mesh-fillet generalTool): the
24
24
  // ball-centre polyline itself; r is the radius
25
+ // { kind: "planes", planes: [{ n, d }], tol }
26
+ // roundAll's flat faces (mesh-roundall.js
27
+ // flatFacePlanes): a point within tol of one plane
28
+ // (n·x = d) takes its normal; anywhere else — the
29
+ // rounded band off its seams — there is none, and
30
+ // creased-normals keeps the facet average
25
31
  //
26
32
  // A path's polyline usually STANDS FOR a smooth curve (a circle's rim, an outline's
27
33
  // rounded corner): its per-segment cylinders would shade faceted around the curve,
@@ -40,6 +46,7 @@
40
46
  // boolean and re-stamp that carries runTransform along (Manifold does, verified).
41
47
  // Pure module: no DOM, no node:, no three.
42
48
 
49
+ import { hypot3 } from "./js-math.js";
43
50
  const EPS = 1e-12;
44
51
 
45
52
  // --- 3x4 column-major affine helpers (Manifold's runTransform layout) -------------
@@ -77,7 +84,7 @@ export function invertAffine(M) {
77
84
  }
78
85
 
79
86
  const norm = (v) => {
80
- const l = Math.hypot(v[0], v[1], v[2]);
87
+ const l = hypot3(v[0], v[1], v[2]);
81
88
  return l > EPS ? [v[0] / l, v[1] / l, v[2] / l] : null;
82
89
  };
83
90
 
@@ -105,10 +112,32 @@ export function mapSurface(desc, M) {
105
112
  M[0] * (M[4] * M[8] - M[5] * M[7]) - M[3] * (M[1] * M[8] - M[2] * M[7]) + M[6] * (M[1] * M[5] - M[2] * M[4])));
106
113
  return { kind: "spine", closed: desc.closed, pts: desc.pts.map((p) => applyPt(M, p)), r: desc.r * s };
107
114
  }
115
+ case "planes": {
116
+ const s = Math.cbrt(Math.abs(
117
+ M[0] * (M[4] * M[8] - M[5] * M[7]) - M[3] * (M[1] * M[8] - M[2] * M[7]) + M[6] * (M[1] * M[5] - M[2] * M[4])));
118
+ return { kind: "planes", tol: desc.tol * s, planes: desc.planes.map(({ n, d }) => {
119
+ const n2 = norm(applyDir(M, n)) ?? n;
120
+ const p = applyPt(M, [n[0] * d, n[1] * d, n[2] * d]);
121
+ return { n: n2, d: n2[0] * p[0] + n2[1] * p[1] + n2[2] * p[2] };
122
+ }) };
123
+ }
108
124
  default: throw new Error(`blend surface: unknown kind ${desc.kind}`);
109
125
  }
110
126
  }
111
127
 
128
+ // The plane x lies on, or null — off every plane, or on two at once (where two
129
+ // flat faces would meet, which a rounded result never shows, so no answer is right).
130
+ function planeNormal(desc, x) {
131
+ let hit = null;
132
+ for (const pl of desc.planes) {
133
+ const n = pl.n;
134
+ if (Math.abs(n[0] * x[0] + n[1] * x[1] + n[2] * x[2] - pl.d) > desc.tol) continue;
135
+ if (hit) return null;
136
+ hit = n;
137
+ }
138
+ return hit;
139
+ }
140
+
112
141
  // Nearest spine point to x, in the descriptor's own frame.
113
142
  function spinePoint(desc, x) {
114
143
  switch (desc.kind) {
@@ -175,7 +204,7 @@ function segmentGrid(desc) {
175
204
  if (g) return g;
176
205
  const { pts, closed } = desc, n = pts.length, nSeg = closed ? n : n - 1;
177
206
  let total = 0;
178
- for (let i = 0; i < nSeg; i++) { const p = pts[i], q = pts[(i + 1) % n]; total += Math.hypot(q[0] - p[0], q[1] - p[1], q[2] - p[2]); }
207
+ for (let i = 0; i < nSeg; i++) { const p = pts[i], q = pts[(i + 1) % n]; total += hypot3(q[0] - p[0], q[1] - p[1], q[2] - p[2]); }
179
208
  const h = Math.max(total / Math.max(1, nSeg), Math.abs(desc.kf ?? 0) + Math.abs(desc.kd ?? 0) + (desc.r ?? 0), 1e-6);
180
209
  const cells = new Map();
181
210
  // numeric hashed cell keys: a collision only adds candidates, each distance-checked
@@ -240,6 +269,7 @@ function nearestSegment(desc, x) {
240
269
  // Unit spine→point direction at x in the descriptor's frame, or null where undefined.
241
270
  export function surfaceNormal(desc, x) {
242
271
  if (desc.kind === "path") return pathNormal(desc, x);
272
+ if (desc.kind === "planes") return planeNormal(desc, x);
243
273
  if (desc.kind === "spine") {
244
274
  const { bi, bt } = nearestSegment(desc, x);
245
275
  if (bi < 0) return null;
@@ -18,6 +18,9 @@
18
18
  // side, and any band vertex riding a face edge as a T-junction all agree.
19
19
  import { SMOOTH, COPLANAR_ANGLE, MIN_EDGE, MIN_FACE, cosDeg } from "./shading-policy.js";
20
20
  import { affineAt, IDENTITY, runEvaluator } from "./blend-surfaces.js";
21
+ import { hypot3 } from "./js-math.js";
22
+ import { core, poisonCore } from "../core/core.js";
23
+ import { coreAccepts, creasedNormalsCore } from "../core/creased-normals-core.js";
21
24
 
22
25
  const COPLANAR_COS = cosDeg(COPLANAR_ANGLE);
23
26
  const MIN_EDGE2 = MIN_EDGE * MIN_EDGE;
@@ -33,7 +36,25 @@ const SHADE_CELL = 1e-3; // its hash-grid cell
33
36
  // Vertex-normal sliver cutoff (mm of triangle height): see the smooth loop below.
34
37
  const SHADE_SLIVER = 1e-3;
35
38
 
36
- export function creasedNormals(g, { policies = null, featureLabels = null, surfaces = null } = {}) {
39
+ // The pass every Manifold mesh goes through: on the native core when it is on
40
+ // (core/creased-normals-core.js — same bits, several times faster), else the JS
41
+ // below. test/core-parity.test.js holds the two to identical output. The core
42
+ // takes only well-formed MeshGL (coreAccepts / cn_create); a fault inside it
43
+ // poisons that instance and this mesh, and every one after, runs the JS.
44
+ export function creasedNormals(g, opts) {
45
+ const c = core();
46
+ if (c && coreAccepts(g)) {
47
+ try {
48
+ const out = creasedNormalsCore(c, g, opts);
49
+ if (out) return out;
50
+ } catch {
51
+ poisonCore(c);
52
+ }
53
+ }
54
+ return creasedNormalsJS(g, opts);
55
+ }
56
+
57
+ export function creasedNormalsJS(g, { policies = null, featureLabels = null, surfaces = null } = {}) {
37
58
  const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
38
59
  const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
39
60
 
@@ -105,7 +126,7 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
105
126
  const vx = vp[c] - vp[a], vy = vp[c + 1] - vp[a + 1], vz = vp[c + 2] - vp[a + 2];
106
127
  const wx = vp[c] - vp[b], wy = vp[c + 1] - vp[b + 1], wz = vp[c + 2] - vp[b + 2];
107
128
  const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
108
- const L0 = Math.hypot(nx, ny, nz), L = L0 || 1; // the || 1 is for the normal divide ONLY
129
+ const L0 = hypot3(nx, ny, nz), L = L0 || 1; // the || 1 is for the normal divide ONLY
109
130
  fn[t * 3] = nx / L; fn[t * 3 + 1] = ny / L; fn[t * 3 + 2] = nz / L;
110
131
  const longest = Math.max(ux * ux + uy * uy + uz * uz, vx * vx + vy * vy + vz * vz, wx * wx + wy * wy + wz * wz);
111
132
  // |cross| / maxEdge = min height — from the RAW cross magnitude, never the
@@ -188,7 +209,7 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
188
209
  const an = analyticAt(t2, weld[v]);
189
210
  if (an) { ax += an[0]; ay += an[1]; az += an[2]; any = true; }
190
211
  }
191
- const L = Math.hypot(ax, ay, az);
212
+ const L = hypot3(ax, ay, az);
192
213
  return any && L > 1e-9 ? [ax / L, ay / L, az / L] : null;
193
214
  };
194
215
 
@@ -248,8 +269,8 @@ export function creasedNormals(g, { policies = null, featureLabels = null, surfa
248
269
  }
249
270
  }
250
271
  if (!solid) { nx = sx; ny = sy; nz = sz; }
251
- if (analytic && Math.hypot(ax, ay, az) > 1e-9) { nx = ax; ny = ay; nz = az; }
252
- const L = Math.hypot(nx, ny, nz) || 1;
272
+ if (analytic && hypot3(ax, ay, az) > 1e-9) { nx = ax; ny = ay; nz = az; }
273
+ const L = hypot3(nx, ny, nz) || 1;
253
274
  const o = (t * 3 + k) * 3, vv = v * np;
254
275
  positions[o] = vp[vv]; positions[o + 1] = vp[vv + 1]; positions[o + 2] = vp[vv + 2];
255
276
  normals[o] = nx / L; normals[o + 1] = ny / L; normals[o + 2] = nz / L;
@@ -0,0 +1,14 @@
1
+ // partforge's own hypot, for the passes the native core (src/framework/core/)
2
+ // mirrors in C++ — creased-normals.js, blend-surfaces.js and min-wall.js.
3
+ //
4
+ // Math.hypot is not one function: JavaScriptCore computes it as libc++'s fused
5
+ // std::hypot(x, y, z) and V8 as a Kahan-summed sum of scaled squares, and the
6
+ // two disagree in the last bit on about a third of inputs — so the same part
7
+ // shaded, measured and hashed slightly differently in Safari and in Chrome, and
8
+ // no C++ could match "the JS" in both. This is three multiplies, two adds and a
9
+ // correctly rounded square root, each rounded in order: the same on every
10
+ // engine (JS never fuses), and reproduced exactly by native/js_math.h.
11
+ //
12
+ // No overflow scaling: inputs are millimetre coordinates and their
13
+ // differences, nowhere near 1e154. Keep this file and native/js_math.h in step.
14
+ export const hypot3 = (x, y, z) => Math.sqrt(x * x + y * y + z * z);
@@ -18,8 +18,8 @@ import { meshToStl } from "./mesh-stl.js";
18
18
  import { creasedNormals } from "./creased-normals.js";
19
19
  import { loftShadingPolicy, SMOOTH, BLEND } from "./shading-policy.js";
20
20
  import { meshFillet, meshChamfer, UnsupportedEdgeError } from "./mesh-fillet.js";
21
- import { affineAt, invertAffine, mapSurface } from "./blend-surfaces.js";
22
- import { meshRoundAll, prismSection, roundAllSegs } from "./mesh-roundall.js";
21
+ import { affineAt, IDENTITY, invertAffine, mapSurface } from "./blend-surfaces.js";
22
+ import { flatFacePlanes, meshRoundAll, prismSection, roundAllSegs } from "./mesh-roundall.js";
23
23
  import { SEGS, circleSegs, doubleCurvatureSegs } from "./circle-segs.js";
24
24
  import { checkBooleanResult } from "./boolean-gate.js";
25
25
  import { KernelCapabilityError } from "./errors.js";
@@ -294,12 +294,20 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
294
294
  // round-trip, so the descriptor's original frame stays valid). Folding the band
295
295
  // into a single blend id, as this used to, lost every descriptor with it: a labeled
296
296
  // fillet shaded with facet normals again.
297
+ //
298
+ // "Blend" here is any surface that must keep an id of its own: a fillet band (the
299
+ // boundaryLines policy) or a surface carrying an analytic descriptor at all —
300
+ // roundAll's flat-face planes ride on a SMOOTH surface, and folding that into the
301
+ // base id would drop them and bring the flat-face shading gradient back on every
302
+ // labeled roundAll. Each keeps the policy it had (none, for the roundAll surface).
303
+ const keepsOwnId = (oid) => !!oidPolicies.get(oid)?.boundaryLines || blendSurfaces.has(oid);
297
304
  const reserveBlendRestamp = (oids) => {
298
- const blends = [...oids].filter((oid) => !!oidPolicies.get(oid)?.boundaryLines);
305
+ const blends = [...oids].filter(keepsOwnId);
299
306
  const baseId = Manifold.reserveIDs(1 + blends.length);
300
307
  const blendIdFor = new Map(blends.map((oid, i) => [oid, baseId + 1 + i]));
301
308
  for (const [oid, id2] of blendIdFor) {
302
- oidPolicies.set(id2, BLEND);
309
+ const pol = oidPolicies.get(oid);
310
+ if (pol !== undefined) oidPolicies.set(id2, pol);
303
311
  const surf = blendSurfaces.get(oid);
304
312
  if (surf) blendSurfaces.set(id2, surf);
305
313
  }
@@ -405,7 +413,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
405
413
  const isBlend = (oid) => !!oidPolicies.get(oid)?.boundaryLines;
406
414
  if (![...new Set(g0.runOriginalID)].some(isBlend)) return T(filleted._m.asOriginal());
407
415
  const { baseId, blendIdFor } = reserveBlendRestamp(new Set(g0.runOriginalID));
408
- g0.runOriginalID = Uint32Array.from(g0.runOriginalID, (o) => (isBlend(o) ? blendIdFor.get(o) : baseId));
416
+ g0.runOriginalID = Uint32Array.from(g0.runOriginalID, (o) => blendIdFor.get(o) ?? baseId);
409
417
  // The constructor re-welds, and that can pinch a latent sliver off a
410
418
  // component as fresh femto-debris (the same rebirth dropDebris's own
411
419
  // compose() loop guards against) — sweep the reconstruction too.
@@ -423,6 +431,39 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
423
431
  }
424
432
  };
425
433
 
434
+ // The reference roundAll's flat faces (mesh-roundall.js flatFacePlanes): the
435
+ // input's flat faces, which the chain returns exactly to their planes, become a
436
+ // "planes" descriptor on the result's surface so creased-normals shades them —
437
+ // and the band's seams beside them — with the plane's own normal. The tolerance
438
+ // sits well under the first ring of band vertices off each face (the same ring
439
+ // meshRoundAll's simplify tolerance protects), so only the face and its seam
440
+ // vertices are on a plane. Keyed on geometry like every descriptor (see
441
+ // blendSurfaces above), so it is never removed with the cache entry.
442
+ const markFlatFaces = (input, out, r) => {
443
+ const gi = input.getMesh();
444
+ let planes;
445
+ try {
446
+ planes = flatFacePlanes(gi, { policyFor: (oid) => oidPolicies.get(oid) });
447
+ } finally {
448
+ gi.delete?.();
449
+ }
450
+ if (!planes.length) return out;
451
+ const segs = roundAllSegs(2 * r, quality);
452
+ const tol = Math.min(1e-3, 0.25 * r * (1 - Math.cos((2 * Math.PI) / segs)));
453
+ const go = out.getMesh();
454
+ try {
455
+ const roid = go.runOriginalID, rt = go.runTransform;
456
+ for (let i = 0; i < roid.length; i++) {
457
+ // a fresh original carries no runTransform at all — identity, as creased-normals reads it
458
+ const inv = rt && rt.length >= (i + 1) * 12 ? invertAffine(affineAt(rt, i)) : IDENTITY;
459
+ if (inv) blendSurfaces.set(roid[i], mapSurface({ kind: "planes", planes, tol }, inv));
460
+ }
461
+ } finally {
462
+ go.delete?.();
463
+ }
464
+ return out;
465
+ };
466
+
426
467
  // Replay a recorded transform chain onto a solid. Each record maps back to the op
427
468
  // that produced it, so the replayed solid rebuilds the same chain on its own canon.
428
469
  const replay = (solid, chain) => chain.reduce(
@@ -503,7 +544,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
503
544
  // key omits it for the same reason); it just spells out that the ball
504
545
  // tessellation, and so the result, is tier-dependent.
505
546
  return cached(h("roundAll", hash, r, quality), () =>
506
- prismRoundAllFast(m, hash, r) ?? T(meshRoundAll(wasm, m, r, quality)));
547
+ prismRoundAllFast(m, hash, r) ?? markFlatFaces(m, T(meshRoundAll(wasm, m, r, quality)), r));
507
548
  },
508
549
  // batch difference: first minus the union of the rest, evaluated as one boolean
509
550
  // tree — no materialized intermediate union (the unionRaw memory note applies)
@@ -538,7 +579,6 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
538
579
  // fresh so cached-solid reuse under another label cannot collide — the same
539
580
  // guarantee asOriginal() gives the plain path below.
540
581
  const g0 = m.getMesh();
541
- const isBlend = (oid) => !!oidPolicies.get(oid)?.boundaryLines;
542
582
  const oids0 = new Set(g0.runOriginalID);
543
583
  // Sector-aware re-stamp: a provenance-sectored loft (the `sector` policy
544
584
  // marker) must keep every run's identity — folding them (either the plain
@@ -561,14 +601,16 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
561
601
  featureLabels.set(newId, name);
562
602
  const pol = oidPolicies.get(oldId);
563
603
  if (pol !== undefined) oidPolicies.set(newId, pol);
604
+ const surf = blendSurfaces.get(oldId); // analytic normals ride the 1:1 stamp too
605
+ if (surf) blendSurfaces.set(newId, surf);
564
606
  setIds.push(newId);
565
607
  }
566
608
  return { value: wrap(o, lh), pin: o, dispose: () => {
567
- for (const id2 of setIds) { featureLabels.delete(id2); oidPolicies.delete(id2); }
609
+ for (const id2 of setIds) { featureLabels.delete(id2); oidPolicies.delete(id2); blendSurfaces.delete(id2); }
568
610
  o.delete?.();
569
611
  } };
570
612
  }
571
- if ([...oids0].some(isBlend)) {
613
+ if ([...oids0].some(keepsOwnId)) {
572
614
  const { baseId, blendIdFor, blendIds } = reserveBlendRestamp(oids0);
573
615
  // base-group policy: the same triangle-weighted majority vote as the plain
574
616
  // path, but over the NON-blend runs only — blend runs would elect BLEND for
@@ -578,7 +620,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
578
620
  const weightByKey = new Map();
579
621
  let bestWeight = -1, basePol;
580
622
  for (let r = 0; r < roid.length; r++) {
581
- if (isBlend(roid[r])) continue;
623
+ if (blendIdFor.has(roid[r])) continue;
582
624
  const pol = oidPolicies.get(roid[r]) ?? SMOOTH;
583
625
  const key = `${pol.creaseAngle}/${pol.sameSurfaceLines}/${!!pol.boundaryLines}`;
584
626
  const weight = (weightByKey.get(key) || 0) + (ri[r + 1] / 3 - ri[r] / 3);
@@ -586,7 +628,7 @@ export function createManifoldKernel(wasm, { quality = "preview" } = {}) {
586
628
  const better = weight > bestWeight || (weight === bestWeight && !pol.sameSurfaceLines && basePol?.sameSurfaceLines);
587
629
  if (better) { bestWeight = weight; basePol = pol; }
588
630
  }
589
- g0.runOriginalID = Uint32Array.from(roid, (o2) => (isBlend(o2) ? blendIdFor.get(o2) : baseId));
631
+ g0.runOriginalID = Uint32Array.from(roid, (o2) => blendIdFor.get(o2) ?? baseId);
590
632
  const o = T(new Manifold(g0));
591
633
  g0.delete?.();
592
634
  featureLabels.set(baseId, name);
@@ -29,6 +29,7 @@
29
29
  // the two facetings still meets the tier's sagitta tolerance.
30
30
 
31
31
  import { segsForSagitta } from "./circle-segs.js";
32
+ import { SMOOTH, cosDeg } from "./shading-policy.js";
32
33
 
33
34
  // Sphere tessellation from the facet sagitta r·(1 − cos(π/segs)): pick the
34
35
  // fewest segments that keep it under the quality tier's tolerance — its own
@@ -83,6 +84,121 @@ export function meshRoundAll(wasm, m, r, quality) {
83
84
  }
84
85
  }
85
86
 
87
+ // ---------------------------------------------------------------------------
88
+ // Flat-face shading. The reference path's result is one fresh surface, shaded
89
+ // SMOOTH (35° crease), and the rounding ball's facets bend far less than that, so
90
+ // a flat face used to share its corner normals with the band facets around it.
91
+ // The vertex sum is unweighted, so a large face split into two triangles — a
92
+ // sloped palm plate's top — took a several-degree tilt at each corner and showed
93
+ // it as a shading gradient across the whole face (cloud feedback #167).
94
+ //
95
+ // The cure rests on the invariant above: the chain returns every planar face of
96
+ // the input to its own plane. So the input's flat faces, found here, say exactly
97
+ // where the result is flat; the backend registers them as an analytic "planes"
98
+ // descriptor (blend-surfaces.js), and creased-normals then shades every vertex on
99
+ // one of those planes — the band's seam vertices too, since the band is tangent
100
+ // there — with the plane's normal, the same way a fillet band's seam agrees with
101
+ // its face.
102
+ //
103
+ // "Flat" means flat the way the INPUT shades it: a coplanar group counts only if
104
+ // every edge bounding it is one creased-normals would shade hard (a bend past the
105
+ // surface's crease angle, or a cut seam). A rod's wall facets, or a slot's sides
106
+ // running tangentially into its round ends, meet their neighbours softly — the
107
+ // input already shades them as part of a curved surface, and pinning them to
108
+ // their own planes would facet the rounded result.
109
+ //
110
+ // `g` is a MeshGL (or the same fields on plain arrays); `policyFor(oid)` returns
111
+ // that surface's shading policy. Returns [{ n, d }] with n·x = d on the plane.
112
+ const PLANE_COS = cosDeg(0.05); // coplanar neighbours: a boolean split, not a bend
113
+ export function flatFacePlanes(g, { policyFor = () => SMOOTH } = {}) {
114
+ const np = g.numProp, vp = g.vertProperties, tris = g.triVerts;
115
+ const nTri = (tris.length / 3) | 0, nVert = (vp.length / np) | 0;
116
+ const remap = new Uint32Array(nVert);
117
+ for (let i = 0; i < nVert; i++) remap[i] = i;
118
+ const mf = g.mergeFromVert, mt = g.mergeToVert;
119
+ if (mf && mt) for (let i = 0; i < mf.length; i++) remap[mf[i]] = mt[i];
120
+ const triOID = new Uint32Array(nTri);
121
+ const ri = g.runIndex, roid = g.runOriginalID;
122
+ if (ri && roid) for (let r = 0; r < roid.length; r++)
123
+ for (let t = ri[r] / 3; t < ri[r + 1] / 3; t++) triOID[t] = roid[r];
124
+
125
+ // facet normals, areas and centroids; a degenerate triangle has no normal and
126
+ // takes no part — it neither joins a face nor disqualifies one
127
+ const fn = new Float64Array(nTri * 3), area = new Float64Array(nTri), cen = new Float64Array(nTri * 3);
128
+ let span = 0;
129
+ for (let t = 0; t < nTri; t++) {
130
+ const a = tris[t * 3] * np, b = tris[t * 3 + 1] * np, c = tris[t * 3 + 2] * np;
131
+ const ux = vp[b] - vp[a], uy = vp[b + 1] - vp[a + 1], uz = vp[b + 2] - vp[a + 2];
132
+ const vx = vp[c] - vp[a], vy = vp[c + 1] - vp[a + 1], vz = vp[c + 2] - vp[a + 2];
133
+ const nx = uy * vz - uz * vy, ny = uz * vx - ux * vz, nz = ux * vy - uy * vx;
134
+ const L = Math.hypot(nx, ny, nz);
135
+ area[t] = L / 2;
136
+ if (L > 0) { fn[t * 3] = nx / L; fn[t * 3 + 1] = ny / L; fn[t * 3 + 2] = nz / L; }
137
+ for (let k = 0; k < 3; k++) cen[t * 3 + k] = (vp[a + k] + vp[b + k] + vp[c + k]) / 3;
138
+ span = Math.max(span, Math.abs(vp[a]), Math.abs(vp[a + 1]), Math.abs(vp[a + 2]));
139
+ }
140
+ const live = (t) => area[t] > 1e-9;
141
+ const dot = (t, u) => fn[t * 3] * fn[u * 3] + fn[t * 3 + 1] * fn[u * 3 + 1] + fn[t * 3 + 2] * fn[u * 3 + 2];
142
+
143
+ // edge → incident triangles, on welded vertex ids
144
+ const edges = new Map();
145
+ for (let t = 0; t < nTri; t++) for (let k = 0; k < 3; k++) {
146
+ const p = remap[tris[t * 3 + k]], q = remap[tris[t * 3 + ((k + 1) % 3)]];
147
+ const key = p < q ? p * nVert + q : q * nVert + p;
148
+ const list = edges.get(key);
149
+ if (list) list.push(t); else edges.set(key, [t]);
150
+ }
151
+
152
+ // coplanar groups (union-find over shared edges)
153
+ const parent = new Int32Array(nTri);
154
+ for (let t = 0; t < nTri; t++) parent[t] = t;
155
+ const find = (t) => { while (parent[t] !== t) { parent[t] = parent[parent[t]]; t = parent[t]; } return t; };
156
+ for (const list of edges.values()) {
157
+ if (list.length !== 2) continue;
158
+ const [t, u] = list;
159
+ if (live(t) && live(u) && dot(t, u) > PLANE_COS) parent[find(t)] = find(u);
160
+ }
161
+
162
+ // a group is a flat face only if every edge leaving it would shade hard
163
+ const soft = new Uint8Array(nTri); // indexed by group root
164
+ const hard = (t, u) => {
165
+ const pt = policyFor(triOID[t]) ?? SMOOTH, pu = policyFor(triOID[u]) ?? SMOOTH;
166
+ if (triOID[t] !== triOID[u] && !(pt.boundaryLines || pu.boundaryLines)) return true;
167
+ return dot(t, u) < cosDeg(pt.creaseAngle);
168
+ };
169
+ for (const list of edges.values()) {
170
+ if (list.length !== 2) continue; // non-manifold: no smooth neighbour to share with
171
+ const [t, u] = list;
172
+ if (!live(t) || !live(u) || find(t) === find(u)) continue;
173
+ if (!hard(t, u)) soft[find(t)] = 1;
174
+ if (!hard(u, t)) soft[find(u)] = 1;
175
+ }
176
+
177
+ // one area-weighted plane per surviving group, merged where two groups share a
178
+ // plane (a degenerate triangle can split one face into two)
179
+ const acc = new Map();
180
+ for (let t = 0; t < nTri; t++) {
181
+ if (!live(t)) continue;
182
+ const root = find(t);
183
+ if (soft[root]) continue;
184
+ let e = acc.get(root);
185
+ if (!e) acc.set(root, (e = { n: [0, 0, 0], c: [0, 0, 0], a: 0 }));
186
+ for (let k = 0; k < 3; k++) { e.n[k] += fn[t * 3 + k] * area[t]; e.c[k] += cen[t * 3 + k] * area[t]; }
187
+ e.a += area[t];
188
+ }
189
+ const dTol = Math.max(1e-6, span * 1e-7);
190
+ const planes = [];
191
+ for (const e of acc.values()) {
192
+ const L = Math.hypot(...e.n);
193
+ if (!(L > 0)) continue;
194
+ const n = e.n.map((x) => x / L);
195
+ const d = (n[0] * e.c[0] + n[1] * e.c[1] + n[2] * e.c[2]) / e.a;
196
+ const dup = planes.find((p) => p.n[0] * n[0] + p.n[1] * n[1] + p.n[2] * n[2] > PLANE_COS && Math.abs(p.d - d) < dTol);
197
+ if (!dup) planes.push({ n, d });
198
+ }
199
+ return planes;
200
+ }
201
+
86
202
  // ---------------------------------------------------------------------------
87
203
  // Prism detection for the fast path (manifold-backend.js). The Minkowski chain
88
204
  // above is seconds-per-thousand-triangles, but roundAll's expensive real-world
@@ -37,6 +37,9 @@
37
37
  // pointing at itself. Nodes are laid out in pre-order, so an internal
38
38
  // node's left child is always the next node.
39
39
 
40
+ import { core, poisonCore } from "../core/core.js";
41
+ import { buildCoreBVH } from "../core/bvh-core.js";
42
+
40
43
  const LEAF = 4; // max triangles per leaf
41
44
 
42
45
  // Coords per triangle in a `vertices` store: v0,v1,v2 interleaved. The ONE place
@@ -285,13 +288,47 @@ function rayTri(ox, oy, oz, dx, dy, dz, V, base, tMin) {
285
288
  // meshes would keep an index alive for as long as anything held its mesh, which
286
289
  // is the quiet retention this pass exists to remove. Here the index's lifetime is
287
290
  // visibly the caller's scope.
291
+ //
292
+ // The native core (core/core.js) is used only where partforge OWNS the index's
293
+ // lifetime: with no Map (the caller — meshGaps — frees it), or with a Map made
294
+ // by coreBVHCache() (measure()'s, freed by measure()). Those get the core's
295
+ // index (core/bvh-core.js): same queries, same bits, living in WebAssembly
296
+ // memory until disposeBVHs(). A caller's own plain Map — meshGaps' public
297
+ // `bvhCache` option — and buildBVH() itself keep getting the JS index, exactly
298
+ // as before: code outside partforge is never handed something it must free.
288
299
  export function cachedBVH(mesh, cache) {
289
- if (!cache) return buildBVH(mesh);
300
+ if (!cache) return indexFor(mesh, true);
290
301
  let bvh = cache.get(mesh);
291
- if (!bvh) cache.set(mesh, (bvh = buildBVH(mesh)));
302
+ if (!bvh) cache.set(mesh, (bvh = indexFor(mesh, cache[CORE_CACHE] === true)));
292
303
  return bvh;
293
304
  }
294
305
 
306
+ const CORE_CACHE = Symbol("coreBVHCache");
307
+ // A Map for cachedBVH that may hold core indexes — its owner must disposeBVHs().
308
+ export function coreBVHCache() {
309
+ const m = new Map();
310
+ m[CORE_CACHE] = true;
311
+ return m;
312
+ }
313
+
314
+ function indexFor(mesh, allowCore) {
315
+ const c = allowCore ? core() : null;
316
+ if (c) {
317
+ try {
318
+ return buildCoreBVH(c, triangleVertices(mesh), () => buildBVH(mesh));
319
+ } catch {
320
+ poisonCore(c); // a fault while building: this realm's core is done; JS from here
321
+ }
322
+ }
323
+ return buildBVH(mesh);
324
+ }
325
+
326
+ // Free every core index among `bvhs` (a Map's values, or any iterable); JS
327
+ // indexes need nothing. Safe to call twice.
328
+ export function disposeBVHs(bvhs) {
329
+ for (const b of bvhs) b?.dispose?.();
330
+ }
331
+
295
332
  export function buildBVH(mesh) {
296
333
  const verts = triangleVertices(mesh);
297
334
  const count = verts.length / 9;
@@ -407,6 +444,8 @@ export function buildBVH(mesh) {
407
444
  // distance at leaf pairs; early-exits at 0 (touching/intersecting). The stack
408
445
  // holds node-index PAIRS, pushed and popped two entries at a time.
409
446
  function distanceTo(other) {
447
+ // A core index on the other side (bvh-core.js) meets this one through its JS twin.
448
+ if (other?.jsIndex) other = other.jsIndex();
410
449
  const oV = other.vertices, oB = other._bounds, oM = other._meta, oO = other._order;
411
450
  let best = { d2: Infinity, a: null, b: null };
412
451
  const stack = [0, 0];
@@ -1,5 +1,5 @@
1
1
  import { buildView } from "./build.js";
2
- import { cachedBVH } from "./bvh.js";
2
+ import { cachedBVH, disposeBVHs } from "./bvh.js";
3
3
 
4
4
  // A measured pair distance at or below this (mm) counts as touching — absorbs
5
5
  // posing float error while staying far below any real print clearance.
@@ -36,15 +36,20 @@ export function meshGaps(built, { bvhCache, prior, onPair } = {}) {
36
36
  return bvhOf.get(it.name);
37
37
  };
38
38
  const out = [];
39
- for (let i = 0; i < items.length; i++) {
40
- for (let j = i + 1; j < items.length; j++) {
41
- const a = items[i].name, b = items[j].name;
42
- const reused = prior?.(a, b);
43
- const { distance, at } = reused ?? bvh(items[i]).distanceTo(bvh(items[j]));
44
- const g = { a, b, distance, at };
45
- onPair?.(a, b, { distance, at });
46
- out.push(g);
39
+ try {
40
+ for (let i = 0; i < items.length; i++) {
41
+ for (let j = i + 1; j < items.length; j++) {
42
+ const a = items[i].name, b = items[j].name;
43
+ const reused = prior?.(a, b);
44
+ const { distance, at } = reused ?? bvh(items[i]).distanceTo(bvh(items[j]));
45
+ const g = { a, b, distance, at };
46
+ onPair?.(a, b, { distance, at });
47
+ out.push(g);
48
+ }
47
49
  }
50
+ } finally {
51
+ // With no caller Map these indexes are ours; with one, its owner frees them.
52
+ if (!bvhCache) disposeBVHs(bvhOf.values());
48
53
  }
49
54
  return out;
50
55
  }
@@ -1,5 +1,5 @@
1
1
  import { buildView } from "./build.js";
2
- import { cachedBVH } from "./bvh.js";
2
+ import { cachedBVH, coreBVHCache, disposeBVHs } from "./bvh.js";
3
3
  import { assemblyOverlaps } from "../assembly.js";
4
4
  import { resolveParams, buildPosed } from "../part-model.js";
5
5
  import { newReadSink, expandReads } from "../read-recorder.js";
@@ -257,7 +257,7 @@ export function measure(kernel, part, view = Object.keys(part.views)[0], params
257
257
  // memory is unchanged (meshGaps already held every sub-part's index at once);
258
258
  // the cache just fills it earlier. min-wall indexes exactly one mesh, so it is
259
259
  // handed the resolved BVH rather than the Map.
260
- const bvhCache = new Map();
260
+ const bvhCache = coreBVHCache();
261
261
  // Sample budget for the min-wall pass. A part that declares a min-wall gate (a
262
262
  // process profile or an `expect` mentioning it) gets the full resolution, because
263
263
  // a gate's verdict rides on the reading. Everything else gets the diagnostic
@@ -440,6 +440,11 @@ export function measure(kernel, part, view = Object.keys(part.views)[0], params
440
440
  })
441
441
  : [])
442
442
  : undefined;
443
+ // Both BVH passes (min-wall above, gaps here) are done: free the indexes this
444
+ // call owns. A native-core index lives in WebAssembly memory until freed; a JS
445
+ // one needs nothing. (A throw before this point leaves them to the core's
446
+ // FinalizationRegistry backstop.)
447
+ disposeBVHs(bvhCache.values());
443
448
 
444
449
  // Rebuilds with the same kernel and cleans up at its end — every solid fact
445
450
  // above is already read, so this is safe.
@@ -24,6 +24,7 @@
24
24
  // 400k triangles and found no wall" is a very different statement from "nobody
25
25
  // measured", and the two used to be indistinguishable downstream.
26
26
  import { buildBVH, readTriangleInto } from "./bvh.js";
27
+ import { hypot3 } from "../geometry/js-math.js";
27
28
 
28
29
  // Triangle budget above which minWall samples. Chosen so the parts people actually
29
30
  // author stay exact: everything in src/parts/ is 200–10,000 triangles, and a
@@ -78,6 +79,14 @@ export const BAND_CEIL = 1.5;
78
79
  // one is built. It does not interact with sampling — sampling picks WHICH rays to
79
80
  // cast, not how the index is built, so a shared BVH is equally valid sampled or exact.
80
81
  export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = buildBVH(mesh), band = null } = {}) {
82
+ // A core BVH (cachedBVH's, when the native core is on) runs the whole pass in
83
+ // C++ — one call instead of a JS loop crossing into WebAssembly per ray. If
84
+ // the core cannot answer (undefined) the JS below runs on the index's JS twin.
85
+ if (bvh.core) {
86
+ const r = bvh.minWall({ maxThickness, maxSamples, band });
87
+ if (r !== undefined) return r;
88
+ bvh = bvh.jsIndex();
89
+ }
81
90
  const n = bvh.triangleCount;
82
91
  if (n === 0) return null;
83
92
  const V = bvh.vertices;
@@ -89,7 +98,7 @@ export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = bu
89
98
  // are not in the tree; that only shrinks a ray cap, never a reading.)
90
99
  if (maxThickness == null) {
91
100
  const rb = bvh.rootBounds;
92
- maxThickness = Math.hypot(rb[3] - rb[0], rb[4] - rb[1], rb[5] - rb[2]) + 1;
101
+ maxThickness = hypot3(rb[3] - rb[0], rb[4] - rb[1], rb[5] - rb[2]) + 1;
93
102
  }
94
103
 
95
104
  // `maxSamples: 0` (or any non-positive) is the explicit "no cap, cast everything"
@@ -119,7 +128,7 @@ export function minWall(mesh, { maxThickness, maxSamples = MAX_SAMPLES, bvh = bu
119
128
  const e1x = tri[3] - v0x, e1y = tri[4] - v0y, e1z = tri[5] - v0z;
120
129
  const e2x = tri[6] - v0x, e2y = tri[7] - v0y, e2z = tri[8] - v0z;
121
130
  let nx = e1y * e2z - e1z * e2y, ny = e1z * e2x - e1x * e2z, nz = e1x * e2y - e1y * e2x;
122
- const len = Math.hypot(nx, ny, nz);
131
+ const len = hypot3(nx, ny, nz);
123
132
  if (len < 1e-9) continue; // degenerate triangle: no normal, no ray
124
133
  nx /= len; ny /= len; nz /= len; // outward normal (manifold winding)
125
134
  const c = [(v0x + tri[3] + tri[6]) / 3, (v0y + tri[4] + tri[7]) / 3, (v0z + tri[5] + tri[8]) / 3];
package/src/oracle.js CHANGED
@@ -25,6 +25,9 @@ export { verify } from "./framework/oracle/verify.js";
25
25
  export { createChangeTracker } from "./framework/oracle/changes.js";
26
26
  export { buildBVH, meshTriangles } from "./framework/oracle/bvh.js";
27
27
  export { minWall } from "./framework/oracle/min-wall.js";
28
+ // The native core's switch (framework/core/core.js): bit-identical either way, so
29
+ // this is a performance and kill switch, never a behaviour choice.
30
+ export { setCoreEnabled } from "./framework/core/core.js";
28
31
  export { overhang } from "./framework/oracle/overhang.js";
29
32
  // Mesh file parsers — the import pipeline's own readers, browser-safe pure
30
33
  // functions; the oracle package's corpus tests read real files through them.
package/types/oracle.d.ts CHANGED
@@ -16,6 +16,8 @@ export {
16
16
  type ChangeTracker, type ChangesReport, type SubPartChange, type ChangeRegion, type ChangeOpRef,
17
17
  // mesh facts, gaps, BVH, min wall
18
18
  meshVolume, bboxSize, bounds, meshArea, assemblyGaps, meshGaps, buildBVH, meshTriangles, minWall, overhang,
19
+ // the native core's switch
20
+ setCoreEnabled,
19
21
  type Gap, type BVH,
20
22
  // mesh file parsers (the import pipeline's own readers)
21
23
  parseStl, parse3MF,
@@ -264,6 +264,16 @@ export function minWall(
264
264
  totalTriangles: number;
265
265
  } | null;
266
266
 
267
+ /**
268
+ * Turn partforge's native core (src/framework/core/ — creasedNormals and the
269
+ * oracle's BVH + min-wall compiled to WebAssembly) on or off for this realm. On
270
+ * by default wherever WebAssembly exists. Output is bit-identical either way, so
271
+ * this is a performance and kill switch, never a behaviour choice. A worker is
272
+ * its own realm: set it there (or `globalThis.PARTFORGE_CORE = false`, which is
273
+ * read on every use).
274
+ */
275
+ export function setCoreEnabled(on: boolean): void;
276
+
267
277
  /**
268
278
  * Unsupported downward-facing surface (oracle/overhang.js): the mm² of faces
269
279
  * steeper than `maxAngle` from vertical, excluding the footprint on the bed