@expofp/floorplan 3.37.0 → 3.38.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/dist/browser/{Button-CNs8VDGG.js → Button-ClbFcvfV.js} +5 -5
- package/dist/browser/{CookieConsent-CcBA-IqC.js → CookieConsent-BtYMAMD8.js} +7 -7
- package/dist/browser/{Debug-DzeeojOv.js → Debug-6rBej4wJ.js} +7 -7
- package/dist/browser/{DebugTools-Cg2kMVuz.js → DebugTools-CweHk4eX.js} +6 -6
- package/dist/browser/{Demo-DlX2eRc5.js → Demo-DkbMkg4o.js} +9 -9
- package/dist/browser/{Free-BPXxN14i.js → Free-Da8_iIA3.js} +9 -9
- package/dist/browser/{GalleryContainer-D3PtNDq1.js → GalleryContainer-cYgizXxX.js} +10 -10
- package/dist/browser/{GpsLoader-MuKCP4hM.js → GpsLoader-dY9414p_.js} +10 -10
- package/dist/browser/{KioskStore-DwJPzK8K.js → KioskStore-dTaEpV2u.js} +5 -5
- package/dist/browser/{MaplibreAdapter-DzycfkS9.js → MaplibreAdapter-Bin47a4P.js} +12 -12
- package/dist/browser/{ModalContainer-U0c94Gcg.js → ModalContainer-cqTsVJWK.js} +10 -10
- package/dist/browser/{PermissionNotice-DyTh0N80.js → PermissionNotice-Czo_ZPGg.js} +6 -6
- package/dist/browser/{SetKioskMode-DFNqggA2.js → SetKioskMode-BHyRe8uR.js} +9 -9
- package/dist/browser/{ShowKiosk-BuXxL7Re.js → ShowKiosk-Btvjwee0.js} +10 -10
- package/dist/browser/{ViewerMenuPanel--flTFhEB.js → ViewerMenuPanel-ChhGSeZi.js} +9 -9
- package/dist/browser/{add-debug-secret-listener-DvCB0ort.js → add-debug-secret-listener-Uy98ISZg.js} +1 -1
- package/dist/browser/{adopt-global-settings-CVQmrlox.js → adopt-global-settings-CSk5bLXy.js} +9 -9
- package/dist/browser/{boolean-editor-Bk6Lfd_2.js → boolean-editor-BX0E97NA.js} +9 -9
- package/dist/browser/{bootIntercom-iv5wse99.js → bootIntercom-CgTbDJ3h.js} +2 -2
- package/dist/browser/bundle.json +71 -71
- package/dist/browser/{camera-events-Uyswpptc.js → camera-events-Djsde0Ux.js} +1 -1
- package/dist/browser/{classnames-TUIUYS3L.js → classnames-B52rwbt4.js} +2 -2
- package/dist/browser/{client-Bm485HWD.js → client-CTsWysuI.js} +5 -5
- package/dist/browser/{components-DcbtuzgN.js → components-CYoiaY2t.js} +37 -37
- package/dist/browser/{debug-context-CiRcA5z7.js → debug-context-BnO2NQR9.js} +5 -5
- package/dist/browser/{debug-overlay-BaIOFaoE.js → debug-overlay-bJmbHnXN.js} +10 -10
- package/dist/browser/{debug-ui-B3yO6QTa.js → debug-ui-DvXUU9-P.js} +6 -6
- package/dist/browser/{dimming-y3MYb4O3.js → dimming-BrGbMBxb.js} +22 -15
- package/dist/browser/{dist-fMLrkr8V.js → dist-CnbCTNO3.js} +3 -3
- package/dist/browser/{dist-DAWn7KI8.js → dist-DZ2Exk9m.js} +6 -6
- package/dist/browser/{dist-BaXVVYa9.js → dist-ShElP6T0.js} +5 -5
- package/dist/browser/{efp-debug-init-CVDjWVXl.js → efp-debug-init-BR__9zmi.js} +3 -3
- package/dist/browser/{enum-editor-B-vJDdwf.js → enum-editor-D1frUcEv.js} +4 -4
- package/dist/browser/{es5-CYKbplUA.js → es5-COBqz2Zh.js} +2 -2
- package/dist/browser/{event-head-BtayW8HA.js → event-head-BUJJHBIq.js} +1 -1
- package/dist/browser/{event-not-found-B4Tz7V1H.js → event-not-found-K1N4NbnT.js} +3 -3
- package/dist/browser/{exports-DTjBGI92.js → exports-DN6wF8DS.js} +1 -1
- package/dist/browser/{favicon-Bq3vaHM_.js → favicon-D6QoTQSP.js} +1 -1
- package/dist/browser/{fetch-retry.umd-Cw9OsA-s.js → fetch-retry.umd-HVXbN6qF.js} +2 -2
- package/dist/browser/{flex-C0jlxRr9.js → flex-BP_sJeus.js} +5 -5
- package/dist/browser/{floorplan.loader-B0b2d8rT.js → floorplan.loader-Dzvb4FTD.js} +10 -10
- package/dist/browser/{floorplan.ready-Bi2mkI_V.js → floorplan.ready-DLq2zteX.js} +15 -15
- package/dist/browser/{fuse-CS-5RDcg.js → fuse-B-w8rUFE.js} +2 -2
- package/dist/browser/{i18n-LVijVdMb.js → i18n-C6fFyMGD.js} +7 -6
- package/dist/browser/index.js +16 -16
- package/dist/browser/{index.module-D7TtIVgi.js → index.module-m51AK8p4.js} +4 -4
- package/dist/browser/{integrateKiosk-BmVtSyFv.js → integrateKiosk-6cmnHeoj.js} +4 -4
- package/dist/browser/{is-own-domain-BL66TBhN.js → is-own-domain-wvyQvGlL.js} +1 -1
- package/dist/browser/{is-webview-DwQBZFcX.js → is-webview-oqXVE6bv.js} +1 -1
- package/dist/browser/{jsx-runtime-DS8yJ69h.js → jsx-runtime-CtJ_t8Mi.js} +2 -2
- package/dist/browser/{kiosk-record-goZjGV8Y.js → kiosk-record-Di9isPMQ.js} +1 -1
- package/dist/browser/{lib-dIwLYV0z.js → lib-DmKWthvt.js} +3 -3
- package/dist/browser/{loadImage-BDk9loud.js → loadImage-DUelfWA7.js} +4 -4
- package/dist/browser/{logDeviceInfo-227-j__X.js → logDeviceInfo-BuhtLa4A.js} +9 -9
- package/dist/browser/{mobx-D3NRVJz0.js → mobx-UGMGcjzY.js} +4 -4
- package/dist/browser/{optional-boolean-editor-BtWARd1i.js → optional-boolean-editor-C1Ndbp_u.js} +3 -3
- package/dist/browser/{optional-enum-editor-CJEQ7pDc.js → optional-enum-editor-DYAfwsr2.js} +4 -4
- package/dist/browser/{optional-string-editor-Bd6a7i5L.js → optional-string-editor-ClMoGgGt.js} +4 -4
- package/dist/browser/{particles.min-CGC94f9R.js → particles.min-BffTQ57s.js} +2 -2
- package/dist/browser/{react-DUWO7pPs.js → react-C-Qd2U47.js} +2 -2
- package/dist/browser/{react-dom-C08Q2osf.js → react-dom-CnXY0ene.js} +3 -3
- package/dist/browser/{rolldown-runtime-CooLcCzw.js → rolldown-runtime-CjjOYn6R.js} +1 -1
- package/dist/browser/{scheduler-DuPfkMc5.js → scheduler-Qu0FRRuK.js} +2 -2
- package/dist/browser/{select-4KfoG4mp.js → select-DBf5drek.js} +10 -10
- package/dist/browser/{settings-Dbl2f0ow.js → settings-CK9N4RDZ.js} +2 -2
- package/dist/browser/{settings-item-CRyyzC8b.js → settings-item-C1kuqAX7.js} +6 -6
- package/dist/browser/{store-BcEvlgIF.js → store-DcCWvP6P.js} +4084 -3727
- package/dist/browser/{string-editor-lytU5wX-.js → string-editor-CZm4w5-_.js} +4 -4
- package/dist/browser/{text-field-BGvPdsaN.js → text-field-BjwNyut3.js} +5 -5
- package/dist/browser/{theme-CxFvVGHQ.js → theme-Cq3CRc3v.js} +8 -8
- package/dist/browser/{ui-D3H7hMUC.js → ui-COIkgfZE.js} +8 -8
- package/dist/browser/{useRenderTarget-DGSXEfzc.js → useRenderTarget-Dr7hirkU.js} +4 -4
- package/dist/browser/{viewport-BczDYrg4.js → viewport-3wsqmW9Q.js} +2 -2
- package/dist/esm/components/Map/drawing/config/booth-logos.d.ts +38 -0
- package/dist/esm/components/Map/drawing/config/booth-logos.js +1 -0
- package/dist/esm/components/Map/drawing/config/config-booth-labels-special.js +2 -2
- package/dist/esm/components/Map/drawing/config/config-booth-labels.js +1 -1
- package/dist/esm/components/Map/drawing/config/config-booths.js +1 -1
- package/dist/esm/components/Map/drawing/config/config-load-layer.js +1 -1
- package/dist/esm/components/Map/drawing/config/config-markers.js +1 -1
- package/dist/esm/components/Map/drawing/config/layer-models.d.ts +2 -2
- package/dist/esm/components/Map/drawing/config/loadBoothsImages.d.ts +19 -2
- package/dist/esm/components/Map/drawing/config/loadBoothsImages.js +1 -1
- package/dist/esm/components/Map/traffic/useManageTraffic.js +1 -1
- package/dist/esm/store/ExhibitorStore.d.ts +2 -0
- package/dist/esm/utils/blob-image-size.d.ts +27 -0
- package/dist/esm/utils/blob-image-size.js +1 -0
- package/dist/esm/utils/loadBlob.d.ts +16 -0
- package/dist/esm/utils/loadBlob.js +1 -0
- package/dist/esm/utils/loadImagesInBatches.d.ts +16 -1
- package/dist/esm/utils/loadImagesInBatches.js +1 -1
- package/dist/esm/utils/loadLayerImages.d.ts +46 -0
- package/dist/esm/utils/loadLayerImages.js +1 -0
- package/dist/esm/utils/rasterize-svg.d.ts +32 -0
- package/dist/esm/utils/rasterize-svg.js +1 -0
- package/package.json +10 -10
- package/dist/esm/utils/imageloader.d.ts +0 -15
- package/dist/esm/utils/imageloader.js +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "8f241b7f-d106-4e96-a6a2-b96a0f9abf69", e._sentryDebugIdIdentifier = "sentry-dbid-8f241b7f-d106-4e96-a6a2-b96a0f9abf69");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { t as e } from "./jsx-runtime-
|
|
10
|
-
import { t } from "./settings-item-
|
|
11
|
-
import { t as n } from "./text-field-
|
|
9
|
+
import { t as e } from "./jsx-runtime-CtJ_t8Mi.js";
|
|
10
|
+
import { t } from "./settings-item-C1kuqAX7.js";
|
|
11
|
+
import { t as n } from "./text-field-BjwNyut3.js";
|
|
12
12
|
//#region ../debug/src/lib/ui/string-editor.tsx
|
|
13
13
|
var r = e(), i = (e) => {
|
|
14
14
|
var i;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "e13f8c4e-8995-47cd-802d-392fd9bdf13a", e._sentryDebugIdIdentifier = "sentry-dbid-e13f8c4e-8995-47cd-802d-392fd9bdf13a");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { r as e } from "./rolldown-runtime-
|
|
10
|
-
import { t } from "./react-
|
|
11
|
-
import { D as n, i as r, l as i, n as a, s as o, u as s, y as c } from "./flex-
|
|
12
|
-
import { t as l } from "./classnames-
|
|
9
|
+
import { r as e } from "./rolldown-runtime-CjjOYn6R.js";
|
|
10
|
+
import { t } from "./react-C-Qd2U47.js";
|
|
11
|
+
import { D as n, i as r, l as i, n as a, s as o, u as s, y as c } from "./flex-BP_sJeus.js";
|
|
12
|
+
import { t as l } from "./classnames-B52rwbt4.js";
|
|
13
13
|
//#region ../../node_modules/.pnpm/@radix-ui+themes@3.3.0_@types+react-dom@19.2.3_@types+react@19.2.17__@types+react@19.2._5ea800d4e947acedb1fa1275f1697b17/node_modules/@radix-ui/themes/dist/esm/components/text-field.props.js
|
|
14
14
|
var u = /* @__PURE__ */ e(t()), d = /* @__PURE__ */ e(l()), f = {
|
|
15
15
|
size: {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "5b26ff7f-61de-4d09-8508-a74b71b94f98", e._sentryDebugIdIdentifier = "sentry-dbid-5b26ff7f-61de-4d09-8508-a74b71b94f98");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { r as e } from "./rolldown-runtime-
|
|
10
|
-
import { t } from "./react-
|
|
11
|
-
import { t as n } from "./jsx-runtime-
|
|
12
|
-
import { t as r } from "./react-dom-
|
|
13
|
-
import { C as i, E as a, O as o, T as s, _ as c, o as l, v as u, w as d } from "./flex-
|
|
14
|
-
import { c as f, i as p, n as m, o as h, r as g, s as _, t as v } from "./dist-
|
|
15
|
-
import { t as y } from "./classnames-
|
|
9
|
+
import { r as e } from "./rolldown-runtime-CjjOYn6R.js";
|
|
10
|
+
import { t } from "./react-C-Qd2U47.js";
|
|
11
|
+
import { t as n } from "./jsx-runtime-CtJ_t8Mi.js";
|
|
12
|
+
import { t as r } from "./react-dom-CnXY0ene.js";
|
|
13
|
+
import { C as i, E as a, O as o, T as s, _ as c, o as l, v as u, w as d } from "./flex-BP_sJeus.js";
|
|
14
|
+
import { c as f, i as p, n as m, o as h, r as g, s as _, t as v } from "./dist-DZ2Exk9m.js";
|
|
15
|
+
import { t as y } from "./classnames-B52rwbt4.js";
|
|
16
16
|
//#region ../../node_modules/.pnpm/@radix-ui+react-visually-hidden@1.2.3_@types+react-dom@19.2.3_@types+react@19.2.17__@ty_cffccd7838985066e8e1d993b5cb6017/node_modules/@radix-ui/react-visually-hidden/dist/index.mjs
|
|
17
17
|
var b = /* @__PURE__ */ e(r(), 1), x = /* @__PURE__ */ e(t(), 1), S = n(), C = Object.freeze({
|
|
18
18
|
position: "absolute",
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "80a4f49f-d869-4a38-b1c0-c3cfd645ceec", e._sentryDebugIdIdentifier = "sentry-dbid-80a4f49f-d869-4a38-b1c0-c3cfd645ceec");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { r as e } from "./rolldown-runtime-
|
|
10
|
-
import { a as t, i as n, s as r } from "./efp-debug-init-
|
|
11
|
-
import { a as i, i as a } from "./adopt-global-settings-
|
|
12
|
-
import { t as o } from "./jsx-runtime-
|
|
13
|
-
import "./settings-
|
|
14
|
-
import { t as s } from "./add-debug-secret-listener-
|
|
9
|
+
import { r as e } from "./rolldown-runtime-CjjOYn6R.js";
|
|
10
|
+
import { a as t, i as n, s as r } from "./efp-debug-init-BR__9zmi.js";
|
|
11
|
+
import { a as i, i as a } from "./adopt-global-settings-CSk5bLXy.js";
|
|
12
|
+
import { t as o } from "./jsx-runtime-CtJ_t8Mi.js";
|
|
13
|
+
import "./settings-CK9N4RDZ.js";
|
|
14
|
+
import { t as s } from "./add-debug-secret-listener-Uy98ISZg.js";
|
|
15
15
|
//#region ../debug/src/lib/ui/render-debug-ui.tsx
|
|
16
16
|
var c = /* @__PURE__ */ e(r(), 1), l = o(), u = !1;
|
|
17
17
|
function d() {
|
|
@@ -26,7 +26,7 @@ function d() {
|
|
|
26
26
|
}
|
|
27
27
|
});
|
|
28
28
|
let o = async (t) => {
|
|
29
|
-
let { DebugUi: n } = await import("./debug-ui-
|
|
29
|
+
let { DebugUi: n } = await import("./debug-ui-DvXUU9-P.js"), { createRoot: i } = await import("./client-CTsWysuI.js").then((t) => /* @__PURE__ */ e(t.t(), 1)), a = document.createElement("div");
|
|
30
30
|
document.body.appendChild(a), i(a).render(/* @__PURE__ */ (0, l.jsx)(n, {
|
|
31
31
|
useDebugButtonState: r.useState,
|
|
32
32
|
open: t
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "44feeb02-c84e-4fb1-b2f8-984c7d50f58d", e._sentryDebugIdIdentifier = "sentry-dbid-44feeb02-c84e-4fb1-b2f8-984c7d50f58d");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { r as e } from "./rolldown-runtime-
|
|
10
|
-
import { t } from "./react-
|
|
11
|
-
import { l as n } from "./store-
|
|
9
|
+
import { r as e } from "./rolldown-runtime-CjjOYn6R.js";
|
|
10
|
+
import { t } from "./react-C-Qd2U47.js";
|
|
11
|
+
import { l as n } from "./store-DcCWvP6P.js";
|
|
12
12
|
//#region ../ui/src/shared/activeElement.ts
|
|
13
13
|
var r = (e) => !!e && "activeElement" in e;
|
|
14
14
|
function i(e) {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
try {
|
|
3
3
|
var e = typeof window < "u" ? window : typeof global < "u" ? global : typeof globalThis < "u" ? globalThis : typeof self < "u" ? self : {};
|
|
4
|
-
e.SENTRY_RELEASE = { id: "3.
|
|
4
|
+
e.SENTRY_RELEASE = { id: "3.38.0" };
|
|
5
5
|
var t = new e.Error().stack;
|
|
6
6
|
t && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[t] = "233b3b22-a917-48c8-8f7e-f558b0dbd9d8", e._sentryDebugIdIdentifier = "sentry-dbid-233b3b22-a917-48c8-8f7e-f558b0dbd9d8");
|
|
7
7
|
} catch {}
|
|
8
8
|
})();
|
|
9
|
-
import { c as e, vt as t } from "./store-
|
|
9
|
+
import { c as e, vt as t } from "./store-DcCWvP6P.js";
|
|
10
10
|
//#region src/components/Map/viewport.ts
|
|
11
11
|
function n(e) {
|
|
12
12
|
return {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Booth } from '../../../../store/BoothStore';
|
|
2
|
+
import { type Exhibitor } from '../../../../store/ExhibitorStore';
|
|
3
|
+
/** One booth logo, ready to draw. */
|
|
4
|
+
export interface BoothLogo {
|
|
5
|
+
/** The bytes the renderer packs. An SVG logo is rasterized and re-encoded as PNG. */
|
|
6
|
+
blob: Blob;
|
|
7
|
+
/** The logo's width divided by its height, which is what fits it inside the booth. */
|
|
8
|
+
aspectRatio: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The exhibitor whose logo is painted in this booth, if any.
|
|
12
|
+
*
|
|
13
|
+
* One function, so the logo URL and the stated ratio always come off the same exhibitor. A booth
|
|
14
|
+
* can hold several.
|
|
15
|
+
* @param booth - The booth to look at.
|
|
16
|
+
* @returns The exhibitor, or undefined when no exhibitor in the booth wants its logo painted.
|
|
17
|
+
*/
|
|
18
|
+
export declare function boothLogoExhibitor(booth: Booth): Exhibitor | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* The logo aspect ratio the event data states for this booth, when it states a usable one.
|
|
21
|
+
*
|
|
22
|
+
* A value that is not a finite positive number is not a ratio. It would mis-fit the logo in every
|
|
23
|
+
* booth the exhibitor holds, and nothing downstream would catch it, so it is rejected here and the
|
|
24
|
+
* caller measures the pixels instead.
|
|
25
|
+
* @param booth - The booth whose logo is being placed.
|
|
26
|
+
* @returns The ratio, or undefined when the data states none that can be used.
|
|
27
|
+
*/
|
|
28
|
+
export declare function statedLogoAspectRatio(booth: Booth): number | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Makes the logo preparer for one batch of booths.
|
|
31
|
+
*
|
|
32
|
+
* The preparer answers two questions per booth: which bytes the renderer packs, and at what ratio
|
|
33
|
+
* the logo is fitted. It holds the batch's two caches, which is why it is built per batch rather
|
|
34
|
+
* than imported: booths share logos, and both answers must be shared with them.
|
|
35
|
+
* @returns A function preparing one booth's logo. It returns null when the logo cannot be drawn.
|
|
36
|
+
*/
|
|
37
|
+
export declare function createLogoPreparer(): (booth: Booth, blob: Blob) => Promise<BoothLogo | null>;
|
|
38
|
+
//# sourceMappingURL=booth-logos.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{blobImageSize as u}from"../../../../utils/blob-image-size";import{isSvgBlob as c,svgToPngBlob as g}from"../../../../utils/rasterize-svg";export function boothLogoExhibitor(e){return e.exhibitors.find(t=>t.logoInBooth&&t.logo)}export function statedLogoAspectRatio(e){const t=boothLogoExhibitor(e)?.logoAspectRatio;return typeof t=="number"&&Number.isFinite(t)&&t>0?t:void 0}export function createLogoPreparer(){const e=new Map,t=o=>{let n=e.get(o);return n||(n=f(o),e.set(o,n)),n},i=new Map,s=o=>{let n=i.get(o);return n||(n=l(o),i.set(o,n)),n};return async(o,n)=>{const r=await t(n);if(!r)return null;const a=statedLogoAspectRatio(o)??await s(r);return a===null?null:{blob:r,aspectRatio:a}}}async function f(e){return c(e)?g(e):e}async function l(e){const t=await u(e);return t?.height?t.width/t.height:null}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{Rect as m}from"@expofp/geometry";import{update as L}from"@expofp/renderer";import{reaction as b}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as g,FONT_WEIGHT_PRIMARY_SPECIAL as
|
|
2
|
-
`),this.shapeLabel.padding=[this.paddingScaled[0]*t+this.padding,this.paddingScaled[1]*t+this.padding],[this.shapeLabel]):(this.shapeLabel.lines[0].fontSize=0,[this.shapeLabel])}layOutDot(t){const s=this.steps.find(
|
|
1
|
+
import{Rect as m}from"@expofp/geometry";import{update as L}from"@expofp/renderer";import{reaction as b}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as g,FONT_WEIGHT_PRIMARY_SPECIAL as y}from"../../../../constants";import{createTextDef as D}from"../../../../engine/defs";import{loadCustomFontsUrls as F}from"../../../../engine/fonts";import{getQuarterTurns as x,getRollValue as R,rotateRectByQuarters as S,rotateTextDefByQuarters as T,shouldFlip as v}from"../../../../engine/update-def";import{heatmapStore as B,layersStore as I,uiState as l}from"../../../../store";import{SpecialBooth as w}from"../../../../store/BoothStore";import z from"../../../../tools/settings";import{getFont as M}from"./canvases";import{BoothLabelDrawer as O,getFontUrlByWeight as k,getMinZoomFactorForDot as C,isDirectionsMode as P}from"./config-booth-labels";import{LABEL_MARGIN_FRACTION as f}from"./label-inset.js";import _ from"./TextFitter";const c=new Map;function A(i){let t=c.get(i);if(!t){const s=[18,16,14,12,10,7].map(o=>o*i),e=14*i;t=new _(M,s,e),c.set(i,t),setTimeout(()=>c.delete(i),5e3)}return t}export default function N(i){if(!(!(i instanceof w)||i.noLabels))return new V(i)}class V extends O{constructor(t){super(t),this.steps=[],this.text="";const s=this.booth.rect,e=Number(getComputedStyle(document.body).getPropertyValue(y))||Number(getComputedStyle(document.body).getPropertyValue(g))||500,o=k(e,F()),h=s.expand({x:-(s.size.width*f+this.padding),y:-(s.size.height*f+this.padding)});this.setText(),this.canvasRect=new m(h.center,h.size,t.rotate,t.elevation),this.setFactors(this.text),this.labelIsVertical=Math.abs(Math.abs(t.rotate)-Math.PI/2)<.01,this.fontSizes=[this.steps,[]],this.minZoomDotVisible=C(this.steps.map(a=>a.scaleFactor)),this.shapeLabel=D([{text:this.text,color:t.labelColor||z.boothLabelColor,fontUrl:o,fontSize:0}],new m(h.center,h.size,t.rotate,t.elevation),[this.padding,this.padding],{horizontal:"center",text:"center",vertical:"center"}),this.shapeLabel.onScale=({pixelSize:a})=>this.layOutLabel(a),this.getShapeDot(),b(()=>[this.booth.skipDim,l.selectedRoute,I.layersLoaded],()=>{const a=P();this.shapeLabel.dim=a||this.booth.skipDim?0:void 0,this.shapeDot.dim=a||this.booth.skipDim?0:void 0,L(this.shapeLabel,this.shapeDot)}),b(()=>l.mapSettings,({roll:a})=>{R(a??0)&&(this.shapeLabel.onRoll=({roll:p,pixelSize:d})=>{const r=this.shapeLabel.bounds.rotation;if(this.labelIsVertical)return v(p,r)?(this.shapeLabel.bounds.rotate(-2*r,this.shapeLabel.bounds),[this.shapeLabel,this.shapeDot]):void 0;const n=x(p,r);if(n===0)return;const{size:u}=this.canvasRect;return this.shapeLabel=T(this.shapeLabel,n),u.x!==u.y&&!this.shapeLabel.hidden&&(this.canvasRect=S(this.canvasRect,n),this.setFactors(this.text),this.layOutLabel(d),this.layOutDot(d)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0})}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const s=this.steps.find(e=>e.scaleFactor<1/t);return s?(this.shapeLabel.lines[0].fontSize=s.value*t,this.shapeLabel.lines[0].text=s.lines.join(`
|
|
2
|
+
`),this.shapeLabel.padding=[this.paddingScaled[0]*t+this.padding,this.paddingScaled[1]*t+this.padding],[this.shapeLabel]):(this.shapeLabel.lines[0].fontSize=0,[this.shapeLabel])}layOutDot(t){const s=this.steps.find(h=>h.scaleFactor<1/t),e=this.shapeDot.bounds,o=this.shapeDot.source;return e.scale({x:o.width*t/e.size.x,y:o.height*t/e.size.y},e.center,e),this.shapeDot.hidden=!!s,[this.shapeDot]}setFactors(t){this.steps=A(devicePixelRatio).getStepsForRect(t,this.canvasRect.size.x,this.canvasRect.size.y)}setText(){const t=this.booth.title||this.booth.name,e=`Clicks: ${B.getTotalClicksByBooth(this.booth)}`;this.text=l.heatmap?`${t} - ${e}`:t}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Rect as B}from"@expofp/geometry";import{update as U}from"@expofp/renderer";import{reaction as M}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as V,FONT_WEIGHT_PRIMARY_EXHIBITOR as Z,FONT_WEIGHT_SECONDARY_BOOTH as X,FONT_WEIGHT_SECONDARY_EXHIBITOR as G}from"../../../../constants";import c from"../../../../data";import{createShapeDot as k,createTextDef as Y,createTextDefLines as Q}from"../../../../engine/defs";import{DEFAULT_FONT_LIGHT_URL as $,DEFAULT_FONT_URL as W,loadCustomFontsUrls as q}from"../../../../engine/fonts";import{getQuarterTurns as j,getRollValue as J,rotateRectByQuarters as K,rotateTextDefByQuarters as tt,updateLinesScale as et}from"../../../../engine/update-def";import{boothStore as it,layersStore as _,uiState as m}from"../../../../store";import{RegularBooth as st,SpecialBooth as ot}from"../../../../store/BoothStore";import v from"../../../../tools/settings";import{t as S}from"../../../../utils/i18n";import nt from"../../../../utils/is-mobile";import at from"../../../../utils/is-webview";import{isArabicText as
|
|
1
|
+
import{Rect as B}from"@expofp/geometry";import{update as U}from"@expofp/renderer";import{reaction as M}from"mobx";import{FONT_WEIGHT_PRIMARY_BOOTH as V,FONT_WEIGHT_PRIMARY_EXHIBITOR as Z,FONT_WEIGHT_SECONDARY_BOOTH as X,FONT_WEIGHT_SECONDARY_EXHIBITOR as G}from"../../../../constants";import c from"../../../../data";import{createShapeDot as k,createTextDef as Y,createTextDefLines as Q}from"../../../../engine/defs";import{DEFAULT_FONT_LIGHT_URL as $,DEFAULT_FONT_URL as W,loadCustomFontsUrls as q}from"../../../../engine/fonts";import{getQuarterTurns as j,getRollValue as J,rotateRectByQuarters as K,rotateTextDefByQuarters as tt,updateLinesScale as et}from"../../../../engine/update-def";import{boothStore as it,layersStore as _,uiState as m}from"../../../../store";import{RegularBooth as st,SpecialBooth as ot}from"../../../../store/BoothStore";import v from"../../../../tools/settings";import{t as S}from"../../../../utils/i18n";import nt from"../../../../utils/is-mobile";import at from"../../../../utils/is-webview";import{isArabicText as rt}from"../../../../utils/rtl";import{BoothDrawerBaseWithoutPainter as ht}from"./BoothDrawerBase";import{getFont as I}from"./canvases";import{getLabelBorderInset as lt}from"./label-inset.js";let z=v.boothLabelColor;v.EXPO==="tqs2021"&&(z="#000");const x=nt||at,F=n=>n.replace(" ","").substring(0,4).replace(/[0-9]/g,"3").replace(/[A-Z]/gi,"A"),P=document.createElement("canvas").getContext("2d");export default function ct(n){if(!(!(n instanceof st)||n.noLabels))return new BoothLabelDrawer(n)}export function getMinZoomFactorForDot(n){return Array.isArray(n)&&n.length>0?Math.max(...n.map(t=>t)):typeof n=="number"?n:-0}export const isDirectionsMode=()=>!!(m.selectedRoute?.from&&m.selectedRoute?.to);export function getFontUrlByWeight(n,t=[],e="normal"){return[...t,{weight:500,url:W,style:"normal"},{weight:300,url:$,style:"normal"}].find(s=>+s.weight===n&&s.style===e)?.url||W}function b(n,t){return Number(getComputedStyle(document.body).getPropertyValue(n))||t}export function getBoothLabelWeights(){return{main:b(V,500),details:b(X,300)}}export function getExhibitorLabelWeights(){return{main:b(Z,500),details:b(G,300)}}export function getBadgeFontWeight(){return getExhibitorLabelWeights().details}const y="Details";export class BoothLabelDrawer extends ht{constructor(t){super(t),this.minZoomDotVisible=0,this.maxZoomDotVisible=0,this.exh=[],this.shapeLabel=void 0,this.shapeDot=void 0,this.fontSizes=[[],[]],this.lines=[[],[]],this.fontUrls=["",""],this.canvasRect=new B(t.rect.center,t.rect.size,t.rotate,t.elevation),this.paddingScaled=[4,4],this.padding=lt(t.borderWidth||it.borderWidth,t.rect.size),this.topLeftAlignment={horizontal:m.rtl?"right":"left",vertical:"top"},this.centerAlignment={horizontal:"center",vertical:"center"},this.prefixes=x?[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:16,name:y,short:!1}]:[{fontSize:7,name:"XS",short:!0},{fontSize:10,name:"S",short:!0},{fontSize:12,name:"M",short:!0},{fontSize:14,name:"L",short:!0},{fontSize:18,name:y,short:!1}],!(t instanceof ot)&&(this.exh=c.hideExhibitors?[]:c.onlyFeaturedExhibitors?t.exhibitors.filter(e=>e.featured):t.exhibitors,x&&this.optimizationLevel()>=3&&(this.prefixes=this.prefixes.filter(e=>e.name!=="S")),this.createLines(),this.calculateFontSizeFactors(),this.shapeLabel=Y(Q(this.lines,this.booth.labelColor||z,0,this.fontUrls),new B(this.booth.rect.center,this.booth.rect.size,this.booth.rotate,this.booth.elevation),[...this.paddingScaled],{horizontal:"left",vertical:"top"}),this.shapeLabel.onScale=({pixelSize:e})=>this.layOutLabel(e),this.getShapeDot(),M(()=>[this.booth.skipDim,m.selectedRoute,_.layersLoaded],()=>{if(!_.layersLoaded)return;const e=isDirectionsMode();this.shapeLabel.dim=e||this.booth.skipDim?0:void 0,this.shapeDot.dim=e||this.booth.skipDim?0:void 0,U(this.shapeLabel,this.shapeDot)}),M(()=>m.mapSettings,({roll:e})=>{J(e??0)&&(this.shapeLabel.onRoll=({roll:i,pixelSize:a})=>{const s=j(i,this.shapeLabel.bounds.rotation);if(s===0)return;const{size:r}=this.canvasRect;return this.shapeLabel=tt(this.shapeLabel,s),!this.shapeLabel.hidden&&!this.exh.length&&r.x!==r.y&&(this.canvasRect=K(this.canvasRect,s),this.calculateFontSizeFactors(),this.layOutLabel(a),this.layOutDot(a)),[this.shapeLabel,this.shapeDot]})},{fireImmediately:!0}))}getShape(){return[this.shapeLabel,this.shapeDot]}layOutLabel(t){const e=this.lines[1]??[],i=this.fontSizes[1]??[];if(v.EXPO!=="wineparis2026"){const s=this.exh.length?this.topLeftAlignment:e.length?t<i[i.length-1].scaleFactor?this.topLeftAlignment:this.centerAlignment:this.topLeftAlignment;this.shapeLabel.alignment=s}return et(this.shapeLabel.lines,t,this.fontSizes)?(this.shapeLabel.padding[0]=this.paddingScaled[0]*t+this.padding,this.shapeLabel.padding[1]=this.paddingScaled[1]*t+this.padding,[this.shapeLabel]):[]}layOutDot(t){const e=t>=this.minZoomDotVisible&&t<=this.maxZoomDotVisible;if(!e&&this.shapeDot.hidden)return[];const i=this.shapeDot.bounds,a=this.shapeDot.source;return i.scale({x:a.width*t/i.size.x,y:a.height*t/i.size.y},i.center,i),this.shapeDot.hidden=!e,[this.shapeDot]}getShapeDot(){this.shapeDot=k(this.canvasRect,this.booth.labelColor||z),this.shapeDot.hidden=!0,this.shapeDot.onScale=({pixelSize:e})=>this.layOutDot(e);const t=this.shapeDot.source;this.maxZoomDotVisible=Math.min(this.canvasRect.size.x/t.width,this.canvasRect.size.y/t.height)}createLines(){const t=this.booth,e=[],i=[],a=x&&this.optimizationLevel()>=3?1:3;if(this.exh.length){const s=t.exhibitors.filter(o=>o.order===0),r=t.exhibitors.filter(o=>o.order);if(s.length>0)e.push(...s.map(o=>o.name));else if(c.onlyFeaturedExhibitors)e.push(...t.exhibitors.filter(o=>o.featured).map(o=>o.name));else if(r.length>0){e.push(...r.map(u=>u.name));const o=t.exhibitors.filter(u=>u.order===void 0);o.length>0&&e.push(S("and {{moreCount}} more",{moreCount:o.length}))}else t.exhibitors.length>a?e.push(`${t.exhibitors.length} ${c.exhibitorTermPlural}`):e.push(...t.exhibitors.map(o=>o.name));i.push(t.title||t.name)}else{const s=!!t.exhibitors.length;e.push(t.title||t.name),t.onHold?i.push(S("On Hold")):t.reserved?i.push(S("Reserved")):s||i.push(...t.exhibitors.map(r=>r.name).sort((r,o)=>r>o?1:-1)),t.size&&i.push(t.size.indexOf("/")>-1?t.size.substring(0,t.size.indexOf("/")).trim():t.size),t.price&&t.price!=="0"&&!m.previewMode&&i.push(t.price)}m.rtl&&e.forEach((s,r)=>{(s.endsWith(".")||s.endsWith("!")||s.endsWith("?"))&&(e[r]=e[r]+"\u200F"),rt(s)&&(e[r]=e[r]+" ")}),this.lines=[e,i]}calculateFontSizeFactors(){const t=this.lines[0];let e;const i=this.canvasRect,a=[],s=[],r=this.prefixes.slice(0,this.exh.length?this.prefixes.length:this.prefixes.length-1),{main:o,details:u}=this.exh.length?getExhibitorLabelWeights():getBoothLabelWeights();for(const{fontSize:l,short:p}of r){const d=l*devicePixelRatio,L=.9*l*devicePixelRatio,f=I(d,o),T=I(L,u),O=c.hideExhibitorBoothNumber||p;let w,A,D,g;if(this.exh.length)e=p?[]:this.lines[1],D=Math.max(...t.map(h=>this.measureText(h,f).width),...e.map(h=>this.measureText(h,T).width)),w=Math.max(...t.map(h=>this.exh.length?this.measureText(F(h),f).width:this.measureText(F(h),f).width+3+3),...e.map(h=>this.measureText(F(h),T).width)),g=d*t.length+L*e.length+devicePixelRatio*(t.length+e.length)+3,A=O?g/t.length:null;else{const h=t[0].replace(/[0-9]/g,"3").replace(/[A-Z]/g,"A"),H=4;D=this.measureText(h,f).width+3+3,g=d+H}const C=i.size.x/(w||D),N=i.size.y/(A||g),E=Math.min(C,N);a.push({scaleFactor:E,value:d,lines:[]}),O||s.push({scaleFactor:E,value:L,lines:[]})}if(!this.exh.length){const l=a[a.length-1],p=this.prefixes.find(d=>d.name===y);p&&(a.push({scaleFactor:l.scaleFactor/1.8,value:p.fontSize*devicePixelRatio,lines:[]}),s.push({scaleFactor:l.scaleFactor/1.8,value:p.fontSize*(x?1:.9)*devicePixelRatio,lines:[]}))}const R=q();this.fontUrls=[getFontUrlByWeight(o,R),getFontUrlByWeight(u,R)],this.minZoomDotVisible=getMinZoomFactorForDot(a.map(l=>l.scaleFactor)),this.fontSizes=[a,s]}calcArea(t,e){return Math.floor(Math.max(0,t)*Math.max(0,e)/1e3)}optimizationLevel(){return Math.min(c.viewOptimizationLevel?c.viewOptimizationLevel:Math.floor(this.calcArea(this.canvasRect.size.x,this.canvasRect.size.y)/5e3),3)}measureText(t,e){return P.font=e,P.measureText(t)}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Rect as
|
|
1
|
+
import{Rect as A}from"@expofp/geometry";import C from"debug";import{SEPARATOR as I}from"../../../../constants";import{createImageDef as E}from"../../../../engine/defs";import{flipImageDef as T,isInnerInsideOuter as U,rotateImageDef as _}from"../../../../engine/utils/rotation";import{boothStore as y,uiState as z}from"../../../../store";import K from"../../../../tools/settings";import{loadBlobsInBatchesById as M}from"../../../../utils/loadImagesInBatches";import{clearHoveredBooth as Z,hoverBooth as j,rememberBoothShapes as q,selectBooth as F}from"../../pointer";import{createLogoPreparer as G}from"./booth-logos";import J from"./config-booth-bg";import Q from"./config-booth-bookmark";import V from"./config-booth-border";import X from"./config-booth-labels";import Y from"./config-booth-labels-special";import{registerLayerImages as oo}from"./layer-images";import{createBoothImg as eo,getImageLayerName as to,mapBoothsLogos as ro}from"./loadBoothsImages";const k=C("efp:booth-logos");export const BOOTHS_CHUNK_SIZE=350;export default function no($,D){return(l=>{const i=$,d=[],m=[],p=[],g=[],b=[],u=to(i),B={name:u,children:[]};for(const o of l){const s=J(o)?.getShape();s&&(d.push(...s),q(o,s));const a=X(o)?.getShape();a&&m.push(...a);const c=Y(o)?.getShape();if(c&&p.push(...c),!K.borderless){const e=V(o)?.getShape();e&&g.push(e)}const h=Q(o)?.getShape();h&&b.push(h)}const R=m.filter(o=>o.lines),x=p.filter(o=>o.lines),O=m.filter(o=>o.source),P=p.filter(o=>o.source);if(!z.hideLogoInBooth){const o=ro(l);oo(u,async()=>{const s=await M(o,BOOTHS_CHUNK_SIZE),a=[],c=G(),h=await Promise.all([...s].map(async([e,t])=>{const n=y.boothById.get(e);return[e,n,n?await c(n,t):null]}));for(const[e,t,n]of h){if(!t){k("dropped a logo: no booth has id %s",e);continue}if(!n){k("dropped the logo of booth %s: the image could not be read",e);continue}const{blob:w,aspectRatio:v}=n,{bounds:H}=eo(t,v),r=E(w,H),N=t.borderWidth||y.borderWidth,S=t.rect.expand(-N),W=new A(S.center,S.size,t.rotate);r.onRoll=U(r.bounds,W)?({roll:f})=>_(r,f)?[r]:void 0:({roll:f})=>T(r,f)?[r]:void 0,t.shapes.push(r),a.push(r)}return{layer:B,children:a}})}let L=[];if(l.length){const o=i+I;L=[{name:`${o}boothBackground`,children:d,onPointerMove:j,onPointerOut:Z,onClick:F},{name:`${o}labels`,children:R},{name:`${o}specialLabels`,children:x},{name:`${o}dots`,children:O},{name:`${o}specialDots`,children:P},B,{name:`${o}boothsBookmark`,children:b},{name:`${i}${I}boothBorder`,children:g}]}return{name:i,children:L}})(D)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getConfig as x}from"@expofp/config";import{degToRad as C,Rect as T}from"@expofp/geometry";import{resolve as v}from"@expofp/resolve";import{BOOTHS_PAINTER_MARKER as D,SEPARATOR as s}from"../../../../constants";import{getFpPaths as F}from"../../../../data/fp-payloads";import{createImageDef as G,createLayerDef as h}from"../../../../engine/defs";import m,{boothStore as H,uiState as k}from"../../../../store";import K from"../../../../store/init/init-booths";import{getChildLayers as Y}from"../../../../store/init/init-layers";import{LayersMode as J}from"../../../../store/LayerStore";import{chunkArray as U}from"../../../../utils";import{
|
|
1
|
+
import{getConfig as x}from"@expofp/config";import{degToRad as C,Rect as T}from"@expofp/geometry";import{resolve as v}from"@expofp/resolve";import{BOOTHS_PAINTER_MARKER as D,SEPARATOR as s}from"../../../../constants";import{getFpPaths as F}from"../../../../data/fp-payloads";import{createImageDef as G,createLayerDef as h}from"../../../../engine/defs";import m,{boothStore as H,uiState as k}from"../../../../store";import K from"../../../../store/init/init-booths";import{getChildLayers as Y}from"../../../../store/init/init-layers";import{LayersMode as J}from"../../../../store/LayerStore";import{chunkArray as U}from"../../../../utils";import{loadLayerImages as Z}from"../../../../utils/loadLayerImages";import j,{BG_LAYER_NAME as $,FG_LAYER_NAME as E}from"./config-bg";import q,{BOOTHS_CHUNK_SIZE as z}from"./config-booths";import{configOutdoorPoiLayer as Q}from"./config-outdoor-poi";import{registerLayerImages as V}from"./layer-images";import{createModelDefFromElement as W}from"./layer-models";import{getImageLayerName as X,getLayerGraphics as ee,getModelLayerName as oe}from"./loadBoothsImages";function re(e){return e.childLayers.length?e.childLayers:Y(e,e.basePriority,15).layers}async function R(e,i){const r=[],n=K(m,e);if(Q(e,n))return e.loaded=!0,e.configured=!0,e.children=[],h(e.name,[],{hidden:!0});const a=await j(e),c=[],S=U(n,z),d=H.booths.filter(o=>o.rect&&(!o.layer||o.layer===e||o.layer.childLayers.includes(e))&&o.exhibitors.find(t=>!!t.logoInBooth&&!!t.logo?.url)&&!k.hideLogoInBooth),I=new Map(d.map(o=>[o,o.noLabels]));d.forEach(o=>o.noLabels=!0),n.length&&S.forEach((o,t)=>{c.push(q(`${e.name}${s}${D}${s}${t}`,o))});for(const[o,t]of I)o.noLabels=t;e.loaded=!0;const g=a.children.find(o=>o.name===$),l=a.children.find(o=>o.name===E),u=X(e.name),{icons:f,models:A}=ee(e),p={name:u,children:[]},y={name:oe(e.name),children:A.map(W)};f.length&&V(u,async()=>{const o=await Z(f),t=[];for(const M of o){const{bounds:{x:L,y:b,height:P,angle:N,width:_},source:w}=M,O=T.fromMinMax({x:L,y:b},{x:L+_,y:b+P},C(N));t.push(G(w,O))}return{layer:p,children:t}}),g&&r.push({...g,name:`${a.name}${s}${$}`}),c.length&&r.push(...c),l&&r.push({...l,name:`${a.name}${s}${E}`}),f.length&&r.push(p),y.children.length&&r.push(y);const B=await Promise.all(e.childLayers.sort((o,t)=>o.basePriority-t.basePriority).map(o=>R(o,!0)));return r.push(...B),e.children=r,e.configured=!0,h(e.name,r,{hidden:!i})}export default async function te(e){if(e.configured)return h(e.name,e.children,{hidden:!e.visible});if(m.layerStore.mode!==J.Default&&!F(e.name)&&!e.rootParent)try{const n=x().fpSvgLayerJsRefs[e.name];n&&await v(n)}catch(n){console.warn(`Layer data not loaded: ${e.name}`,n)}const i=re(e);i.length&&(e.childLayers=i);const{layers:r}=m.layerStore;return m.layerStore.layers=[...r,...i.filter(n=>!r.some(a=>a.name===n.name))],R(e,e.visible)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Box as O}from"@expofp/geometry";import{update as
|
|
1
|
+
import{Box as O}from"@expofp/geometry";import{update as v}from"@expofp/renderer";import{reaction as I}from"mobx";import{getBounds as w}from"../../../../engine/canvases";import{createImageDef as E}from"../../../../engine/defs";import u,{layersStore as C}from"../../../../store";import{setMarkerResolver as R}from"../../pointer";import{createImageCanvas as P}from"./canvases";const L="_selected";export const MARKER_LAYER_NAME="markers";function T(o,f){const{center:c,rotation:r}=o.bounds,{width:i,height:s}=o.source;return o.bounds=w(c.x,c.y,i,s,f,r),[o]}function W(o){B=o}export function configMarkers(o){const{scene:f}=o,c=[],r=new Map,i=new Map;let s=[];const a=f.rootLayer.children.find(e=>e.name===MARKER_LAYER_NAME);a.onScale=({pixelSize:e})=>W(e),R(markerAt),v(a);async function g(e){const n=[];e.forEach(m=>{const{name:t,content:d,width:l,height:k,scale:y}=m;if(r.has(t))return;const h=new Image,M=new Promise((S,D)=>{h.onload=()=>{r.set(t,{img:h,width:l,height:k,scale:y}),S()},h.onerror=b=>{D(b)}});n.push(M),h.src=d,h.crossOrigin="anonymous"}),await Promise.all(n)}const z=e=>{e.onScale=({pixelSize:n})=>T(e,n)},A=e=>{e.onRoll=({roll:n})=>{if(n!==e.bounds.rotation)return e.bounds.rotate(n-e.bounds.rotation,e.bounds),[e]}};function _(){const e=u.routeStore.markersData.markers;if(!e.length)return;s=[];const n=1,m=0;e.forEach(t=>{const d=r.get(t.icon);if(!d)return;const l=d.scale||window.devicePixelRatio,k=t.icon;if(!i.has(k)){const x=P(d.img,d.width,d.height,l);i.set(k,x)}const y=i.get(k),h=r.get(t.selectedIcon),M=t.selectedIcon;if(!i.has(M)){const x=P(h.img,h.width,h.height,l);i.set(M,x)}const S=i.get(M),D=C.findLayer(t.z)?.visible??!0,b=w(t.x,t.y,y.width,y.height,n,m),F=w(t.x,t.y,S.width,S.height,n,m);let p;switch(t.position){case"lefttop":p=[0,0];break;case"centertop":p=[.5,0];break;case"centerbottom":p=[.5,1];break;default:p=[.5,.5]}const H={...E(y,b,{hidden:!D,origin:p}),id:t.id,scale:l},N={...E(S,F,{hidden:!(D&&t.active),origin:p}),id:`${t.id}${L}`,scale:l};s.push(H,N)}),a.children=s,s.forEach(t=>{z(t),A(t)})}function $(){a.children=[],s=[]}function K(){const e=u.routeStore.markersData.markers;e.length&&e.forEach(n=>{const m=s.find(l=>l.id===n.id),t=s.find(l=>l.id===`${n.id}${L}`);if(!m)return;const d=C.findLayer(n.z)?.visible??!0;n.active?(m.hidden=!0,t.hidden=!(d&&n.active)):(m.hidden=!d,t.hidden=!0)})}return c.push(I(()=>[u.routeStore.selectedMarkers,u.layerStore.visible],()=>{if(!u.routeStore.markersData.markers.length){$(),v(a);return}K(),v(...s)})),c.push(I(()=>u.routeStore.markersData.markers,()=>{g(u.routeStore.markersData.icons).then(()=>{_(),v(a)})},{fireImmediately:!0})),function(){c.forEach(n=>n()),c.length=0,a.onScale=void 0,R(),v(a)}}export function markerAt(o,f){return getMarkerFromClick(o,f,B)}export function getMarkerFromClick(o,f,c){for(const r of u.routeStore.markersData.markers){const i=u.routeStore.markersData.icons.find(g=>g.name===r.icon);if(!i)continue;const s=i.width*c*devicePixelRatio,a=i.height*c*devicePixelRatio;if(Y(o,f,r.x,r.y,s,a)){const g=u.layerStore.findLayer(r.z);if(!g||g&&g.visible)return r}}return null}function Y(o,f,c,r,i,s){return O.fromCenter({x:c,y:r},{x:2*i,y:2*s}).containsPoint({x:o,y:f})}let B=1;
|
|
@@ -11,8 +11,8 @@ export declare const MODEL_3D_ATTRIBUTE = "data-model-3d";
|
|
|
11
11
|
* The rotation an element's `transform` carries, in radians.
|
|
12
12
|
*
|
|
13
13
|
* Only the first transform in the list is read, which is what the designer emits. It inherits the
|
|
14
|
-
* assumption `
|
|
15
|
-
* the element's own center, because that is what a geometry `Rect` does. A transform with a
|
|
14
|
+
* assumption `loadLayerImages` has always made: an SVG `rotate(a, cx, cy)` is treated as pivoting
|
|
15
|
+
* about the element's own center, because that is what a geometry `Rect` does. A transform with a
|
|
16
16
|
* different pivot is placed wrongly — pre-existing behavior, recorded rather than fixed here.
|
|
17
17
|
* @param element - The graphic to read.
|
|
18
18
|
* @returns The rotation in radians, positive = clockwise.
|
|
@@ -18,11 +18,28 @@ export interface LayerGraphics {
|
|
|
18
18
|
models: SVGImageElement[];
|
|
19
19
|
}
|
|
20
20
|
export declare function getLayerGraphics(layer: Layer): LayerGraphics;
|
|
21
|
+
/** Where one booth's logo goes. */
|
|
21
22
|
export interface BoothImg {
|
|
23
|
+
/** The booth the logo sits in. */
|
|
22
24
|
booth: Booth;
|
|
25
|
+
/** The booth's slug, which becomes the def's name. */
|
|
23
26
|
name?: string;
|
|
24
|
-
|
|
27
|
+
/**
|
|
28
|
+
* The booth center, the fitted logo size, and the booth rotation.
|
|
29
|
+
*
|
|
30
|
+
* The image def keeps this `Rect` by reference, and `rotateImageDef` and `flipImageDef` rotate
|
|
31
|
+
* it in place. Each booth gets its own, so no other owner sees those writes.
|
|
32
|
+
*/
|
|
25
33
|
bounds: Rect;
|
|
26
34
|
}
|
|
27
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Fits a logo inside a booth and returns where the logo goes.
|
|
37
|
+
*
|
|
38
|
+
* This function takes the logo's aspect ratio, not the logo and not its pixel size. The ratio is
|
|
39
|
+
* the only fact it ever needed from the image: every length below comes from the booth.
|
|
40
|
+
* @param booth - The booth to fit the logo into.
|
|
41
|
+
* @param ratio - The logo's width divided by its height. A finite positive number.
|
|
42
|
+
* @returns The placement.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createBoothImg(booth: Booth, ratio: number): BoothImg;
|
|
28
45
|
//# sourceMappingURL=loadBoothsImages.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{degToRad as
|
|
1
|
+
import{degToRad as f,radToDeg as p,Rect as d}from"@expofp/geometry";import{update as h}from"@expofp/renderer";import{select as u}from"d3";import{SEPARATOR as g}from"../../../../constants";import{getFpSvgJs as y}from"../../../../data/fp-payloads";import{getLayerSvg as L}from"../../../../data/svg";import{getLogoUrl as A}from"../../../../utils/getLogoUrl";import{boothLogoExhibitor as x}from"./booth-logos";import{invokeLayerImages as T}from"./layer-images";import{MODEL_3D_ATTRIBUTE as R}from"./layer-models";export async function loadLayersImages(){const e=T();await Promise.all(e.map(async t=>{const r=await t;if(!r?.children.length)return;const{layer:o,children:s}=r;o.children.push(...s),h(o)}))}export const getImageLayerName=e=>`${e}${g}images`,getModelLayerName=e=>`${e}${g}models`;export function mapBoothsLogos(e){const t=new Map;for(const r of e){if(!r.rect)continue;const o=x(r)?.logo;o&&t.set(r.id,{preferred:A(o),fallback:o.url})}return t}export function getLayerGraphics(e){const t=u(L(e)).select(`[data-layer="${e.name}"]`),r=((y().__fpVersion??0)>5?t.selectAll(":scope > image, :scope > g:not([data-layer]) image").nodes():t.selectAll(":scope > g[data-is-editable='false'] image").nodes()).filter(Boolean),o=[],s=[];for(const a of r)(a.hasAttribute(R)?s:o).push(a);return{icons:o,models:s}}export function createBoothImg(e,t){const r=e.rect,o=r.size.width,s=r.size.height,a=s?o/s:1;let i,n,c;const l=.9;a>t?(n=s*l,i=n*t):(i=o*l,n=i/t);const m=e.rotate||0;return t>=2&&!m&&s>=o*2?(n=o*l,i=n*t,c=-90):c=p(m),i>o&&(i=o,n=i/t),n>s&&(n=s,i=n*t),{name:e.slug,bounds:new d(r.center,{x:i,y:n},f(c),e.elevation),booth:e}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{degToRad as Me,lineAngle as ae,pointDistance as le}from"@expofp/geometry";import{update as
|
|
1
|
+
import{degToRad as Me,lineAngle as ae,pointDistance as le}from"@expofp/geometry";import{update as Y}from"@expofp/renderer";import{useEffect as ve,useRef as v}from"react";import{getBounds as $}from"../../../engine/canvases";import Le from"../../../tools/base-runtime-url";import{loadImage as Re}from"../../../utils/loadImage";import{mapCamera as ue}from"../camera";import{createImageCanvas as Se}from"../drawing/config/canvases";import{getRouteLayerRegex as be,getRouteStopLayerRegex as Te,TRAFFIC_VEHICLES as te}from"./trafficLayers";import{UpdateQueue as Ae}from"./UpdateQueue";const ne=2,Fe=ne*3.5,Z=ne*12,de=Z*.7,Pe=8,Ce="transport_locations",_e=150,Ne="#a4aab6",he=1e3,De=2e4,fe=500;export function useManageTraffic({permission:t,scene:r,dataJsonUrl:n,websocketUrl:a}){const e=v(window.devicePixelRatio),s=v(new Map),o=v(new Map),c=v(null),h=v(null),u=v(0),M=v(1),T=v(new Ae),L=v(new Map),x=v(he),f=v(new Map),p=v(void 0);ve(()=>{if(!t||!r)return;let l=!1,P;const R=r.rootLayer.children,g=o.current,y=s.current,I=T.current;async function ye(){try{let d;try{const i=await fetch(n,{method:"GET",headers:{"Content-Type":"application/json"}});if(!i.ok||i.status===204)return;d=await i.json()}catch(i){console.warn("useManageTraffic failed to get JSON",i)}if(!d||d.disabled||d.error)return;e.current=ge(ue()?.state().pixelSize??window.devicePixelRatio);const D=new Map(d.routes.map(({id:i,color:m})=>[i,m])),z=new Map;D.forEach(i=>{z.set(i,Ve({radius:Fe,color:i,scale:window.devicePixelRatio}))});const U=be(),j=R.filter(i=>U.test(i.name)),Q=Te(),q=R.filter(i=>Q.test(i.name));d.routes.slice(0,j.length).forEach(({id:i,color:m,path:w,stops:C,hiddenPoints:S},V)=>{L.current.set(i,w);const E=j[V];if(E){const H=new Map(S?.map(_=>[ce(_),_])??[]);for(let _=1;_<w.length;_++){const b=w[_-1],W=w[_];H.has(ce(b))||H.has(ce(W))||E.children.push({points:{p0:b,p1:W},color:m,width:ne})}E.children.length&&I.add(()=>Y(E))}const A=q[V],F=z.get(m);A&&F&&C?.length&&(C.forEach(H=>{A.children.push({source:F,bounds:$(H.x,H.y,F.width,F.height,e.current)})}),A.children.length&&I.add(()=>Y(A)))});const O=R.find(i=>i.name===te);if(!O){console.warn(`useManageTraffic: the scene has no "${te}" layer`);return}const B=new Map;O.onScale=({pixelSize:i})=>{e.current=ge(i);const m=[];for(const w of q){const C=w.children;for(const S of C){const V=S.source;S.bounds=$(S.bounds.center.x,S.bounds.center.y,V.width,V.height,e.current,S.bounds.rotation),m.push(S)}}for(const w of s.current.values()){const C=w.source;w.bounds=$(w.bounds.center.x,w.bounds.center.y,C.width,C.height,e.current,w.bounds.rotation),m.push(w)}return m},I.add(()=>Y(O)),D.forEach((i,m)=>{B.set(m,me({id:m,width:Z,height:Z,color:i,scale:window.devicePixelRatio}))});const xe=me({id:"orphan",width:Z,height:Z,color:Ne,scale:window.devicePixelRatio});let G=null;try{const i=await Re(`${Le}icons/bus-white.svg`);G=Se(i,de,de,window.devicePixelRatio)}catch(i){console.error(i)}h.current=i=>{try{const m=JSON.parse(i.data);if(m.type!==Ce)return;const w=i.timeStamp||performance.now();M.current=Math.round(w-u.current),u.current=w;const C=Math.max(M.current??fe,fe),S=O.children;let V=!1;m.data.forEach(({id:E,x:A,y:F,route_id:H,hidden:_})=>{g.has(E)&&(g.get(E)?.(),g.delete(E));const b=y.get(E),W=y.get(re(E))??null;if(_&&b&&W){b.hidden=!0,W.hidden=!0,I.add(()=>Y(b,W));return}if(f.current.set(E,performance.now()),!b){const k=B.get(H)??xe,N={source:k,bounds:$(A,F,k.width,k.height,e.current,0)};if(y.set(E,N),G){const X=re(E),ie={source:G,bounds:$(A,F,G.width,G.height,e.current,0)};G.setAttribute("id",X),y.set(X,ie),S.push(N,ie)}else S.push(N);V=!0;return}const Ee=b.bounds.center,ee=We(Ee,{x:A,y:F},L.current.get(H));if(ee.reduce((k,N,X)=>X===0?k:k+oe(ee[X-1],N),0)>=_e||document.hidden)we({updateQueue:I,vehicle:b,vehicleFinery:W,x:A,y:F,scale:e.current,angle:Oe(b.bounds.center,{x:A,y:F})});else{const k=ke(ee,C,N=>{we({updateQueue:I,vehicle:b,vehicleFinery:W,x:N.x,y:N.y,scale:e.current,angle:N.angle})});g.set(E,k)}}),V&&I.add(()=>Y(O))}catch(m){console.error("handleSocketMessage",m)}},u.current=performance.now(),K(),window.addEventListener("online",se),Ie(d.config?(Number(d.config.vehicle_inactive_interval)||20)*1e3:De)}catch(d){console.warn(d)}}ye();function K(){l||c.current?.readyState===WebSocket.OPEN||c.current?.readyState===WebSocket.CONNECTING||(c.current=new WebSocket(a),c.current.onmessage=h.current,c.current.onopen=()=>{x.current=he},c.current.onclose=()=>{if(l||!navigator.onLine)return;P=window.setTimeout(K,x.current);const d=3e4;x.current=Math.min(x.current*2,d)})}function se(){K()}function Ie(d){clearInterval(p.current),p.current=window.setInterval(()=>{const D=performance.now(),z=[],U=[];f.current.forEach((j,Q)=>{if(D-j<d)return;const q=y.get(Q);q&&(q.hidden=!0,U.push(q),z.push(Q));const O=re(Q),B=y.get(O);B&&(B.hidden=!0,U.push(B),z.push(O))}),U.length&&I.add(()=>Y(...U)),z.forEach(j=>f.current.delete(j))},d)}return()=>{l=!0,clearTimeout(P),c.current?.close(),c.current=null;const d=R.find(D=>D.name===te);d&&(d.onScale=void 0),g.forEach(D=>D?.()),g.clear(),y.clear(),I.destroy(),window.removeEventListener("online",se),clearInterval(p.current)}},[t,r,n,a])}function ge(t){return Math.min(t||window.devicePixelRatio,Pe)}function Oe(t,r){return ae(t,r)}function Ve({radius:t,scale:r,color:n}){const a=document.createElement("canvas"),e=a.getContext("2d");e.imageSmoothingEnabled=!1;const s=Math.ceil(t*2*r),o=s/2,c=t*.78,h=t*.33;return a.width=s,a.height=s,e.translate(o,o),e.scale(r,r),e.beginPath(),e.arc(0,0,t,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),e.beginPath(),e.arc(0,0,c,0,2*Math.PI),e.fillStyle=n,e.fill(),e.beginPath(),e.arc(0,0,h,0,2*Math.PI),e.fillStyle="#FFFFFF",e.fill(),a}function me({id:t,width:r,height:n,color:a,scale:e}){const s=2*e,o=r/2*e,c=n*e,h=.6,u=.01,M=c*h,T=c,L=8*e,x=T+s+M/2+L*2,f=o*2+M+s+L*2,p=document.createElement("canvas");p.setAttribute("id",t),p.width=x,p.height=f;const l=p.getContext("2d"),P=x/2,R=f/2;l.save(),l.translate(P,R),l.rotate(-Math.PI/2),l.translate(-P,-R);const g=P,y=R-T/2+o,I=y+M;return l.shadowColor="rgba(16, 24, 40, 0.2)",l.shadowBlur=L/2,l.beginPath(),l.arc(g,y,o,Math.PI,0,!1),l.bezierCurveTo(g+o,y+c*.3,g+u*o,I,g,I),l.bezierCurveTo(g-u*o,I,g-o,y+c*.3,g-o,y),l.closePath(),l.fillStyle=a,l.fill(),l.strokeStyle="#FFFFFF",l.lineWidth=s,l.stroke(),l.restore(),p}function oe(t,r){return le(t,r)}function re(t){return`${t}_finery`}function we({updateQueue:t,vehicle:r,vehicleFinery:n,x:a,y:e,scale:s,angle:o}){const c=r.source;if(r.bounds=$(a,e,c.width,c.height,s,o),r.hidden=!1,n){const h=ue()?.state().roll??0,u=n.source;n.bounds=$(a,e,u.width,u.height,s,Me(h)),n.hidden=!1,t.add(()=>Y(n,r))}else t.add(()=>Y(r))}function J(t,r,n){return{x:t.x+(r.x-t.x)*n,y:t.y+(r.y-t.y)*n}}function pe(t,r){let n=1/0,a={index:0,t:0};for(let e=0;e<r.length-1;e++){const s=r[e],o=r[e+1],c=o.x-s.x,h=o.y-s.y,u=c*c+h*h,M=u?((t.x-s.x)*c+(t.y-s.y)*h)/u:0,T=Math.max(0,Math.min(1,M)),L=J(s,o,T),x=oe(t,L);x<n&&(n=x,a={index:e,t:T})}return a}function He(t,r,n){const a=oe(t,r),e=Math.max(2,Math.ceil(a/n)+1),s=[];for(let o=0;o<e;o++){const c=o/(e-1),h=J(t,r,c);s.push(h)}return s}function We(t,r,n){if(!n||!n.length)return He(t,r,10);const a=pe(t,n),e=pe(r,n),s=[],o=c=>s.push(c);a.index+1<n.length?o(J(n[a.index],n[a.index+1],a.t)):o(n[a.index]);for(let c=a.index+1;c<=e.index&&c<n.length;c++)o(n[c]);return e.index+1<n.length?o(J(n[e.index],n[e.index+1],e.t)):o(n[e.index]),s}function ke(t,r,n,a){if(t.length<2)return()=>{};let e=null,s;const o=[];let c=0;for(let u=0;u<t.length-1;u++){const M=le(t[u],t[u+1]);o.push(M),c+=M}const h=u=>{e||(e=u);const M=u-e,T=Math.min(M/r,1),L=T*c;let x=0,f=0;for(;f<o.length&&x+o[f]<L;)x+=o[f],f++;f>=o.length&&(f=o.length-1);const p=t[f],l=t[Math.min(f+1,t.length-1)],P=o[f]||0,R=P===0?0:(L-x)/P,g=p.x+(l.x-p.x)*R,y=p.y+(l.y-p.y)*R,I=ae(p,l);n({x:g,y,angle:I}),T<1?s=requestAnimationFrame(h):a&&a()};return s=requestAnimationFrame(h),()=>{s&&cancelAnimationFrame(s)}}function ce(t){return`${t.x},${t.y}`}
|
|
@@ -67,6 +67,8 @@ export declare class Exhibitor implements Omit<RawExhibitor, 'categories' | 'boo
|
|
|
67
67
|
/** Always the object form — `normalizeLegacyData` converts legacy string logos. */
|
|
68
68
|
readonly logo?: Logo;
|
|
69
69
|
readonly logoInBooth: boolean;
|
|
70
|
+
/** The logo's width divided by its height, when the event data states it. */
|
|
71
|
+
readonly logoAspectRatio?: number;
|
|
70
72
|
readonly gallery: string[];
|
|
71
73
|
readonly marketMaterials: MarketMaterial[];
|
|
72
74
|
readonly slug: string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Measures an image's intrinsic size without keeping its pixels.
|
|
3
|
+
*
|
|
4
|
+
* Floorplan needs one number from a logo's pixels: the aspect ratio, to fit the logo inside a
|
|
5
|
+
* booth. `createImageBitmap` gives that number at low cost. The browser decodes the image on its
|
|
6
|
+
* own thread. Then it resolves a promise. The main thread pays only for the call and for the
|
|
7
|
+
* promise resolution, not for the decode itself. This is the difference between
|
|
8
|
+
* `createImageBitmap` and an `<img>` element, which decodes on the same thread as the page.
|
|
9
|
+
*
|
|
10
|
+
* The function closes the bitmap right after it reads the size. A caller can start as many calls
|
|
11
|
+
* as it wants. At any instant, only a few bitmaps exist in memory: the ones the browser's decoder
|
|
12
|
+
* already finished but did not yet hand back. The whole batch of logos never sits in memory
|
|
13
|
+
* together. One cost remains, and this cost is accepted: each logo gets decoded twice, once here
|
|
14
|
+
* and once in the atlas worker. This happens because a Blob cannot report its own size, and the
|
|
15
|
+
* renderer does not report one back either.
|
|
16
|
+
*
|
|
17
|
+
* This function has no `<img>` fallback. `createImageBitmap` works on every build target that
|
|
18
|
+
* this SDK supports. The only targets that lack `createImageBitmap` are targets where the whole
|
|
19
|
+
* SDK already fails to run.
|
|
20
|
+
* @param blob - The image bytes.
|
|
21
|
+
* @returns The size, or `null` if the bytes cannot be decoded.
|
|
22
|
+
*/
|
|
23
|
+
export declare function blobImageSize(blob: Blob): Promise<{
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
} | null>;
|
|
27
|
+
//# sourceMappingURL=blob-image-size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export async function blobImageSize(e){try{const t=await createImageBitmap(e),i={width:t.width,height:t.height};return t.close(),i}catch{return null}}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches an image as a `Blob`, the form the renderer packs from.
|
|
3
|
+
*
|
|
4
|
+
* This function returns a `Blob`, not an `HTMLImageElement`, because decoding an image element
|
|
5
|
+
* blocks the main thread. At a thousand booth logos, the `HTMLImageElement` route stalls the
|
|
6
|
+
* thread for two seconds, and the `Blob` route does not stall it at all. A `Blob` is also a handle
|
|
7
|
+
* to bytes that do not change. A worker that receives one gets the handle, not a copy of the bytes.
|
|
8
|
+
*
|
|
9
|
+
* This function never throws. `normalize-legacy-data.ts` mints the `__small` and `__tiny` logo
|
|
10
|
+
* variants by adding a suffix to the full URL. It never confirms that the variant file exists. A
|
|
11
|
+
* 404 here is routine. When it happens, the caller retries with its fallback URL.
|
|
12
|
+
* @param src - The image URL.
|
|
13
|
+
* @returns The bytes, or `null` when the fetch fails.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadBlob(src: string): Promise<Blob | null>;
|
|
16
|
+
//# sourceMappingURL=loadBlob.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export async function loadBlob(o){try{const t=await fetch(o,{mode:"cors",credentials:"omit"});if(!t.ok)return null;const n=await t.blob();return n.type.startsWith("image/")?n:null}catch{return null}}
|
|
@@ -2,6 +2,21 @@ export interface ImageUrls {
|
|
|
2
2
|
preferred?: string;
|
|
3
3
|
fallback: string;
|
|
4
4
|
}
|
|
5
|
-
export declare function loadImagesInBatches(urls: ImageUrls[], batchSize?: number, delay?: number): Promise<HTMLImageElement[]>;
|
|
6
5
|
export declare function loadImagesInBatchesById(logosUrls: Map<number, ImageUrls>, batchSize?: number, delay?: number): Promise<Map<number, HTMLImageElement>>;
|
|
6
|
+
/**
|
|
7
|
+
* Loads a map of ids to image bytes. One URL loads at most once per call, no matter how many ids
|
|
8
|
+
* share it.
|
|
9
|
+
*
|
|
10
|
+
* This dedup is not an optimization. It is a correctness requirement. The renderer dedupes image
|
|
11
|
+
* sources by object identity, so two booths that share a logo must get the very same `Blob`
|
|
12
|
+
* object. If they do not, the logo downloads twice, packs twice, and draws from two atlas
|
|
13
|
+
* regions. The cache lives only for the length of this call, because the defs keep their own
|
|
14
|
+
* Blobs afterward. A cache that outlived the call would give every logo on the plan a second
|
|
15
|
+
* place to stay in memory.
|
|
16
|
+
* @param logosUrls - The URLs to load, keyed by booth id.
|
|
17
|
+
* @param batchSize - How many URLs to load at once.
|
|
18
|
+
* @param delay - Milliseconds to wait between batches.
|
|
19
|
+
* @returns The bytes, keyed by booth id. An id is absent when its logo failed to load.
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadBlobsInBatchesById(logosUrls: Map<number, ImageUrls>, batchSize?: number, delay?: number): Promise<Map<number, Blob>>;
|
|
7
22
|
//# sourceMappingURL=loadImagesInBatches.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import
|
|
1
|
+
import w from"./is-mobile";import y from"./is-webview";import{loadBlob as B}from"./loadBlob";import{loadImage as I}from"./loadImage";const f=w||y,l=f?8:512,d=f?100:0;async function b(e,o){const t=e.preferred?await o(e.preferred):null;return t||(e.fallback?o(e.fallback):null)}async function m(e,o,t,a){if(!e.size)return new Map;const c=Array.from(e.entries()),r=new Map;for(let n=0;n<c.length;n+=t){const p=c.slice(n,n+t),u=await Promise.all(p.map(async([i,s])=>[i,await b(s,o)]));for(const[i,s]of u)s&&r.set(i,s);a&&await new Promise(i=>setTimeout(i,a))}return r}export async function loadImagesInBatchesById(e,o=l,t=d){return m(e,I,o,t)}export async function loadBlobsInBatchesById(e,o=l,t=d){const a=new Map;return m(e,r=>{let n=a.get(r);return n||(n=B(r),a.set(r,n)),n},o,t)}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type Booth } from '../store/BoothStore';
|
|
2
|
+
/** One `<image>` from a layer's drawing: where it sits, and the pixels to draw there. */
|
|
3
|
+
export interface LayerImage {
|
|
4
|
+
/** The booth this image belongs to, or null for a plain layer graphic. */
|
|
5
|
+
booth: Booth | null;
|
|
6
|
+
/** The image's name, when it has one. */
|
|
7
|
+
name?: string;
|
|
8
|
+
/**
|
|
9
|
+
* The bytes the renderer packs. An SVG image is rasterized and re-encoded as PNG.
|
|
10
|
+
*
|
|
11
|
+
* `createImageBitmap` rejects SVG bytes, so an SVG cannot travel to the atlas worker as it is.
|
|
12
|
+
* It stays a `Blob` all the same: a layer packs in the worker only while every one of its
|
|
13
|
+
* sources is a `Blob`, so one canvas among a layer's graphics would drop the whole layer back
|
|
14
|
+
* onto the main thread.
|
|
15
|
+
*/
|
|
16
|
+
source: Blob;
|
|
17
|
+
/** Placement read off the SVG element: top-left, size, and rotation in degrees. */
|
|
18
|
+
bounds: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
angle: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Loads a layer's drawing images as bytes.
|
|
28
|
+
*
|
|
29
|
+
* The placement comes from the SVG element, not from the file. Nothing here needs the image's
|
|
30
|
+
* intrinsic size, so a raster image is never decoded. Avoiding that decode on the main thread is
|
|
31
|
+
* the reason for this change.
|
|
32
|
+
*
|
|
33
|
+
* Most of these hrefs are inline `data:image/webp;base64` URLs, not file references. The
|
|
34
|
+
* converter embeds designer graphics directly in the drawing payload. In a real plan, the first
|
|
35
|
+
* such image is 74KB of WebP inside a 68-unit box. `fetch` serves a `data:` URL from the browser
|
|
36
|
+
* itself, with no network call and no CORS check, and returns a Blob whose `type` matches the one
|
|
37
|
+
* the URL declares. These Blobs reach the renderer exactly as a fetched logo does, and take the
|
|
38
|
+
* same worker path. A drawing can also carry `svg-images/…` file references. `@expofp/config`
|
|
39
|
+
* rebases those to absolute URLs before this function sees them. Both forms go through `loadBlob`
|
|
40
|
+
* unchanged.
|
|
41
|
+
* @param svgImages - The `<image>` elements to load.
|
|
42
|
+
* @returns One entry per image that loaded, in element order. Images that failed to load are
|
|
43
|
+
* dropped.
|
|
44
|
+
*/
|
|
45
|
+
export declare function loadLayerImages(svgImages: SVGImageElement[]): Promise<LayerImage[]>;
|
|
46
|
+
//# sourceMappingURL=loadLayerImages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{loadBlob as e}from"./loadBlob";import{isSvgBlob as u,svgToPngBlob as i}from"./rasterize-svg";export async function loadLayerImages(a){const t=new Map,r=n=>{let l=t.get(n);return l||(l=s(n),t.set(n,l)),l};return(await Promise.all(a.map(async n=>{const l=n.getAttribute("xlink:href")??n.getAttribute("href"),o=l?await r(l):null;return o?{bounds:{x:n.x.animVal.value,y:n.y.animVal.value,width:n.width.animVal.value,height:n.height.animVal.value,angle:n.transform?.animVal[0]?.angle??0},source:o,booth:null}:null}))).filter(n=>n!==null)}async function s(a){const t=await e(a);return t?u(t)?i(t):t:null}
|