@graphrefly/ts 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +197 -117
- package/dist/actions-types-CH-XCU9O.d.cts +657 -0
- package/dist/actions-types-w2iPQTkv.d.ts +657 -0
- package/dist/adapters/index.cjs +5157 -2951
- package/dist/adapters/index.cjs.map +1 -1
- package/dist/adapters/index.d.cts +207 -70
- package/dist/adapters/index.d.ts +207 -70
- package/dist/adapters/index.js +3738 -1688
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/nestjs/microservices.cjs +841 -0
- package/dist/adapters/nestjs/microservices.cjs.map +1 -0
- package/dist/adapters/nestjs/microservices.d.cts +45 -0
- package/dist/adapters/nestjs/microservices.d.ts +45 -0
- package/dist/adapters/nestjs/microservices.js +206 -0
- package/dist/adapters/nestjs/microservices.js.map +1 -0
- package/dist/adapters/nestjs/native.cjs +1391 -0
- package/dist/adapters/nestjs/native.cjs.map +1 -0
- package/dist/adapters/nestjs/native.d.cts +111 -0
- package/dist/adapters/nestjs/native.d.ts +111 -0
- package/dist/adapters/nestjs/native.js +577 -0
- package/dist/adapters/nestjs/native.js.map +1 -0
- package/dist/adapters/nestjs/websockets.cjs +924 -0
- package/dist/adapters/nestjs/websockets.cjs.map +1 -0
- package/dist/adapters/nestjs/websockets.d.cts +47 -0
- package/dist/adapters/nestjs/websockets.d.ts +47 -0
- package/dist/adapters/nestjs/websockets.js +286 -0
- package/dist/adapters/nestjs/websockets.js.map +1 -0
- package/dist/adapters/nestjs.cjs +1085 -0
- package/dist/adapters/nestjs.cjs.map +1 -0
- package/dist/adapters/nestjs.d.cts +385 -0
- package/dist/adapters/nestjs.d.ts +385 -0
- package/dist/adapters/nestjs.js +112 -0
- package/dist/adapters/nestjs.js.map +1 -0
- package/dist/adapters/observe-storage.d.cts +3 -3
- package/dist/adapters/observe-storage.d.ts +3 -3
- package/dist/adapters/observe-storage.js +4 -4
- package/dist/adapters/react.cjs.map +1 -1
- package/dist/adapters/react.d.cts +2 -2
- package/dist/adapters/react.d.ts +2 -2
- package/dist/adapters/react.js +1 -1
- package/dist/adapters/solid.cjs.map +1 -1
- package/dist/adapters/solid.d.cts +2 -2
- package/dist/adapters/solid.d.ts +2 -2
- package/dist/adapters/solid.js +1 -1
- package/dist/adapters/svelte.cjs.map +1 -1
- package/dist/adapters/svelte.d.cts +2 -2
- package/dist/adapters/svelte.d.ts +2 -2
- package/dist/adapters/svelte.js +1 -1
- package/dist/adapters/vue.cjs.map +1 -1
- package/dist/adapters/vue.d.cts +2 -2
- package/dist/adapters/vue.d.ts +2 -2
- package/dist/adapters/vue.js +1 -1
- package/dist/{agent-runtime-BesGDZcB.d.ts → agent-runtime-types-core-CKwrBDyi.d.ts} +171 -320
- package/dist/{agent-runtime-DZTJ3C-p.d.cts → agent-runtime-types-core-bfl4m0vM.d.cts} +171 -320
- package/dist/agent-runtime-types-tool-BLPV3azj.d.cts +695 -0
- package/dist/agent-runtime-types-tool-hwqvVqNt.d.ts +695 -0
- package/dist/agentic-memory-retention-CLwI76JK.d.ts +14 -0
- package/dist/agentic-memory-retention-Cz8GR6ie.d.cts +14 -0
- package/dist/{agentic-memory-DfuVZ-lY.d.cts → agentic-memory-types-JDr7MPhh.d.cts} +13 -57
- package/dist/{agentic-memory-BmRCvh0d.d.ts → agentic-memory-types-khYJgzKL.d.ts} +13 -57
- package/dist/{capability-admission-B0BzqAm5.d.cts → capability-admission-B8RNFyaZ.d.cts} +3 -3
- package/dist/{capability-admission-g0mn9hpq.d.ts → capability-admission-Dkw1Xz3r.d.ts} +3 -3
- package/dist/chunk-2KUAG2GZ.js +9693 -0
- package/dist/chunk-2KUAG2GZ.js.map +1 -0
- package/dist/{chunk-CZNV3VXM.js → chunk-3J7UPZL5.js} +11 -11
- package/dist/{chunk-HKK2JD7Z.js → chunk-3LYI6ADX.js} +12 -125
- package/dist/chunk-3LYI6ADX.js.map +1 -0
- package/dist/{chunk-YXMZ2N6J.js → chunk-4M37FH2I.js} +1071 -1025
- package/dist/chunk-4M37FH2I.js.map +1 -0
- package/dist/{chunk-YDSIVHRR.js → chunk-4NWSNI4K.js} +1598 -1584
- package/dist/chunk-4NWSNI4K.js.map +1 -0
- package/dist/{chunk-Z2ANQ6JW.js → chunk-4Q77MMJY.js} +2 -2
- package/dist/{chunk-SS2A464I.js → chunk-54WPEODM.js} +3 -3
- package/dist/chunk-54WPEODM.js.map +1 -0
- package/dist/chunk-6E76H4OU.js +132 -0
- package/dist/chunk-6E76H4OU.js.map +1 -0
- package/dist/chunk-7GOTIIQ7.js +819 -0
- package/dist/chunk-7GOTIIQ7.js.map +1 -0
- package/dist/{chunk-V7CIJE4B.js → chunk-DKFWDTVY.js} +92 -9
- package/dist/chunk-DKFWDTVY.js.map +1 -0
- package/dist/{chunk-FBUU43PM.js → chunk-E4QCH32M.js} +448 -446
- package/dist/chunk-E4QCH32M.js.map +1 -0
- package/dist/{chunk-XKXWK2KP.js → chunk-GXU6WFEJ.js} +1157 -1021
- package/dist/chunk-GXU6WFEJ.js.map +1 -0
- package/dist/{chunk-K3FXTC3I.js → chunk-HJACH5PU.js} +3 -3
- package/dist/{chunk-GTPCOEOZ.js → chunk-IDMLXLLG.js} +3 -3
- package/dist/{chunk-DKP56CSW.js → chunk-JKAYLDQV.js} +2 -2
- package/dist/{chunk-4VLAQHZI.js → chunk-K7FB3JTD.js} +17 -1
- package/dist/chunk-K7FB3JTD.js.map +1 -0
- package/dist/{chunk-43BKLFZU.js → chunk-KFURM6FM.js} +10 -10
- package/dist/{chunk-H75VXTGT.js → chunk-L6LDXRWE.js} +3 -3
- package/dist/{chunk-H75VXTGT.js.map → chunk-L6LDXRWE.js.map} +1 -1
- package/dist/chunk-MCOFHMUU.js +4131 -0
- package/dist/chunk-MCOFHMUU.js.map +1 -0
- package/dist/chunk-MQEQMS7B.js +1009 -0
- package/dist/chunk-MQEQMS7B.js.map +1 -0
- package/dist/chunk-MTELVIYR.js +1421 -0
- package/dist/chunk-MTELVIYR.js.map +1 -0
- package/dist/{chunk-3JR3EDB2.js → chunk-NNDIFUKX.js} +121 -115
- package/dist/chunk-NNDIFUKX.js.map +1 -0
- package/dist/{chunk-2747WN4Y.js → chunk-PUSRRALM.js} +3 -3
- package/dist/{chunk-QFY4AFY4.js → chunk-PVC7WDKI.js} +58 -52
- package/dist/chunk-PVC7WDKI.js.map +1 -0
- package/dist/{chunk-VTHLCFN4.js → chunk-RAHNUYA5.js} +2 -2
- package/dist/chunk-TQPCAIQI.js +612 -0
- package/dist/chunk-TQPCAIQI.js.map +1 -0
- package/dist/{chunk-IXZBUWSP.js → chunk-UEMN5URK.js} +2 -2
- package/dist/chunk-WOS7RJYZ.js +1320 -0
- package/dist/chunk-WOS7RJYZ.js.map +1 -0
- package/dist/{chunk-6PHB5CJS.js → chunk-ZLFRB6FI.js} +2 -2
- package/dist/composition/index.cjs +1228 -1076
- package/dist/composition/index.cjs.map +1 -1
- package/dist/composition/index.d.cts +3 -3
- package/dist/composition/index.d.ts +3 -3
- package/dist/composition/index.js +4 -4
- package/dist/core/index.cjs +1198 -1046
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +23 -2
- package/dist/core/index.d.ts +23 -2
- package/dist/core/index.js +2 -2
- package/dist/cqrs/index.d.cts +3 -3
- package/dist/cqrs/index.d.ts +3 -3
- package/dist/cqrs/messaging.d.cts +4 -4
- package/dist/cqrs/messaging.d.ts +4 -4
- package/dist/cqrs/work-queue.d.cts +5 -5
- package/dist/cqrs/work-queue.d.ts +5 -5
- package/dist/data-structures/index.cjs +1226 -1074
- package/dist/data-structures/index.cjs.map +1 -1
- package/dist/data-structures/index.d.cts +8 -7
- package/dist/data-structures/index.d.ts +8 -7
- package/dist/data-structures/index.js +6 -5
- package/dist/{describe-DYMw_l1C.d.cts → describe-BumQ-3_0.d.cts} +1 -1
- package/dist/{describe-BpyJuWkw.d.ts → describe-cYr_Z5zm.d.ts} +1 -1
- package/dist/executors/tool-provider-adapters.cjs +3091 -0
- package/dist/executors/tool-provider-adapters.cjs.map +1 -0
- package/dist/executors/tool-provider-adapters.d.cts +174 -0
- package/dist/executors/tool-provider-adapters.d.ts +174 -0
- package/dist/executors/tool-provider-adapters.js +1336 -0
- package/dist/executors/tool-provider-adapters.js.map +1 -0
- package/dist/executors/tool-provider-runtime.cjs +5178 -0
- package/dist/executors/tool-provider-runtime.cjs.map +1 -0
- package/dist/executors/tool-provider-runtime.d.cts +17 -0
- package/dist/executors/tool-provider-runtime.d.ts +17 -0
- package/dist/executors/tool-provider-runtime.js +15 -0
- package/dist/executors/tool-provider-runtime.js.map +1 -0
- package/dist/executors/tool-provider.cjs +6392 -0
- package/dist/executors/tool-provider.cjs.map +1 -0
- package/dist/executors/tool-provider.d.cts +60 -0
- package/dist/executors/tool-provider.d.ts +60 -0
- package/dist/executors/tool-provider.js +89 -0
- package/dist/executors/tool-provider.js.map +1 -0
- package/dist/executors/work-queue.d.cts +6 -6
- package/dist/executors/work-queue.d.ts +6 -6
- package/dist/graph/index.cjs +1499 -1341
- package/dist/graph/index.cjs.map +1 -1
- package/dist/graph/index.d.cts +9 -8
- package/dist/graph/index.d.ts +9 -8
- package/dist/graph/index.js +23 -22
- package/dist/{graph-DCEWh4T2.d.cts → graph-C1C-wb0L.d.cts} +266 -137
- package/dist/{graph-D-1-SQeC.d.ts → graph-CS0b4V9B.d.ts} +266 -137
- package/dist/{index-72VZC0-E.d.cts → index-DLrNopda.d.cts} +151 -10
- package/dist/{index-Bmxeu0nK.d.ts → index-DzJni3_6.d.ts} +151 -10
- package/dist/index.cjs +3397 -3140
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -9
- package/dist/index.d.ts +12 -9
- package/dist/index.js +110 -109
- package/dist/inspection/boundary.d.cts +4 -4
- package/dist/inspection/boundary.d.ts +4 -4
- package/dist/measurements-BWAnochv.d.ts +294 -0
- package/dist/measurements-B_gJfD8h.d.cts +294 -0
- package/dist/messaging/index.cjs +57 -51
- package/dist/messaging/index.cjs.map +1 -1
- package/dist/messaging/index.d.cts +11 -276
- package/dist/messaging/index.d.ts +11 -276
- package/dist/messaging/index.js +1 -1
- package/dist/operators/index.cjs +1228 -1076
- package/dist/operators/index.cjs.map +1 -1
- package/dist/operators/index.d.cts +5 -5
- package/dist/operators/index.d.ts +5 -5
- package/dist/operators/index.js +5 -5
- package/dist/orchestration/index.cjs +8844 -6071
- package/dist/orchestration/index.cjs.map +1 -1
- package/dist/orchestration/index.d.cts +171 -224
- package/dist/orchestration/index.d.ts +171 -224
- package/dist/orchestration/index.js +42 -991
- package/dist/orchestration/index.js.map +1 -1
- package/dist/orchestration/messaging.d.cts +5 -8
- package/dist/orchestration/messaging.d.ts +5 -8
- package/dist/orchestration/work-queue.cjs +1243 -5
- package/dist/orchestration/work-queue.cjs.map +1 -1
- package/dist/orchestration/work-queue.d.cts +121 -10
- package/dist/orchestration/work-queue.d.ts +121 -10
- package/dist/orchestration/work-queue.js +1067 -4
- package/dist/orchestration/work-queue.js.map +1 -1
- package/dist/patterns/event-flow.cjs +6 -20
- package/dist/patterns/event-flow.cjs.map +1 -1
- package/dist/patterns/event-flow.d.cts +4 -4
- package/dist/patterns/event-flow.d.ts +4 -4
- package/dist/patterns/event-flow.js +2 -2
- package/dist/patterns/index.cjs +453 -465
- package/dist/patterns/index.cjs.map +1 -1
- package/dist/patterns/index.d.cts +6 -5
- package/dist/patterns/index.d.ts +6 -5
- package/dist/patterns/index.js +3 -3
- package/dist/process-types-BB7oRhX3.d.cts +200 -0
- package/dist/process-types-QNhyoYJ8.d.ts +200 -0
- package/dist/{reactive-collection-DNV0-gFi.d.cts → reactive-collection-BYlWvtnp.d.cts} +4 -34
- package/dist/{reactive-collection-BAmfrGjd.d.ts → reactive-collection-efOEdGFN.d.ts} +4 -34
- package/dist/{reactive-collection-storage-BNEldDyi.d.cts → reactive-collection-storage-BjoLsoiC.d.cts} +5 -5
- package/dist/{reactive-collection-storage-YZsAQsWK.d.ts → reactive-collection-storage-DwW6UuK_.d.ts} +5 -5
- package/dist/{reactive-map-DRD1LJ2H.d.cts → reactive-map-BHacbIqz.d.cts} +7 -2
- package/dist/{reactive-map-EsDiCmJk.d.ts → reactive-map-DN4Jyqnf.d.ts} +7 -2
- package/dist/render/index.d.cts +2 -2
- package/dist/render/index.d.ts +2 -2
- package/dist/scheduled-readiness-BmqXxnzX.d.ts +91 -0
- package/dist/scheduled-readiness-CYSw7KDE.d.cts +91 -0
- package/dist/semantic-memory-graph-B_LwbM-E.d.cts +30 -0
- package/dist/semantic-memory-graph-rsFNNhwn.d.ts +30 -0
- package/dist/{semantic-memory-graph-DKuNzuWw.d.cts → semantic-memory-graph-types-Y73bbwVI.d.cts} +2 -28
- package/dist/{semantic-memory-graph-uwbwJdhe.d.ts → semantic-memory-graph-types-safmPkuX.d.ts} +2 -28
- package/dist/solutions/index.cjs +6353 -6169
- package/dist/solutions/index.cjs.map +1 -1
- package/dist/solutions/index.d.cts +12 -10
- package/dist/solutions/index.d.ts +12 -10
- package/dist/solutions/index.js +5 -5
- package/dist/solutions/reactive-layout/browser/index.cjs +116 -108
- package/dist/solutions/reactive-layout/browser/index.cjs.map +1 -1
- package/dist/solutions/reactive-layout/browser/index.d.cts +4 -4
- package/dist/solutions/reactive-layout/browser/index.d.ts +4 -4
- package/dist/solutions/reactive-layout/browser/index.js +3 -3
- package/dist/solutions/reactive-layout/index.cjs +3578 -3350
- package/dist/solutions/reactive-layout/index.cjs.map +1 -1
- package/dist/solutions/reactive-layout/index.d.cts +32 -576
- package/dist/solutions/reactive-layout/index.d.ts +32 -576
- package/dist/solutions/reactive-layout/index.js +65 -5
- package/dist/solutions/reactive-layout/node-canvas/index.cjs +127 -117
- package/dist/solutions/reactive-layout/node-canvas/index.cjs.map +1 -1
- package/dist/solutions/reactive-layout/node-canvas/index.d.cts +4 -4
- package/dist/solutions/reactive-layout/node-canvas/index.d.ts +4 -4
- package/dist/solutions/reactive-layout/node-canvas/index.js +3 -3
- package/dist/solutions/reactive-layout/react-native/index.cjs +127 -117
- package/dist/solutions/reactive-layout/react-native/index.cjs.map +1 -1
- package/dist/solutions/reactive-layout/react-native/index.d.cts +4 -4
- package/dist/solutions/reactive-layout/react-native/index.d.ts +4 -4
- package/dist/solutions/reactive-layout/react-native/index.js +3 -3
- package/dist/solutions/reactive-layout/skia/index.cjs +127 -117
- package/dist/solutions/reactive-layout/skia/index.cjs.map +1 -1
- package/dist/solutions/reactive-layout/skia/index.d.cts +4 -4
- package/dist/solutions/reactive-layout/skia/index.d.ts +4 -4
- package/dist/solutions/reactive-layout/skia/index.js +3 -3
- package/dist/solutions/work-item/actions.cjs +1609 -1428
- package/dist/solutions/work-item/actions.cjs.map +1 -1
- package/dist/solutions/work-item/actions.d.cts +23 -184
- package/dist/solutions/work-item/actions.d.ts +23 -184
- package/dist/solutions/work-item/actions.js +1558 -934
- package/dist/solutions/work-item/actions.js.map +1 -1
- package/dist/solutions/work-item/scheduling.cjs +9181 -1838
- package/dist/solutions/work-item/scheduling.cjs.map +1 -1
- package/dist/solutions/work-item/scheduling.d.cts +1763 -328
- package/dist/solutions/work-item/scheduling.d.ts +1763 -328
- package/dist/solutions/work-item/scheduling.js +117 -3
- package/dist/solutions/work-item/work-queue.d.cts +7 -7
- package/dist/solutions/work-item/work-queue.d.ts +7 -7
- package/dist/sources/browser.cjs +1318 -1083
- package/dist/sources/browser.cjs.map +1 -1
- package/dist/sources/browser.d.cts +22 -6
- package/dist/sources/browser.d.ts +22 -6
- package/dist/sources/browser.js +4 -4
- package/dist/sources/browser.js.map +1 -1
- package/dist/sources/index.cjs +1318 -1083
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.d.cts +4 -4
- package/dist/sources/index.d.ts +4 -4
- package/dist/sources/index.js +4 -4
- package/dist/sources/node.d.cts +3 -3
- package/dist/sources/node.d.ts +3 -3
- package/dist/storage/browser.cjs +16 -0
- package/dist/storage/browser.cjs.map +1 -1
- package/dist/storage/browser.js +3 -3
- package/dist/storage/index.cjs +16 -0
- package/dist/storage/index.cjs.map +1 -1
- package/dist/storage/index.d.cts +5 -4
- package/dist/storage/index.d.ts +5 -4
- package/dist/storage/index.js +6 -6
- package/dist/storage/node.cjs +16 -0
- package/dist/storage/node.cjs.map +1 -1
- package/dist/storage/node.js +3 -3
- package/dist/{store-C-joM4gh.d.ts → store-6_CHF6Ge.d.ts} +1 -1
- package/dist/{store-CNJwmT-h.d.cts → store-BljX8RkQ.d.cts} +1 -1
- package/dist/types-BAw2QVVE.d.cts +274 -0
- package/dist/types-BUbbbh4f.d.cts +34 -0
- package/dist/types-CMnzoL54.d.cts +457 -0
- package/dist/{types-CcPIn7sy.d.cts → types-CTN3XoMl.d.cts} +57 -108
- package/dist/types-CV_ohy5T.d.cts +357 -0
- package/dist/{types-BsJvElYZ.d.ts → types-DChxk1vK.d.ts} +57 -108
- package/dist/types-DRu7SnLV.d.ts +274 -0
- package/dist/types-DeID_FRl.d.ts +34 -0
- package/dist/types-IhKH0hGW.d.ts +357 -0
- package/dist/types-ePlD2uyT.d.ts +457 -0
- package/dist/{work-item-runtime-qaVgsL0T.d.cts → work-item-runtime-types-BTxLskN5.d.cts} +3 -93
- package/dist/{work-item-runtime-C3M79vE9.d.ts → work-item-runtime-types-DAsZbb2y.d.ts} +3 -93
- package/dist/work-queue/index.cjs +957 -953
- package/dist/work-queue/index.cjs.map +1 -1
- package/dist/work-queue/index.d.cts +9 -357
- package/dist/work-queue/index.d.ts +9 -357
- package/dist/work-queue/index.js +957 -953
- package/dist/work-queue/index.js.map +1 -1
- package/package.json +611 -513
- package/dist/chunk-3JR3EDB2.js.map +0 -1
- package/dist/chunk-4VLAQHZI.js.map +0 -1
- package/dist/chunk-6XAIOL3X.js +0 -2407
- package/dist/chunk-6XAIOL3X.js.map +0 -1
- package/dist/chunk-FBUU43PM.js.map +0 -1
- package/dist/chunk-HKK2JD7Z.js.map +0 -1
- package/dist/chunk-PC3BTTBE.js +0 -3217
- package/dist/chunk-PC3BTTBE.js.map +0 -1
- package/dist/chunk-QFY4AFY4.js.map +0 -1
- package/dist/chunk-SS2A464I.js.map +0 -1
- package/dist/chunk-V7CIJE4B.js.map +0 -1
- package/dist/chunk-XKXWK2KP.js.map +0 -1
- package/dist/chunk-YDSIVHRR.js.map +0 -1
- package/dist/chunk-YXMZ2N6J.js.map +0 -1
- /package/dist/{chunk-CZNV3VXM.js.map → chunk-3J7UPZL5.js.map} +0 -0
- /package/dist/{chunk-Z2ANQ6JW.js.map → chunk-4Q77MMJY.js.map} +0 -0
- /package/dist/{chunk-K3FXTC3I.js.map → chunk-HJACH5PU.js.map} +0 -0
- /package/dist/{chunk-GTPCOEOZ.js.map → chunk-IDMLXLLG.js.map} +0 -0
- /package/dist/{chunk-DKP56CSW.js.map → chunk-JKAYLDQV.js.map} +0 -0
- /package/dist/{chunk-43BKLFZU.js.map → chunk-KFURM6FM.js.map} +0 -0
- /package/dist/{chunk-2747WN4Y.js.map → chunk-PUSRRALM.js.map} +0 -0
- /package/dist/{chunk-VTHLCFN4.js.map → chunk-RAHNUYA5.js.map} +0 -0
- /package/dist/{chunk-IXZBUWSP.js.map → chunk-UEMN5URK.js.map} +0 -0
- /package/dist/{chunk-6PHB5CJS.js.map → chunk-ZLFRB6FI.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Node
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-GXU6WFEJ.js";
|
|
4
4
|
import {
|
|
5
5
|
depLatest
|
|
6
6
|
} from "./chunk-WQIA3GFB.js";
|
|
@@ -8,12 +8,7 @@ import {
|
|
|
8
8
|
errorPayload
|
|
9
9
|
} from "./chunk-S6HXABGL.js";
|
|
10
10
|
|
|
11
|
-
// src/solutions/reactive-layout/
|
|
12
|
-
var TEXT_SEGMENTS_MEASUREMENT_KIND = "text-segments";
|
|
13
|
-
var BLOCKS_MEASUREMENT_KIND = "blocks";
|
|
14
|
-
var READINESS_MEASUREMENT_KIND = "readiness";
|
|
15
|
-
var IMAGE_SIZE_MEASUREMENT_KIND = "image-size";
|
|
16
|
-
var SVG_BOUNDS_MEASUREMENT_KIND = "svg-bounds";
|
|
11
|
+
// src/solutions/reactive-layout/segment.ts
|
|
17
12
|
var kinsokuStart = /* @__PURE__ */ new Set([
|
|
18
13
|
"\u3001",
|
|
19
14
|
"\u3002",
|
|
@@ -159,6 +154,43 @@ function measuredWidth(value) {
|
|
|
159
154
|
function metricKey(text, font) {
|
|
160
155
|
return `${font}\0${text}`;
|
|
161
156
|
}
|
|
157
|
+
|
|
158
|
+
// src/solutions/reactive-layout/utils.ts
|
|
159
|
+
function nonNegativeFinite(value, fallback) {
|
|
160
|
+
return Number.isFinite(value) ? Math.max(0, value) : fallback;
|
|
161
|
+
}
|
|
162
|
+
function finiteNumber(value, fallback) {
|
|
163
|
+
return Number.isFinite(value) ? value : fallback;
|
|
164
|
+
}
|
|
165
|
+
function emitLayoutError(ctx, error, fallback) {
|
|
166
|
+
ctx.down([["ERROR", errorPayload(error, fallback)]]);
|
|
167
|
+
}
|
|
168
|
+
function positiveFinite(value, fallback) {
|
|
169
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
170
|
+
}
|
|
171
|
+
function clampDimension(value) {
|
|
172
|
+
return nonNegativeFinite(value ?? 0, 0);
|
|
173
|
+
}
|
|
174
|
+
function fitSize(size, maxWidth) {
|
|
175
|
+
const width = nonNegativeFinite(size.width, 0);
|
|
176
|
+
const height = nonNegativeFinite(size.height, 0);
|
|
177
|
+
if (width === 0 || maxWidth <= 0 || width <= maxWidth) return { width, height };
|
|
178
|
+
const scale = maxWidth / width;
|
|
179
|
+
return { width: maxWidth, height: height * scale };
|
|
180
|
+
}
|
|
181
|
+
function blockMaxWidth(blockMaxWidth2, maxWidth) {
|
|
182
|
+
const own = blockMaxWidth2 === void 0 ? maxWidth : nonNegativeFinite(blockMaxWidth2, maxWidth);
|
|
183
|
+
if (maxWidth <= 0) return own;
|
|
184
|
+
if (own <= 0) return maxWidth;
|
|
185
|
+
return Math.min(own, maxWidth);
|
|
186
|
+
}
|
|
187
|
+
function resolveTextAdapter(opts) {
|
|
188
|
+
const adapter = opts.adapters?.text ?? opts.adapter;
|
|
189
|
+
if (!adapter) throw new Error("Text blocks require a MeasurementAdapter");
|
|
190
|
+
return adapter;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// src/solutions/reactive-layout/adapters.ts
|
|
162
194
|
var InjectedMeasureAdapter = class {
|
|
163
195
|
measure;
|
|
164
196
|
shouldCache;
|
|
@@ -289,1075 +321,1055 @@ function isImageSizeLookup(value) {
|
|
|
289
321
|
if (valueType !== "object" && valueType !== "function") return false;
|
|
290
322
|
return typeof value.get === "function";
|
|
291
323
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
source: opts.source,
|
|
299
|
-
subjectId: targetId,
|
|
300
|
-
measurementKind,
|
|
301
|
-
details: opts.details,
|
|
302
|
-
metadata: opts.metadata
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
function measurementOk(targetId, measurementKind, value, opts = {}) {
|
|
306
|
-
return {
|
|
307
|
-
kind: "ok",
|
|
308
|
-
targetId,
|
|
309
|
-
measurementKind,
|
|
310
|
-
value,
|
|
311
|
-
source: opts.source,
|
|
312
|
-
metadata: opts.metadata
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
function latestMeasurementValue(measurements, targetId, measurementKind) {
|
|
316
|
-
let value;
|
|
317
|
-
for (const fact of measurements) {
|
|
318
|
-
if (fact.kind === "ok" && fact.targetId === targetId && fact.measurementKind === measurementKind) {
|
|
319
|
-
value = fact.value;
|
|
320
|
-
}
|
|
324
|
+
|
|
325
|
+
// src/solutions/reactive-layout/line.ts
|
|
326
|
+
function analyzeAndMeasure(text, font, adapter, cache, stats, segmentAdapter) {
|
|
327
|
+
const normalized = normalizeWhitespace(text);
|
|
328
|
+
if (normalized.length === 0) {
|
|
329
|
+
return [];
|
|
321
330
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
331
|
+
const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
|
|
332
|
+
const pieces = segmentText(normalized, segAdapter);
|
|
333
|
+
const rawTexts = [];
|
|
334
|
+
const rawKinds = [];
|
|
335
|
+
const rawWordLike = [];
|
|
336
|
+
for (const piece of pieces) {
|
|
337
|
+
for (let i = 0; i < piece.texts.length; i += 1) {
|
|
338
|
+
rawTexts.push(piece.texts[i]);
|
|
339
|
+
rawKinds.push(piece.kinds[i]);
|
|
340
|
+
rawWordLike.push(piece.isWordLike[i]);
|
|
341
|
+
}
|
|
329
342
|
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
343
|
+
const mergedTexts = [];
|
|
344
|
+
const mergedKinds = [];
|
|
345
|
+
const mergedWordLike = [];
|
|
346
|
+
for (let i = 0; i < rawTexts.length; i += 1) {
|
|
347
|
+
const t = rawTexts[i];
|
|
348
|
+
const k = rawKinds[i];
|
|
349
|
+
const wl = rawWordLike[i];
|
|
350
|
+
if (k === "text" && !wl && mergedTexts.length > 0 && mergedKinds[mergedTexts.length - 1] === "text") {
|
|
351
|
+
const isSticky = t.length === 1 && (leftStickyPunctuation.has(t) || kinsokuStart.has(t));
|
|
352
|
+
if (isSticky) {
|
|
353
|
+
mergedTexts[mergedTexts.length - 1] += t;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
if (t === "-" && mergedTexts.length > 0 && mergedKinds[mergedKinds.length - 1] === "text" && mergedWordLike[mergedWordLike.length - 1]) {
|
|
358
|
+
mergedTexts[mergedTexts.length - 1] += t;
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
mergedTexts.push(t);
|
|
362
|
+
mergedKinds.push(k);
|
|
363
|
+
mergedWordLike.push(wl);
|
|
334
364
|
}
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
hyphenWidth === void 0 ? { segments } : { segments, hyphenWidth },
|
|
346
|
-
{ source }
|
|
347
|
-
)
|
|
348
|
-
];
|
|
349
|
-
if (hyphenWidth === void 0) {
|
|
350
|
-
facts.push(
|
|
351
|
-
measurementIssue(
|
|
352
|
-
"measurement.hyphen.failed",
|
|
353
|
-
`Hyphen measurement failed for '${targetId}'`,
|
|
354
|
-
targetId,
|
|
355
|
-
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
356
|
-
{ source, severity: "warning" }
|
|
357
|
-
)
|
|
358
|
-
);
|
|
365
|
+
const fontCache = cache.get(font) ?? /* @__PURE__ */ new Map();
|
|
366
|
+
if (!cache.has(font)) cache.set(font, fontCache);
|
|
367
|
+
function measureCached(segment) {
|
|
368
|
+
const cached = fontCache.get(segment);
|
|
369
|
+
if (cached === void 0) {
|
|
370
|
+
if (stats) stats.misses += 1;
|
|
371
|
+
const measured = adapter.measureSegment(segment, font).width;
|
|
372
|
+
const width = Number.isFinite(measured) && measured >= 0 ? measured : 0;
|
|
373
|
+
fontCache.set(segment, width);
|
|
374
|
+
return width;
|
|
359
375
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
return [
|
|
363
|
-
measurementIssue(
|
|
364
|
-
"measurement.failed",
|
|
365
|
-
`Text measurement failed for '${targetId}'`,
|
|
366
|
-
targetId,
|
|
367
|
-
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
368
|
-
{ source, details: error, severity: "error" }
|
|
369
|
-
)
|
|
370
|
-
];
|
|
376
|
+
if (stats) stats.hits += 1;
|
|
377
|
+
return cached;
|
|
371
378
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
379
|
+
const out = [];
|
|
380
|
+
for (let i = 0; i < mergedTexts.length; i += 1) {
|
|
381
|
+
const t = mergedTexts[i];
|
|
382
|
+
const kind = mergedKinds[i];
|
|
383
|
+
if (kind !== "text") {
|
|
384
|
+
out.push({
|
|
385
|
+
text: t,
|
|
386
|
+
width: kind === "space" ? measureCached(" ") * t.length : 0,
|
|
387
|
+
kind,
|
|
388
|
+
graphemeWidths: null
|
|
389
|
+
});
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
if (isCJK(t)) {
|
|
393
|
+
let unitText = "";
|
|
394
|
+
for (const graphemeSegment of segAdapter.segmentGraphemes(t)) {
|
|
395
|
+
const grapheme = graphemeSegment.segment;
|
|
396
|
+
if (unitText.length > 0 && kinsokuStart.has(grapheme)) {
|
|
397
|
+
unitText += grapheme;
|
|
398
|
+
continue;
|
|
381
399
|
}
|
|
382
|
-
|
|
400
|
+
if (unitText.length > 0) {
|
|
401
|
+
out.push({
|
|
402
|
+
text: unitText,
|
|
403
|
+
width: measureCached(unitText),
|
|
404
|
+
kind: "text",
|
|
405
|
+
graphemeWidths: null
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
unitText = grapheme;
|
|
383
409
|
}
|
|
384
|
-
|
|
410
|
+
if (unitText.length > 0) {
|
|
411
|
+
out.push({
|
|
412
|
+
text: unitText,
|
|
413
|
+
width: measureCached(unitText),
|
|
414
|
+
kind: "text",
|
|
415
|
+
graphemeWidths: null
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
const textWidth = measureCached(t);
|
|
421
|
+
let graphemeWidths = null;
|
|
422
|
+
if (mergedWordLike[i] && t.length > 1) {
|
|
423
|
+
const widths = [];
|
|
424
|
+
for (const grapheme of segAdapter.segmentGraphemes(t)) {
|
|
425
|
+
widths.push(measureCached(grapheme.segment));
|
|
426
|
+
}
|
|
427
|
+
if (widths.length > 1) graphemeWidths = widths;
|
|
428
|
+
}
|
|
429
|
+
out.push({
|
|
430
|
+
text: t,
|
|
431
|
+
width: textWidth,
|
|
432
|
+
kind: "text",
|
|
433
|
+
graphemeWidths
|
|
434
|
+
});
|
|
385
435
|
}
|
|
386
|
-
|
|
387
|
-
return { node: state, set: (value) => state.set(value) };
|
|
388
|
-
}
|
|
389
|
-
function scopedName(scope, local) {
|
|
390
|
-
return scope === local ? local : `${scope}:${local}`;
|
|
436
|
+
return out;
|
|
391
437
|
}
|
|
392
|
-
function
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
const segmentAdapter = opts.segmentAdapter === void 0 ? getDefaultSegmentAdapter() : depLatest(ctx, 3);
|
|
415
|
-
ctx.down([
|
|
416
|
-
[
|
|
417
|
-
"DATA",
|
|
418
|
-
textMeasurementFacts(text, font, adapter, cache, segmentAdapter, targetId, source)
|
|
419
|
-
]
|
|
420
|
-
]);
|
|
421
|
-
},
|
|
422
|
-
{ name }
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
function injectedTextMeasurements(opts) {
|
|
426
|
-
const targetId = opts.targetId ?? "text";
|
|
427
|
-
const adapter = opts.graph.state(
|
|
428
|
-
new InjectedMeasureAdapter(opts.measure, { cache: opts.cache }),
|
|
429
|
-
{
|
|
430
|
-
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
438
|
+
function computeLineBreaks(segments, maxWidth, opts = {}) {
|
|
439
|
+
if (segments.length === 0) return { lines: [], lineCount: 0 };
|
|
440
|
+
const segAdapter = opts.segmentAdapter ?? getDefaultSegmentAdapter();
|
|
441
|
+
const lines = [];
|
|
442
|
+
let cursor = { segmentIndex: 0, graphemeIndex: 0 };
|
|
443
|
+
while (cursor.segmentIndex < segments.length) {
|
|
444
|
+
const next = layoutNextLine(segments, cursor, maxWidth, {
|
|
445
|
+
hyphenWidth: opts.hyphenWidth,
|
|
446
|
+
segmentAdapter: segAdapter
|
|
447
|
+
});
|
|
448
|
+
if (next === null) break;
|
|
449
|
+
lines.push({
|
|
450
|
+
text: next.text,
|
|
451
|
+
width: next.width,
|
|
452
|
+
startSegment: next.start.segmentIndex,
|
|
453
|
+
startGrapheme: next.start.graphemeIndex,
|
|
454
|
+
endSegment: next.end.segmentIndex,
|
|
455
|
+
endGrapheme: next.end.graphemeIndex
|
|
456
|
+
});
|
|
457
|
+
if (next.end.segmentIndex === cursor.segmentIndex && next.end.graphemeIndex === cursor.graphemeIndex) {
|
|
458
|
+
break;
|
|
431
459
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
adapter,
|
|
436
|
-
source: opts.source ?? "injectedTextMeasurements"
|
|
437
|
-
});
|
|
460
|
+
cursor = next.end;
|
|
461
|
+
}
|
|
462
|
+
return { lines, lineCount: lines.length };
|
|
438
463
|
}
|
|
439
|
-
function
|
|
440
|
-
|
|
441
|
-
const adapter = opts.graph.state(new PrecomputedMeasureAdapter(opts), {
|
|
442
|
-
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
443
|
-
});
|
|
444
|
-
return textMeasurementProvider({
|
|
445
|
-
...opts,
|
|
446
|
-
adapter,
|
|
447
|
-
source: opts.source ?? "precomputedTextMeasurements"
|
|
448
|
-
});
|
|
464
|
+
function canBreakAfter(kind) {
|
|
465
|
+
return kind === "space" || kind === "zero-width-break" || kind === "soft-hyphen";
|
|
449
466
|
}
|
|
450
|
-
function
|
|
451
|
-
|
|
452
|
-
const
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
return textMeasurementProvider({
|
|
456
|
-
...opts,
|
|
457
|
-
adapter,
|
|
458
|
-
source: opts.source ?? "cellTextMeasurements"
|
|
459
|
-
});
|
|
467
|
+
function sliceSegmentText(seg, startGrapheme, endGrapheme, segmentAdapter) {
|
|
468
|
+
if (startGrapheme === 0 && endGrapheme < 0) return seg.text;
|
|
469
|
+
const graphemes = [...segmentAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
|
|
470
|
+
const stop = endGrapheme < 0 ? graphemes.length : endGrapheme;
|
|
471
|
+
return graphemes.slice(startGrapheme, stop).join("");
|
|
460
472
|
}
|
|
461
|
-
function
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
[
|
|
465
|
-
(
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
{
|
|
471
|
-
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
473
|
+
function buildLineText(segments, startSegment, startGrapheme, endSegment, endGrapheme, appendHyphen, segmentAdapter) {
|
|
474
|
+
let text = "";
|
|
475
|
+
for (let i = startSegment; i < endSegment; i += 1) {
|
|
476
|
+
const seg = segments[i];
|
|
477
|
+
if (seg.kind === "soft-hyphen" || seg.kind === "hard-break") continue;
|
|
478
|
+
if (i === startSegment && startGrapheme > 0) {
|
|
479
|
+
text += sliceSegmentText(seg, startGrapheme, -1, segmentAdapter);
|
|
480
|
+
} else {
|
|
481
|
+
text += seg.text;
|
|
472
482
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
483
|
+
}
|
|
484
|
+
if (endGrapheme > 0 && endSegment < segments.length) {
|
|
485
|
+
const seg = segments[endSegment];
|
|
486
|
+
const from = startSegment === endSegment ? startGrapheme : 0;
|
|
487
|
+
text += sliceSegmentText(seg, from, endGrapheme, segmentAdapter);
|
|
488
|
+
}
|
|
489
|
+
if (appendHyphen) text += "-";
|
|
490
|
+
return text;
|
|
479
491
|
}
|
|
480
|
-
function
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
const
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
(
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
492
|
+
function resolveHyphenWidth(ctx) {
|
|
493
|
+
if (ctx?.hyphenWidth !== void 0) return nonNegativeFinite(ctx.hyphenWidth, 0);
|
|
494
|
+
if (ctx?.adapter === void 0 || ctx.font === void 0) return 0;
|
|
495
|
+
const cache = ctx.cache;
|
|
496
|
+
if (cache) {
|
|
497
|
+
let fontCache = cache.get(ctx.font);
|
|
498
|
+
if (fontCache === void 0) {
|
|
499
|
+
fontCache = /* @__PURE__ */ new Map();
|
|
500
|
+
cache.set(ctx.font, fontCache);
|
|
501
|
+
}
|
|
502
|
+
let width = fontCache.get("-");
|
|
503
|
+
if (width === void 0) {
|
|
504
|
+
width = ctx.adapter.measureSegment("-", ctx.font).width;
|
|
505
|
+
fontCache.set("-", width);
|
|
506
|
+
}
|
|
507
|
+
return width;
|
|
508
|
+
}
|
|
509
|
+
return ctx.adapter.measureSegment("-", ctx.font).width;
|
|
510
|
+
}
|
|
511
|
+
function layoutNextLine(segments, cursor, slotWidth, ctx) {
|
|
512
|
+
let i = cursor.segmentIndex;
|
|
513
|
+
const initialGrapheme = cursor.graphemeIndex;
|
|
514
|
+
const segmentAdapter = ctx?.segmentAdapter ?? getDefaultSegmentAdapter();
|
|
515
|
+
if (i >= segments.length) return null;
|
|
516
|
+
if (initialGrapheme === 0) {
|
|
517
|
+
while (i < segments.length) {
|
|
518
|
+
const seg = segments[i];
|
|
519
|
+
if (seg.kind === "hard-break") {
|
|
520
|
+
return {
|
|
521
|
+
text: "",
|
|
522
|
+
width: 0,
|
|
523
|
+
start: { segmentIndex: cursor.segmentIndex, graphemeIndex: 0 },
|
|
524
|
+
end: { segmentIndex: i + 1, graphemeIndex: 0 }
|
|
525
|
+
};
|
|
503
526
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
activeReadiness = readiness;
|
|
527
|
+
if (seg.kind === "space" || seg.kind === "zero-width-break" || seg.kind === "soft-hyphen") {
|
|
528
|
+
i += 1;
|
|
529
|
+
continue;
|
|
508
530
|
}
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
531
|
+
break;
|
|
532
|
+
}
|
|
533
|
+
if (i >= segments.length) return null;
|
|
534
|
+
}
|
|
535
|
+
const hyphenWidth = resolveHyphenWidth(ctx);
|
|
536
|
+
const startSegment = i;
|
|
537
|
+
const startGrapheme = i === cursor.segmentIndex ? initialGrapheme : 0;
|
|
538
|
+
let lineW = 0;
|
|
539
|
+
let lineEndSegment = startSegment;
|
|
540
|
+
let lineEndGrapheme = 0;
|
|
541
|
+
let hasContent = false;
|
|
542
|
+
let pendingBreakSegment = -1;
|
|
543
|
+
let pendingBreakGrapheme = 0;
|
|
544
|
+
let pendingBreakWidth = 0;
|
|
545
|
+
let pendingBreakSoftHyphen = false;
|
|
546
|
+
const recordPending = (sIdx, gIdx, width, kind) => {
|
|
547
|
+
pendingBreakSegment = sIdx;
|
|
548
|
+
pendingBreakGrapheme = gIdx;
|
|
549
|
+
pendingBreakWidth = width;
|
|
550
|
+
pendingBreakSoftHyphen = kind === "soft-hyphen";
|
|
551
|
+
};
|
|
552
|
+
const consumeBreakable = (segIdx, startG, widths) => {
|
|
553
|
+
for (let g = startG; g < widths.length; g += 1) {
|
|
554
|
+
const gw = widths[g];
|
|
555
|
+
if (!hasContent) {
|
|
556
|
+
lineW = gw;
|
|
557
|
+
lineEndSegment = segIdx;
|
|
558
|
+
lineEndGrapheme = g + 1;
|
|
559
|
+
hasContent = true;
|
|
560
|
+
continue;
|
|
530
561
|
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
[
|
|
534
|
-
"DATA",
|
|
535
|
-
textMeasurementFacts(text, font, adapter, cache, segmentAdapter, targetId, source)
|
|
536
|
-
]
|
|
537
|
-
]);
|
|
538
|
-
},
|
|
539
|
-
{ name }
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
|
-
function readinessMeasurements(opts) {
|
|
543
|
-
const targetId = opts.targetId ?? "measurement-readiness";
|
|
544
|
-
const measurementKind = opts.measurementKind ?? READINESS_MEASUREMENT_KIND;
|
|
545
|
-
const name = opts.name ?? `${targetId}-measurements`;
|
|
546
|
-
const source = opts.source ?? name;
|
|
547
|
-
return opts.graph.node(
|
|
548
|
-
[opts.readiness],
|
|
549
|
-
(ctx) => {
|
|
550
|
-
const readiness = depLatest(ctx, 0);
|
|
551
|
-
if (!readiness.ready) {
|
|
552
|
-
ctx.down([
|
|
553
|
-
[
|
|
554
|
-
"DATA",
|
|
555
|
-
[
|
|
556
|
-
measurementIssue(
|
|
557
|
-
readiness.code ?? "measurement.not-ready",
|
|
558
|
-
readiness.message ?? `Measurement readiness blocked '${targetId}'`,
|
|
559
|
-
targetId,
|
|
560
|
-
measurementKind,
|
|
561
|
-
{
|
|
562
|
-
source: readiness.source ?? source,
|
|
563
|
-
details: readiness.details,
|
|
564
|
-
metadata: readiness.metadata,
|
|
565
|
-
severity: "warning"
|
|
566
|
-
}
|
|
567
|
-
)
|
|
568
|
-
]
|
|
569
|
-
]
|
|
570
|
-
]);
|
|
571
|
-
return;
|
|
562
|
+
if (lineW + gw > slotWidth + 1e-3) {
|
|
563
|
+
return true;
|
|
572
564
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
facts.push(
|
|
604
|
-
measurementOk(
|
|
605
|
-
subjectId,
|
|
606
|
-
measurementKind,
|
|
607
|
-
validMeasurementSize(measurer.measureImage(image.src), "image"),
|
|
608
|
-
{
|
|
609
|
-
source,
|
|
610
|
-
metadata: image.metadata
|
|
611
|
-
}
|
|
612
|
-
)
|
|
613
|
-
);
|
|
614
|
-
} catch (error) {
|
|
615
|
-
facts.push(
|
|
616
|
-
measurementIssue(
|
|
617
|
-
"measurement.image-size.failed",
|
|
618
|
-
`Image size measurement failed for '${subjectId}'`,
|
|
619
|
-
subjectId,
|
|
620
|
-
measurementKind,
|
|
621
|
-
{
|
|
622
|
-
source,
|
|
623
|
-
details: { error, index: i, src: image?.src },
|
|
624
|
-
metadata: image?.metadata,
|
|
625
|
-
severity: "error"
|
|
626
|
-
}
|
|
627
|
-
)
|
|
628
|
-
);
|
|
629
|
-
}
|
|
565
|
+
lineW += gw;
|
|
566
|
+
lineEndSegment = segIdx;
|
|
567
|
+
lineEndGrapheme = g + 1;
|
|
568
|
+
}
|
|
569
|
+
if (lineEndSegment === segIdx && lineEndGrapheme === widths.length) {
|
|
570
|
+
lineEndSegment = segIdx + 1;
|
|
571
|
+
lineEndGrapheme = 0;
|
|
572
|
+
}
|
|
573
|
+
return false;
|
|
574
|
+
};
|
|
575
|
+
if (startGrapheme > 0 && startSegment < segments.length) {
|
|
576
|
+
const seg = segments[startSegment];
|
|
577
|
+
if (seg.graphemeWidths) {
|
|
578
|
+
const overflow = consumeBreakable(startSegment, startGrapheme, seg.graphemeWidths);
|
|
579
|
+
if (overflow) {
|
|
580
|
+
const text2 = buildLineText(
|
|
581
|
+
segments,
|
|
582
|
+
startSegment,
|
|
583
|
+
startGrapheme,
|
|
584
|
+
lineEndSegment,
|
|
585
|
+
lineEndGrapheme,
|
|
586
|
+
false,
|
|
587
|
+
segmentAdapter
|
|
588
|
+
);
|
|
589
|
+
return {
|
|
590
|
+
text: text2,
|
|
591
|
+
width: lineW,
|
|
592
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
593
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
594
|
+
};
|
|
630
595
|
}
|
|
631
|
-
|
|
632
|
-
}
|
|
633
|
-
|
|
634
|
-
)
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
)
|
|
596
|
+
i = lineEndSegment;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
for (; i < segments.length; i += 1) {
|
|
600
|
+
const seg = segments[i];
|
|
601
|
+
if (seg.kind === "hard-break") {
|
|
602
|
+
if (hasContent) {
|
|
603
|
+
const endsAtSoftHyphen2 = lineEndSegment > 0 && segments[lineEndSegment - 1]?.kind === "soft-hyphen";
|
|
604
|
+
const text2 = buildLineText(
|
|
605
|
+
segments,
|
|
606
|
+
startSegment,
|
|
607
|
+
startGrapheme,
|
|
608
|
+
lineEndSegment,
|
|
609
|
+
lineEndGrapheme,
|
|
610
|
+
endsAtSoftHyphen2,
|
|
611
|
+
segmentAdapter
|
|
612
|
+
);
|
|
613
|
+
return {
|
|
614
|
+
text: text2,
|
|
615
|
+
width: lineW + (endsAtSoftHyphen2 ? hyphenWidth : 0),
|
|
616
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
617
|
+
end: { segmentIndex: i + 1, graphemeIndex: 0 }
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
return {
|
|
621
|
+
text: "",
|
|
622
|
+
width: 0,
|
|
623
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
624
|
+
end: { segmentIndex: i + 1, graphemeIndex: 0 }
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
const w = seg.width;
|
|
628
|
+
if (!hasContent) {
|
|
629
|
+
if (w > slotWidth && seg.graphemeWidths) {
|
|
630
|
+
const overflow = consumeBreakable(i, 0, seg.graphemeWidths);
|
|
631
|
+
if (overflow) {
|
|
632
|
+
const text2 = buildLineText(
|
|
633
|
+
segments,
|
|
634
|
+
startSegment,
|
|
635
|
+
startGrapheme,
|
|
636
|
+
lineEndSegment,
|
|
637
|
+
lineEndGrapheme,
|
|
638
|
+
false,
|
|
639
|
+
segmentAdapter
|
|
676
640
|
);
|
|
641
|
+
return {
|
|
642
|
+
text: text2,
|
|
643
|
+
width: lineW,
|
|
644
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
645
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
646
|
+
};
|
|
677
647
|
}
|
|
648
|
+
i = lineEndSegment - 1;
|
|
649
|
+
continue;
|
|
678
650
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
651
|
+
lineW = w;
|
|
652
|
+
lineEndSegment = i + 1;
|
|
653
|
+
lineEndGrapheme = 0;
|
|
654
|
+
hasContent = true;
|
|
655
|
+
if (canBreakAfter(seg.kind)) {
|
|
656
|
+
recordPending(i + 1, 0, seg.kind === "space" ? lineW - w : lineW, seg.kind);
|
|
657
|
+
}
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
const projectedWidth = lineW + w;
|
|
661
|
+
if (projectedWidth > slotWidth + 1e-3) {
|
|
662
|
+
if (canBreakAfter(seg.kind)) {
|
|
663
|
+
lineEndSegment = i + 1;
|
|
664
|
+
lineEndGrapheme = 0;
|
|
665
|
+
const endsAtSoftHyphen2 = seg.kind === "soft-hyphen";
|
|
666
|
+
const text3 = buildLineText(
|
|
667
|
+
segments,
|
|
668
|
+
startSegment,
|
|
669
|
+
startGrapheme,
|
|
670
|
+
lineEndSegment,
|
|
671
|
+
lineEndGrapheme,
|
|
672
|
+
endsAtSoftHyphen2,
|
|
673
|
+
segmentAdapter
|
|
674
|
+
);
|
|
675
|
+
return {
|
|
676
|
+
text: text3,
|
|
677
|
+
width: seg.kind === "space" ? lineW : lineW + (endsAtSoftHyphen2 ? hyphenWidth : 0),
|
|
678
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
679
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
if (pendingBreakSegment >= 0) {
|
|
683
|
+
const text3 = buildLineText(
|
|
684
|
+
segments,
|
|
685
|
+
startSegment,
|
|
686
|
+
startGrapheme,
|
|
687
|
+
pendingBreakSegment,
|
|
688
|
+
pendingBreakGrapheme,
|
|
689
|
+
pendingBreakSoftHyphen,
|
|
690
|
+
segmentAdapter
|
|
691
|
+
);
|
|
692
|
+
return {
|
|
693
|
+
text: text3,
|
|
694
|
+
width: pendingBreakWidth + (pendingBreakSoftHyphen ? hyphenWidth : 0),
|
|
695
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
696
|
+
end: { segmentIndex: pendingBreakSegment, graphemeIndex: pendingBreakGrapheme }
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
if (w > slotWidth && seg.graphemeWidths) {
|
|
700
|
+
const text3 = buildLineText(
|
|
701
|
+
segments,
|
|
702
|
+
startSegment,
|
|
703
|
+
startGrapheme,
|
|
704
|
+
lineEndSegment,
|
|
705
|
+
lineEndGrapheme,
|
|
706
|
+
false,
|
|
707
|
+
segmentAdapter
|
|
708
|
+
);
|
|
709
|
+
return {
|
|
710
|
+
text: text3,
|
|
711
|
+
width: lineW,
|
|
712
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
713
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
714
|
+
};
|
|
692
715
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
deps.push(opts.svg);
|
|
708
|
-
}
|
|
709
|
-
if (opts.image) {
|
|
710
|
-
positions.image = deps.length;
|
|
711
|
-
deps.push(opts.image);
|
|
712
|
-
}
|
|
713
|
-
return opts.graph.node(
|
|
714
|
-
deps,
|
|
715
|
-
(ctx) => {
|
|
716
|
-
const adapters = {
|
|
717
|
-
text: positions.text === void 0 ? void 0 : depLatest(ctx, positions.text),
|
|
718
|
-
svg: positions.svg === void 0 ? void 0 : depLatest(ctx, positions.svg),
|
|
719
|
-
image: positions.image === void 0 ? void 0 : depLatest(ctx, positions.image)
|
|
716
|
+
const text2 = buildLineText(
|
|
717
|
+
segments,
|
|
718
|
+
startSegment,
|
|
719
|
+
startGrapheme,
|
|
720
|
+
lineEndSegment,
|
|
721
|
+
lineEndGrapheme,
|
|
722
|
+
false,
|
|
723
|
+
segmentAdapter
|
|
724
|
+
);
|
|
725
|
+
return {
|
|
726
|
+
text: text2,
|
|
727
|
+
width: lineW,
|
|
728
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
729
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
720
730
|
};
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
731
|
+
}
|
|
732
|
+
lineW = projectedWidth;
|
|
733
|
+
lineEndSegment = i + 1;
|
|
734
|
+
lineEndGrapheme = 0;
|
|
735
|
+
if (canBreakAfter(seg.kind)) {
|
|
736
|
+
recordPending(i + 1, 0, seg.kind === "space" ? lineW - w : lineW, seg.kind);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
if (!hasContent) return null;
|
|
740
|
+
const endsAtSoftHyphen = lineEndSegment > 0 && segments[lineEndSegment - 1]?.kind === "soft-hyphen";
|
|
741
|
+
const text = buildLineText(
|
|
742
|
+
segments,
|
|
743
|
+
startSegment,
|
|
744
|
+
startGrapheme,
|
|
745
|
+
lineEndSegment,
|
|
746
|
+
lineEndGrapheme,
|
|
747
|
+
endsAtSoftHyphen,
|
|
748
|
+
segmentAdapter
|
|
724
749
|
);
|
|
750
|
+
return {
|
|
751
|
+
text,
|
|
752
|
+
width: lineW + (endsAtSoftHyphen ? hyphenWidth : 0),
|
|
753
|
+
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
754
|
+
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
755
|
+
};
|
|
725
756
|
}
|
|
726
|
-
function
|
|
727
|
-
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
if (opts.lineHeight) deps.push(opts.lineHeight);
|
|
735
|
-
if (opts.segmentAdapter) deps.push(opts.segmentAdapter);
|
|
736
|
-
return opts.graph.node(
|
|
737
|
-
deps,
|
|
738
|
-
(ctx) => {
|
|
739
|
-
const flush = () => {
|
|
740
|
-
cache.clear();
|
|
741
|
-
const adapters = depLatest(ctx, 2);
|
|
742
|
-
adapters.text?.clearCache?.();
|
|
743
|
-
};
|
|
744
|
-
ctx.onDeactivation(flush);
|
|
745
|
-
ctx.onInvalidate(flush);
|
|
746
|
-
try {
|
|
747
|
-
const blocks = depLatest(ctx, 0);
|
|
748
|
-
const maxWidth = nonNegativeFinite(depLatest(ctx, 1), 0);
|
|
749
|
-
const adapters = depLatest(ctx, 2);
|
|
750
|
-
if (adapters.text !== activeTextAdapter) {
|
|
751
|
-
cache.clear();
|
|
752
|
-
activeTextAdapter = adapters.text;
|
|
753
|
-
}
|
|
754
|
-
let depIndex = 3;
|
|
755
|
-
const font = opts.font ? depLatest(ctx, depIndex++) : void 0;
|
|
756
|
-
const lineHeight = opts.lineHeight ? nonNegativeFinite(depLatest(ctx, depIndex++), 0) : void 0;
|
|
757
|
-
const segmentAdapter = opts.segmentAdapter ? depLatest(ctx, depIndex) : getDefaultSegmentAdapter();
|
|
758
|
-
const measured = [];
|
|
759
|
-
const issues = [];
|
|
760
|
-
for (let i = 0; i < blocks.length; i += 1) {
|
|
761
|
-
const block = blocks[i];
|
|
762
|
-
const subjectId = block?.id ?? `${targetId}:${i}`;
|
|
763
|
-
try {
|
|
764
|
-
if (block === void 0) {
|
|
765
|
-
throw new Error(`Missing content block at index ${i}`);
|
|
766
|
-
}
|
|
767
|
-
const blockFont = block.kind === "text" ? block.font ?? font ?? "16px sans-serif" : void 0;
|
|
768
|
-
const hyphenWidth = block.kind === "text" && adapters.text ? tryMeasureHyphenWidth(adapters.text, blockFont ?? "16px sans-serif") : void 0;
|
|
769
|
-
measured.push(
|
|
770
|
-
measureBlock(block, {
|
|
771
|
-
adapters,
|
|
772
|
-
font,
|
|
773
|
-
hyphenWidth,
|
|
774
|
-
lineHeight,
|
|
775
|
-
maxWidth,
|
|
776
|
-
cache,
|
|
777
|
-
segmentAdapter
|
|
778
|
-
})
|
|
779
|
-
);
|
|
780
|
-
if (block.kind === "text" && adapters.text) {
|
|
781
|
-
if (hyphenWidth === void 0) {
|
|
782
|
-
issues.push(
|
|
783
|
-
measurementIssue(
|
|
784
|
-
"measurement.hyphen.failed",
|
|
785
|
-
`Hyphen measurement failed for '${subjectId}'`,
|
|
786
|
-
subjectId,
|
|
787
|
-
BLOCKS_MEASUREMENT_KIND,
|
|
788
|
-
{
|
|
789
|
-
source,
|
|
790
|
-
details: { targetId, index: i },
|
|
791
|
-
severity: "warning"
|
|
792
|
-
}
|
|
793
|
-
)
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
} catch (error) {
|
|
798
|
-
issues.push(
|
|
799
|
-
measurementIssue(
|
|
800
|
-
"measurement.block.failed",
|
|
801
|
-
`Block measurement failed for '${subjectId}'`,
|
|
802
|
-
subjectId,
|
|
803
|
-
BLOCKS_MEASUREMENT_KIND,
|
|
804
|
-
{
|
|
805
|
-
source,
|
|
806
|
-
details: { error, targetId, index: i, blockKind: block?.kind },
|
|
807
|
-
severity: "error"
|
|
808
|
-
}
|
|
809
|
-
)
|
|
810
|
-
);
|
|
811
|
-
}
|
|
812
|
-
}
|
|
813
|
-
ctx.down([
|
|
814
|
-
[
|
|
815
|
-
"DATA",
|
|
816
|
-
[
|
|
817
|
-
measurementOk(
|
|
818
|
-
targetId,
|
|
819
|
-
BLOCKS_MEASUREMENT_KIND,
|
|
820
|
-
{ blocks: measured },
|
|
821
|
-
{ source }
|
|
822
|
-
),
|
|
823
|
-
...issues
|
|
824
|
-
]
|
|
825
|
-
]
|
|
826
|
-
]);
|
|
827
|
-
} catch (error) {
|
|
828
|
-
ctx.down([
|
|
829
|
-
[
|
|
830
|
-
"DATA",
|
|
831
|
-
[
|
|
832
|
-
measurementIssue(
|
|
833
|
-
"measurement.failed",
|
|
834
|
-
`Block measurement failed for '${targetId}'`,
|
|
835
|
-
targetId,
|
|
836
|
-
BLOCKS_MEASUREMENT_KIND,
|
|
837
|
-
{ source, details: error, severity: "error" }
|
|
838
|
-
)
|
|
839
|
-
]
|
|
840
|
-
]
|
|
841
|
-
]);
|
|
757
|
+
function carveTextLineSlots(base, blocked, minSlotWidth = 0) {
|
|
758
|
+
let slots = [base];
|
|
759
|
+
for (const block of blocked) {
|
|
760
|
+
const next = [];
|
|
761
|
+
for (const slot of slots) {
|
|
762
|
+
if (block.right <= slot.left || block.left >= slot.right) {
|
|
763
|
+
next.push(slot);
|
|
764
|
+
continue;
|
|
842
765
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
);
|
|
846
|
-
}
|
|
847
|
-
function analyzeAndMeasure(text, font, adapter, cache, stats, segmentAdapter) {
|
|
848
|
-
const normalized = normalizeWhitespace(text);
|
|
849
|
-
if (normalized.length === 0) {
|
|
850
|
-
return [];
|
|
851
|
-
}
|
|
852
|
-
const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
|
|
853
|
-
const pieces = segmentText(normalized, segAdapter);
|
|
854
|
-
const rawTexts = [];
|
|
855
|
-
const rawKinds = [];
|
|
856
|
-
const rawWordLike = [];
|
|
857
|
-
for (const piece of pieces) {
|
|
858
|
-
for (let i = 0; i < piece.texts.length; i += 1) {
|
|
859
|
-
rawTexts.push(piece.texts[i]);
|
|
860
|
-
rawKinds.push(piece.kinds[i]);
|
|
861
|
-
rawWordLike.push(piece.isWordLike[i]);
|
|
766
|
+
if (block.left > slot.left) next.push({ left: slot.left, right: block.left });
|
|
767
|
+
if (block.right < slot.right) next.push({ left: block.right, right: slot.right });
|
|
862
768
|
}
|
|
769
|
+
slots = next;
|
|
863
770
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
771
|
+
if (minSlotWidth > 0) return slots.filter((slot) => slot.right - slot.left >= minSlotWidth);
|
|
772
|
+
return slots;
|
|
773
|
+
}
|
|
774
|
+
function computeCharPositions(lineBreaks, segments, lineHeight, segmentAdapter) {
|
|
775
|
+
const positions = [];
|
|
776
|
+
const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
|
|
777
|
+
for (let lineIdx = 0; lineIdx < lineBreaks.lines.length; lineIdx += 1) {
|
|
778
|
+
const line = lineBreaks.lines[lineIdx];
|
|
779
|
+
const y = lineIdx * lineHeight;
|
|
780
|
+
let x = 0;
|
|
781
|
+
for (let si = line.startSegment; si < segments.length; si += 1) {
|
|
782
|
+
const seg = segments[si];
|
|
783
|
+
if (seg.kind === "soft-hyphen" || seg.kind === "hard-break") {
|
|
784
|
+
if (si >= line.endSegment && line.endGrapheme === 0) break;
|
|
875
785
|
continue;
|
|
876
786
|
}
|
|
787
|
+
const graphemes = [...segAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
|
|
788
|
+
if (graphemes.length === 0) continue;
|
|
789
|
+
const startGrapheme = si === line.startSegment ? line.startGrapheme : 0;
|
|
790
|
+
let endGrapheme;
|
|
791
|
+
if (si < line.endSegment) {
|
|
792
|
+
endGrapheme = graphemes.length;
|
|
793
|
+
} else if (si === line.endSegment && line.endGrapheme > 0) {
|
|
794
|
+
endGrapheme = line.endGrapheme;
|
|
795
|
+
} else {
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
798
|
+
for (let g = startGrapheme; g < endGrapheme; g += 1) {
|
|
799
|
+
const width = seg.graphemeWidths ? seg.graphemeWidths[g] : seg.width / graphemes.length;
|
|
800
|
+
positions.push({ x, y, width, height: lineHeight, line: lineIdx });
|
|
801
|
+
x += width;
|
|
802
|
+
}
|
|
877
803
|
}
|
|
878
|
-
if (t === "-" && mergedTexts.length > 0 && mergedKinds[mergedKinds.length - 1] === "text" && mergedWordLike[mergedWordLike.length - 1]) {
|
|
879
|
-
mergedTexts[mergedTexts.length - 1] += t;
|
|
880
|
-
continue;
|
|
881
|
-
}
|
|
882
|
-
mergedTexts.push(t);
|
|
883
|
-
mergedKinds.push(k);
|
|
884
|
-
mergedWordLike.push(wl);
|
|
885
804
|
}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
805
|
+
return positions;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/solutions/reactive-layout/types.ts
|
|
809
|
+
var TEXT_SEGMENTS_MEASUREMENT_KIND = "text-segments";
|
|
810
|
+
var BLOCKS_MEASUREMENT_KIND = "blocks";
|
|
811
|
+
var READINESS_MEASUREMENT_KIND = "readiness";
|
|
812
|
+
var IMAGE_SIZE_MEASUREMENT_KIND = "image-size";
|
|
813
|
+
var SVG_BOUNDS_MEASUREMENT_KIND = "svg-bounds";
|
|
814
|
+
|
|
815
|
+
// src/solutions/reactive-layout/measurements.ts
|
|
816
|
+
function measurementIssue(code, message, targetId, measurementKind, opts = {}) {
|
|
817
|
+
return {
|
|
818
|
+
kind: "issue",
|
|
819
|
+
code,
|
|
820
|
+
message,
|
|
821
|
+
severity: opts.severity ?? "warning",
|
|
822
|
+
source: opts.source,
|
|
823
|
+
subjectId: targetId,
|
|
824
|
+
measurementKind,
|
|
825
|
+
details: opts.details,
|
|
826
|
+
metadata: opts.metadata
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function measurementOk(targetId, measurementKind, value, opts = {}) {
|
|
830
|
+
return {
|
|
831
|
+
kind: "ok",
|
|
832
|
+
targetId,
|
|
833
|
+
measurementKind,
|
|
834
|
+
value,
|
|
835
|
+
source: opts.source,
|
|
836
|
+
metadata: opts.metadata
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
function latestMeasurementValue(measurements, targetId, measurementKind) {
|
|
840
|
+
let value;
|
|
841
|
+
for (const fact of measurements) {
|
|
842
|
+
if (fact.kind === "ok" && fact.targetId === targetId && fact.measurementKind === measurementKind) {
|
|
843
|
+
value = fact.value;
|
|
896
844
|
}
|
|
897
|
-
if (stats) stats.hits += 1;
|
|
898
|
-
return cached;
|
|
899
845
|
}
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
846
|
+
return value;
|
|
847
|
+
}
|
|
848
|
+
function tryMeasureHyphenWidth(adapter, font) {
|
|
849
|
+
try {
|
|
850
|
+
return nonNegativeFinite(adapter.measureSegment("-", font).width, 0);
|
|
851
|
+
} catch {
|
|
852
|
+
return void 0;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
function validMeasurementSize(size, label) {
|
|
856
|
+
if (!Number.isFinite(size.width) || !Number.isFinite(size.height) || size.width < 0 || size.height < 0) {
|
|
857
|
+
throw new Error(`Invalid ${label} measurement size`);
|
|
858
|
+
}
|
|
859
|
+
return size;
|
|
860
|
+
}
|
|
861
|
+
function textMeasurementFacts(text, font, adapter, cache, segmentAdapter, targetId, source) {
|
|
862
|
+
try {
|
|
863
|
+
const segments = analyzeAndMeasure(text, font, adapter, cache, void 0, segmentAdapter);
|
|
864
|
+
const hyphenWidth = tryMeasureHyphenWidth(adapter, font);
|
|
865
|
+
const facts = [
|
|
866
|
+
measurementOk(
|
|
867
|
+
targetId,
|
|
868
|
+
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
869
|
+
hyphenWidth === void 0 ? { segments } : { segments, hyphenWidth },
|
|
870
|
+
{ source }
|
|
871
|
+
)
|
|
872
|
+
];
|
|
873
|
+
if (hyphenWidth === void 0) {
|
|
874
|
+
facts.push(
|
|
875
|
+
measurementIssue(
|
|
876
|
+
"measurement.hyphen.failed",
|
|
877
|
+
`Hyphen measurement failed for '${targetId}'`,
|
|
878
|
+
targetId,
|
|
879
|
+
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
880
|
+
{ source, severity: "warning" }
|
|
881
|
+
)
|
|
882
|
+
);
|
|
912
883
|
}
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
884
|
+
return facts;
|
|
885
|
+
} catch (error) {
|
|
886
|
+
return [
|
|
887
|
+
measurementIssue(
|
|
888
|
+
"measurement.failed",
|
|
889
|
+
`Text measurement failed for '${targetId}'`,
|
|
890
|
+
targetId,
|
|
891
|
+
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
892
|
+
{ source, details: error, severity: "error" }
|
|
893
|
+
)
|
|
894
|
+
];
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function inputNode(g, input, fallback, name) {
|
|
898
|
+
if (input instanceof Node) {
|
|
899
|
+
return {
|
|
900
|
+
node: input,
|
|
901
|
+
set(value) {
|
|
902
|
+
const maybeState = input;
|
|
903
|
+
if (typeof maybeState.set !== "function") {
|
|
904
|
+
throw new TypeError(`reactive-layout input '${name}' is not a writable state node`);
|
|
928
905
|
}
|
|
929
|
-
|
|
930
|
-
}
|
|
931
|
-
if (unitText.length > 0) {
|
|
932
|
-
out.push({
|
|
933
|
-
text: unitText,
|
|
934
|
-
width: measureCached(unitText),
|
|
935
|
-
kind: "text",
|
|
936
|
-
graphemeWidths: null
|
|
937
|
-
});
|
|
938
|
-
}
|
|
939
|
-
continue;
|
|
940
|
-
}
|
|
941
|
-
const textWidth = measureCached(t);
|
|
942
|
-
let graphemeWidths = null;
|
|
943
|
-
if (mergedWordLike[i] && t.length > 1) {
|
|
944
|
-
const widths = [];
|
|
945
|
-
for (const grapheme of segAdapter.segmentGraphemes(t)) {
|
|
946
|
-
widths.push(measureCached(grapheme.segment));
|
|
906
|
+
maybeState.set(value);
|
|
947
907
|
}
|
|
948
|
-
|
|
949
|
-
}
|
|
950
|
-
out.push({
|
|
951
|
-
text: t,
|
|
952
|
-
width: textWidth,
|
|
953
|
-
kind: "text",
|
|
954
|
-
graphemeWidths
|
|
955
|
-
});
|
|
908
|
+
};
|
|
956
909
|
}
|
|
957
|
-
|
|
910
|
+
const state = g.state(input ?? fallback, { name });
|
|
911
|
+
return { node: state, set: (value) => state.set(value) };
|
|
958
912
|
}
|
|
959
|
-
function
|
|
960
|
-
|
|
961
|
-
const segAdapter = opts.segmentAdapter ?? getDefaultSegmentAdapter();
|
|
962
|
-
const lines = [];
|
|
963
|
-
let cursor = { segmentIndex: 0, graphemeIndex: 0 };
|
|
964
|
-
while (cursor.segmentIndex < segments.length) {
|
|
965
|
-
const next = layoutNextLine(segments, cursor, maxWidth, {
|
|
966
|
-
hyphenWidth: opts.hyphenWidth,
|
|
967
|
-
segmentAdapter: segAdapter
|
|
968
|
-
});
|
|
969
|
-
if (next === null) break;
|
|
970
|
-
lines.push({
|
|
971
|
-
text: next.text,
|
|
972
|
-
width: next.width,
|
|
973
|
-
startSegment: next.start.segmentIndex,
|
|
974
|
-
startGrapheme: next.start.graphemeIndex,
|
|
975
|
-
endSegment: next.end.segmentIndex,
|
|
976
|
-
endGrapheme: next.end.graphemeIndex
|
|
977
|
-
});
|
|
978
|
-
if (next.end.segmentIndex === cursor.segmentIndex && next.end.graphemeIndex === cursor.graphemeIndex) {
|
|
979
|
-
break;
|
|
980
|
-
}
|
|
981
|
-
cursor = next.end;
|
|
982
|
-
}
|
|
983
|
-
return { lines, lineCount: lines.length };
|
|
913
|
+
function scopedName(scope, local) {
|
|
914
|
+
return scope === local ? local : `${scope}:${local}`;
|
|
984
915
|
}
|
|
985
|
-
function
|
|
986
|
-
|
|
916
|
+
function textMeasurementProvider(opts) {
|
|
917
|
+
const targetId = opts.targetId ?? "text";
|
|
918
|
+
const name = opts.name ?? `${targetId}-measurements`;
|
|
919
|
+
const source = opts.source ?? name;
|
|
920
|
+
const cache = /* @__PURE__ */ new Map();
|
|
921
|
+
let activeAdapter = null;
|
|
922
|
+
return opts.graph.node(
|
|
923
|
+
opts.segmentAdapter ? [opts.text, opts.font, opts.adapter, opts.segmentAdapter] : [opts.text, opts.font, opts.adapter],
|
|
924
|
+
(ctx) => {
|
|
925
|
+
const flush = () => {
|
|
926
|
+
cache.clear();
|
|
927
|
+
depLatest(ctx, 2).clearCache?.();
|
|
928
|
+
};
|
|
929
|
+
ctx.onDeactivation(flush);
|
|
930
|
+
ctx.onInvalidate(flush);
|
|
931
|
+
const text = depLatest(ctx, 0);
|
|
932
|
+
const font = depLatest(ctx, 1);
|
|
933
|
+
const adapter = depLatest(ctx, 2);
|
|
934
|
+
if (adapter !== activeAdapter) {
|
|
935
|
+
cache.clear();
|
|
936
|
+
activeAdapter = adapter;
|
|
937
|
+
}
|
|
938
|
+
const segmentAdapter = opts.segmentAdapter === void 0 ? getDefaultSegmentAdapter() : depLatest(ctx, 3);
|
|
939
|
+
ctx.down([
|
|
940
|
+
[
|
|
941
|
+
"DATA",
|
|
942
|
+
textMeasurementFacts(text, font, adapter, cache, segmentAdapter, targetId, source)
|
|
943
|
+
]
|
|
944
|
+
]);
|
|
945
|
+
},
|
|
946
|
+
{ name }
|
|
947
|
+
);
|
|
948
|
+
}
|
|
949
|
+
function injectedTextMeasurements(opts) {
|
|
950
|
+
const targetId = opts.targetId ?? "text";
|
|
951
|
+
const adapter = opts.graph.state(
|
|
952
|
+
new InjectedMeasureAdapter(opts.measure, { cache: opts.cache }),
|
|
953
|
+
{
|
|
954
|
+
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
return textMeasurementProvider({
|
|
958
|
+
...opts,
|
|
959
|
+
adapter,
|
|
960
|
+
source: opts.source ?? "injectedTextMeasurements"
|
|
961
|
+
});
|
|
987
962
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
963
|
+
function precomputedTextMeasurements(opts) {
|
|
964
|
+
const targetId = opts.targetId ?? "text";
|
|
965
|
+
const adapter = opts.graph.state(new PrecomputedMeasureAdapter(opts), {
|
|
966
|
+
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
967
|
+
});
|
|
968
|
+
return textMeasurementProvider({
|
|
969
|
+
...opts,
|
|
970
|
+
adapter,
|
|
971
|
+
source: opts.source ?? "precomputedTextMeasurements"
|
|
972
|
+
});
|
|
993
973
|
}
|
|
994
|
-
function
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1005
|
-
if (endGrapheme > 0 && endSegment < segments.length) {
|
|
1006
|
-
const seg = segments[endSegment];
|
|
1007
|
-
const from = startSegment === endSegment ? startGrapheme : 0;
|
|
1008
|
-
text += sliceSegmentText(seg, from, endGrapheme, segmentAdapter);
|
|
1009
|
-
}
|
|
1010
|
-
if (appendHyphen) text += "-";
|
|
1011
|
-
return text;
|
|
974
|
+
function cellTextMeasurements(opts) {
|
|
975
|
+
const targetId = opts.targetId ?? "text";
|
|
976
|
+
const adapter = opts.graph.state(new CellMeasureAdapter(opts), {
|
|
977
|
+
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
978
|
+
});
|
|
979
|
+
return textMeasurementProvider({
|
|
980
|
+
...opts,
|
|
981
|
+
adapter,
|
|
982
|
+
source: opts.source ?? "cellTextMeasurements"
|
|
983
|
+
});
|
|
1012
984
|
}
|
|
1013
|
-
function
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
if (width === void 0) {
|
|
1025
|
-
width = ctx.adapter.measureSegment("-", ctx.font).width;
|
|
1026
|
-
fontCache.set("-", width);
|
|
985
|
+
function capabilityTextMeasurements(opts) {
|
|
986
|
+
const targetId = opts.targetId ?? "text";
|
|
987
|
+
const adapter = opts.graph.node(
|
|
988
|
+
[opts.capability],
|
|
989
|
+
(ctx) => {
|
|
990
|
+
ctx.down([
|
|
991
|
+
["DATA", new CapabilityMeasureAdapter(depLatest(ctx, 0))]
|
|
992
|
+
]);
|
|
993
|
+
},
|
|
994
|
+
{
|
|
995
|
+
name: opts.name ? scopedName(opts.name, "measure-capability") : `${targetId}-measure-capability`
|
|
1027
996
|
}
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
997
|
+
);
|
|
998
|
+
return textMeasurementProvider({
|
|
999
|
+
...opts,
|
|
1000
|
+
adapter,
|
|
1001
|
+
source: opts.source ?? "capabilityTextMeasurements"
|
|
1002
|
+
});
|
|
1031
1003
|
}
|
|
1032
|
-
function
|
|
1033
|
-
|
|
1034
|
-
const
|
|
1035
|
-
const
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}
|
|
1056
|
-
const hyphenWidth = resolveHyphenWidth(ctx);
|
|
1057
|
-
const startSegment = i;
|
|
1058
|
-
const startGrapheme = i === cursor.segmentIndex ? initialGrapheme : 0;
|
|
1059
|
-
let lineW = 0;
|
|
1060
|
-
let lineEndSegment = startSegment;
|
|
1061
|
-
let lineEndGrapheme = 0;
|
|
1062
|
-
let hasContent = false;
|
|
1063
|
-
let pendingBreakSegment = -1;
|
|
1064
|
-
let pendingBreakGrapheme = 0;
|
|
1065
|
-
let pendingBreakWidth = 0;
|
|
1066
|
-
let pendingBreakSoftHyphen = false;
|
|
1067
|
-
const recordPending = (sIdx, gIdx, width, kind) => {
|
|
1068
|
-
pendingBreakSegment = sIdx;
|
|
1069
|
-
pendingBreakGrapheme = gIdx;
|
|
1070
|
-
pendingBreakWidth = width;
|
|
1071
|
-
pendingBreakSoftHyphen = kind === "soft-hyphen";
|
|
1072
|
-
};
|
|
1073
|
-
const consumeBreakable = (segIdx, startG, widths) => {
|
|
1074
|
-
for (let g = startG; g < widths.length; g += 1) {
|
|
1075
|
-
const gw = widths[g];
|
|
1076
|
-
if (!hasContent) {
|
|
1077
|
-
lineW = gw;
|
|
1078
|
-
lineEndSegment = segIdx;
|
|
1079
|
-
lineEndGrapheme = g + 1;
|
|
1080
|
-
hasContent = true;
|
|
1081
|
-
continue;
|
|
1004
|
+
function readinessTextMeasurements(opts) {
|
|
1005
|
+
const targetId = opts.targetId ?? "text";
|
|
1006
|
+
const name = opts.name ?? `${targetId}-measurements`;
|
|
1007
|
+
const source = opts.source ?? name;
|
|
1008
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1009
|
+
let activeAdapter = null;
|
|
1010
|
+
let activeReadiness = null;
|
|
1011
|
+
const deps = opts.segmentAdapter ? [opts.text, opts.font, opts.adapter, opts.readiness, opts.segmentAdapter] : [opts.text, opts.font, opts.adapter, opts.readiness];
|
|
1012
|
+
return opts.graph.node(
|
|
1013
|
+
deps,
|
|
1014
|
+
(ctx) => {
|
|
1015
|
+
const flush = () => {
|
|
1016
|
+
cache.clear();
|
|
1017
|
+
depLatest(ctx, 2).clearCache?.();
|
|
1018
|
+
};
|
|
1019
|
+
ctx.onDeactivation(flush);
|
|
1020
|
+
ctx.onInvalidate(flush);
|
|
1021
|
+
const text = depLatest(ctx, 0);
|
|
1022
|
+
const font = depLatest(ctx, 1);
|
|
1023
|
+
const adapter = depLatest(ctx, 2);
|
|
1024
|
+
if (adapter !== activeAdapter) {
|
|
1025
|
+
cache.clear();
|
|
1026
|
+
activeAdapter = adapter;
|
|
1082
1027
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1028
|
+
const readiness = depLatest(ctx, 3);
|
|
1029
|
+
if (readiness !== activeReadiness) {
|
|
1030
|
+
cache.clear();
|
|
1031
|
+
activeReadiness = readiness;
|
|
1085
1032
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
false,
|
|
1108
|
-
segmentAdapter
|
|
1109
|
-
);
|
|
1110
|
-
return {
|
|
1111
|
-
text: text2,
|
|
1112
|
-
width: lineW,
|
|
1113
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1114
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1115
|
-
};
|
|
1033
|
+
if (!readiness.ready) {
|
|
1034
|
+
ctx.down([
|
|
1035
|
+
[
|
|
1036
|
+
"DATA",
|
|
1037
|
+
[
|
|
1038
|
+
measurementIssue(
|
|
1039
|
+
readiness.code ?? "measurement.not-ready",
|
|
1040
|
+
readiness.message ?? `Measurement readiness blocked '${targetId}'`,
|
|
1041
|
+
targetId,
|
|
1042
|
+
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
1043
|
+
{
|
|
1044
|
+
source: readiness.source ?? source,
|
|
1045
|
+
details: readiness.details,
|
|
1046
|
+
metadata: readiness.metadata,
|
|
1047
|
+
severity: "warning"
|
|
1048
|
+
}
|
|
1049
|
+
)
|
|
1050
|
+
]
|
|
1051
|
+
]
|
|
1052
|
+
]);
|
|
1053
|
+
return;
|
|
1116
1054
|
}
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1055
|
+
const segmentAdapter = opts.segmentAdapter === void 0 ? getDefaultSegmentAdapter() : depLatest(ctx, 4);
|
|
1056
|
+
ctx.down([
|
|
1057
|
+
[
|
|
1058
|
+
"DATA",
|
|
1059
|
+
textMeasurementFacts(text, font, adapter, cache, segmentAdapter, targetId, source)
|
|
1060
|
+
]
|
|
1061
|
+
]);
|
|
1062
|
+
},
|
|
1063
|
+
{ name }
|
|
1064
|
+
);
|
|
1065
|
+
}
|
|
1066
|
+
function readinessMeasurements(opts) {
|
|
1067
|
+
const targetId = opts.targetId ?? "measurement-readiness";
|
|
1068
|
+
const measurementKind = opts.measurementKind ?? READINESS_MEASUREMENT_KIND;
|
|
1069
|
+
const name = opts.name ?? `${targetId}-measurements`;
|
|
1070
|
+
const source = opts.source ?? name;
|
|
1071
|
+
return opts.graph.node(
|
|
1072
|
+
[opts.readiness],
|
|
1073
|
+
(ctx) => {
|
|
1074
|
+
const readiness = depLatest(ctx, 0);
|
|
1075
|
+
if (!readiness.ready) {
|
|
1076
|
+
ctx.down([
|
|
1077
|
+
[
|
|
1078
|
+
"DATA",
|
|
1079
|
+
[
|
|
1080
|
+
measurementIssue(
|
|
1081
|
+
readiness.code ?? "measurement.not-ready",
|
|
1082
|
+
readiness.message ?? `Measurement readiness blocked '${targetId}'`,
|
|
1083
|
+
targetId,
|
|
1084
|
+
measurementKind,
|
|
1085
|
+
{
|
|
1086
|
+
source: readiness.source ?? source,
|
|
1087
|
+
details: readiness.details,
|
|
1088
|
+
metadata: readiness.metadata,
|
|
1089
|
+
severity: "warning"
|
|
1090
|
+
}
|
|
1091
|
+
)
|
|
1092
|
+
]
|
|
1093
|
+
]
|
|
1094
|
+
]);
|
|
1095
|
+
return;
|
|
1140
1096
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1097
|
+
ctx.down([
|
|
1098
|
+
[
|
|
1099
|
+
"DATA",
|
|
1100
|
+
[
|
|
1101
|
+
measurementOk(targetId, measurementKind, readiness, {
|
|
1102
|
+
source: readiness.source ?? source,
|
|
1103
|
+
metadata: readiness.metadata
|
|
1104
|
+
})
|
|
1105
|
+
]
|
|
1106
|
+
]
|
|
1107
|
+
]);
|
|
1108
|
+
},
|
|
1109
|
+
{ name }
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
function imageSizeMeasurements(opts) {
|
|
1113
|
+
const measurementKind = opts.measurementKind ?? IMAGE_SIZE_MEASUREMENT_KIND;
|
|
1114
|
+
const name = opts.name ?? "image-size-measurements";
|
|
1115
|
+
const source = opts.source ?? name;
|
|
1116
|
+
return opts.graph.node(
|
|
1117
|
+
[opts.images, opts.measurer],
|
|
1118
|
+
(ctx) => {
|
|
1119
|
+
const images = depLatest(ctx, 0);
|
|
1120
|
+
const measurer = depLatest(ctx, 1);
|
|
1121
|
+
const facts = [];
|
|
1122
|
+
for (let i = 0; i < images.length; i += 1) {
|
|
1123
|
+
const image = images[i];
|
|
1124
|
+
const subjectId = image?.id ?? image?.src ?? `image:${i}`;
|
|
1125
|
+
try {
|
|
1126
|
+
if (image === void 0) throw new Error(`Missing image target at index ${i}`);
|
|
1127
|
+
facts.push(
|
|
1128
|
+
measurementOk(
|
|
1129
|
+
subjectId,
|
|
1130
|
+
measurementKind,
|
|
1131
|
+
validMeasurementSize(measurer.measureImage(image.src), "image"),
|
|
1132
|
+
{
|
|
1133
|
+
source,
|
|
1134
|
+
metadata: image.metadata
|
|
1135
|
+
}
|
|
1136
|
+
)
|
|
1137
|
+
);
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
facts.push(
|
|
1140
|
+
measurementIssue(
|
|
1141
|
+
"measurement.image-size.failed",
|
|
1142
|
+
`Image size measurement failed for '${subjectId}'`,
|
|
1143
|
+
subjectId,
|
|
1144
|
+
measurementKind,
|
|
1145
|
+
{
|
|
1146
|
+
source,
|
|
1147
|
+
details: { error, index: i, src: image?.src },
|
|
1148
|
+
metadata: image?.metadata,
|
|
1149
|
+
severity: "error"
|
|
1150
|
+
}
|
|
1151
|
+
)
|
|
1161
1152
|
);
|
|
1162
|
-
return {
|
|
1163
|
-
text: text2,
|
|
1164
|
-
width: lineW,
|
|
1165
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1166
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1167
|
-
};
|
|
1168
1153
|
}
|
|
1169
|
-
i = lineEndSegment - 1;
|
|
1170
|
-
continue;
|
|
1171
|
-
}
|
|
1172
|
-
lineW = w;
|
|
1173
|
-
lineEndSegment = i + 1;
|
|
1174
|
-
lineEndGrapheme = 0;
|
|
1175
|
-
hasContent = true;
|
|
1176
|
-
if (canBreakAfter(seg.kind)) {
|
|
1177
|
-
recordPending(i + 1, 0, seg.kind === "space" ? lineW - w : lineW, seg.kind);
|
|
1178
|
-
}
|
|
1179
|
-
continue;
|
|
1180
|
-
}
|
|
1181
|
-
const projectedWidth = lineW + w;
|
|
1182
|
-
if (projectedWidth > slotWidth + 1e-3) {
|
|
1183
|
-
if (canBreakAfter(seg.kind)) {
|
|
1184
|
-
lineEndSegment = i + 1;
|
|
1185
|
-
lineEndGrapheme = 0;
|
|
1186
|
-
const endsAtSoftHyphen2 = seg.kind === "soft-hyphen";
|
|
1187
|
-
const text3 = buildLineText(
|
|
1188
|
-
segments,
|
|
1189
|
-
startSegment,
|
|
1190
|
-
startGrapheme,
|
|
1191
|
-
lineEndSegment,
|
|
1192
|
-
lineEndGrapheme,
|
|
1193
|
-
endsAtSoftHyphen2,
|
|
1194
|
-
segmentAdapter
|
|
1195
|
-
);
|
|
1196
|
-
return {
|
|
1197
|
-
text: text3,
|
|
1198
|
-
width: seg.kind === "space" ? lineW : lineW + (endsAtSoftHyphen2 ? hyphenWidth : 0),
|
|
1199
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1200
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1201
|
-
};
|
|
1202
|
-
}
|
|
1203
|
-
if (pendingBreakSegment >= 0) {
|
|
1204
|
-
const text3 = buildLineText(
|
|
1205
|
-
segments,
|
|
1206
|
-
startSegment,
|
|
1207
|
-
startGrapheme,
|
|
1208
|
-
pendingBreakSegment,
|
|
1209
|
-
pendingBreakGrapheme,
|
|
1210
|
-
pendingBreakSoftHyphen,
|
|
1211
|
-
segmentAdapter
|
|
1212
|
-
);
|
|
1213
|
-
return {
|
|
1214
|
-
text: text3,
|
|
1215
|
-
width: pendingBreakWidth + (pendingBreakSoftHyphen ? hyphenWidth : 0),
|
|
1216
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1217
|
-
end: { segmentIndex: pendingBreakSegment, graphemeIndex: pendingBreakGrapheme }
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
if (w > slotWidth && seg.graphemeWidths) {
|
|
1221
|
-
const text3 = buildLineText(
|
|
1222
|
-
segments,
|
|
1223
|
-
startSegment,
|
|
1224
|
-
startGrapheme,
|
|
1225
|
-
lineEndSegment,
|
|
1226
|
-
lineEndGrapheme,
|
|
1227
|
-
false,
|
|
1228
|
-
segmentAdapter
|
|
1229
|
-
);
|
|
1230
|
-
return {
|
|
1231
|
-
text: text3,
|
|
1232
|
-
width: lineW,
|
|
1233
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1234
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1235
|
-
};
|
|
1236
1154
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
startGrapheme,
|
|
1241
|
-
lineEndSegment,
|
|
1242
|
-
lineEndGrapheme,
|
|
1243
|
-
false,
|
|
1244
|
-
segmentAdapter
|
|
1245
|
-
);
|
|
1246
|
-
return {
|
|
1247
|
-
text: text2,
|
|
1248
|
-
width: lineW,
|
|
1249
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1250
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1251
|
-
};
|
|
1252
|
-
}
|
|
1253
|
-
lineW = projectedWidth;
|
|
1254
|
-
lineEndSegment = i + 1;
|
|
1255
|
-
lineEndGrapheme = 0;
|
|
1256
|
-
if (canBreakAfter(seg.kind)) {
|
|
1257
|
-
recordPending(i + 1, 0, seg.kind === "space" ? lineW - w : lineW, seg.kind);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
if (!hasContent) return null;
|
|
1261
|
-
const endsAtSoftHyphen = lineEndSegment > 0 && segments[lineEndSegment - 1]?.kind === "soft-hyphen";
|
|
1262
|
-
const text = buildLineText(
|
|
1263
|
-
segments,
|
|
1264
|
-
startSegment,
|
|
1265
|
-
startGrapheme,
|
|
1266
|
-
lineEndSegment,
|
|
1267
|
-
lineEndGrapheme,
|
|
1268
|
-
endsAtSoftHyphen,
|
|
1269
|
-
segmentAdapter
|
|
1155
|
+
ctx.down([["DATA", facts]]);
|
|
1156
|
+
},
|
|
1157
|
+
{ name }
|
|
1270
1158
|
);
|
|
1271
|
-
return {
|
|
1272
|
-
text,
|
|
1273
|
-
width: lineW + (endsAtSoftHyphen ? hyphenWidth : 0),
|
|
1274
|
-
start: { segmentIndex: startSegment, graphemeIndex: startGrapheme },
|
|
1275
|
-
end: { segmentIndex: lineEndSegment, graphemeIndex: lineEndGrapheme }
|
|
1276
|
-
};
|
|
1277
1159
|
}
|
|
1278
|
-
function
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1160
|
+
function svgBoundsMeasurements(opts) {
|
|
1161
|
+
const measurementKind = opts.measurementKind ?? SVG_BOUNDS_MEASUREMENT_KIND;
|
|
1162
|
+
const name = opts.name ?? "svg-bounds-measurements";
|
|
1163
|
+
const source = opts.source ?? name;
|
|
1164
|
+
return opts.graph.node(
|
|
1165
|
+
[opts.svgs, opts.measurer],
|
|
1166
|
+
(ctx) => {
|
|
1167
|
+
const svgs = depLatest(ctx, 0);
|
|
1168
|
+
const measurer = depLatest(ctx, 1);
|
|
1169
|
+
const facts = [];
|
|
1170
|
+
for (let i = 0; i < svgs.length; i += 1) {
|
|
1171
|
+
const svg = svgs[i];
|
|
1172
|
+
const subjectId = svg?.id ?? `svg:${i}`;
|
|
1173
|
+
try {
|
|
1174
|
+
if (svg === void 0) throw new Error(`Missing SVG target at index ${i}`);
|
|
1175
|
+
facts.push(
|
|
1176
|
+
measurementOk(
|
|
1177
|
+
subjectId,
|
|
1178
|
+
measurementKind,
|
|
1179
|
+
validMeasurementSize(measurer.measureSvg(svg.svg), "SVG"),
|
|
1180
|
+
{
|
|
1181
|
+
source,
|
|
1182
|
+
metadata: svg.metadata
|
|
1183
|
+
}
|
|
1184
|
+
)
|
|
1185
|
+
);
|
|
1186
|
+
} catch (error) {
|
|
1187
|
+
facts.push(
|
|
1188
|
+
measurementIssue(
|
|
1189
|
+
"measurement.svg-bounds.failed",
|
|
1190
|
+
`SVG bounds measurement failed for '${subjectId}'`,
|
|
1191
|
+
subjectId,
|
|
1192
|
+
measurementKind,
|
|
1193
|
+
{
|
|
1194
|
+
source,
|
|
1195
|
+
details: { error, index: i },
|
|
1196
|
+
metadata: svg?.metadata,
|
|
1197
|
+
severity: "error"
|
|
1198
|
+
}
|
|
1199
|
+
)
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1286
1202
|
}
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1290
|
-
|
|
1291
|
-
}
|
|
1292
|
-
if (minSlotWidth > 0) return slots.filter((slot) => slot.right - slot.left >= minSlotWidth);
|
|
1293
|
-
return slots;
|
|
1203
|
+
ctx.down([["DATA", facts]]);
|
|
1204
|
+
},
|
|
1205
|
+
{ name }
|
|
1206
|
+
);
|
|
1294
1207
|
}
|
|
1295
|
-
function
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
const seg = segments[si];
|
|
1304
|
-
if (seg.kind === "soft-hyphen" || seg.kind === "hard-break") {
|
|
1305
|
-
if (si >= line.endSegment && line.endGrapheme === 0) break;
|
|
1306
|
-
continue;
|
|
1307
|
-
}
|
|
1308
|
-
const graphemes = [...segAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
|
|
1309
|
-
if (graphemes.length === 0) continue;
|
|
1310
|
-
const startGrapheme = si === line.startSegment ? line.startGrapheme : 0;
|
|
1311
|
-
let endGrapheme;
|
|
1312
|
-
if (si < line.endSegment) {
|
|
1313
|
-
endGrapheme = graphemes.length;
|
|
1314
|
-
} else if (si === line.endSegment && line.endGrapheme > 0) {
|
|
1315
|
-
endGrapheme = line.endGrapheme;
|
|
1316
|
-
} else {
|
|
1317
|
-
break;
|
|
1318
|
-
}
|
|
1319
|
-
for (let g = startGrapheme; g < endGrapheme; g += 1) {
|
|
1320
|
-
const width = seg.graphemeWidths ? seg.graphemeWidths[g] : seg.width / graphemes.length;
|
|
1321
|
-
positions.push({ x, y, width, height: lineHeight, line: lineIdx });
|
|
1322
|
-
x += width;
|
|
1208
|
+
function mergeMeasurements(opts) {
|
|
1209
|
+
const sources = [...opts.sources];
|
|
1210
|
+
return opts.graph.node(
|
|
1211
|
+
sources,
|
|
1212
|
+
(ctx) => {
|
|
1213
|
+
const facts = [];
|
|
1214
|
+
for (let i = 0; i < sources.length; i += 1) {
|
|
1215
|
+
facts.push(...depLatest(ctx, i));
|
|
1323
1216
|
}
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
function nonNegativeFinite(value, fallback) {
|
|
1329
|
-
return Number.isFinite(value) ? Math.max(0, value) : fallback;
|
|
1330
|
-
}
|
|
1331
|
-
function finiteNumber(value, fallback) {
|
|
1332
|
-
return Number.isFinite(value) ? value : fallback;
|
|
1333
|
-
}
|
|
1334
|
-
function emitLayoutError(ctx, error, fallback) {
|
|
1335
|
-
ctx.down([["ERROR", errorPayload(error, fallback)]]);
|
|
1336
|
-
}
|
|
1337
|
-
function positiveFinite(value, fallback) {
|
|
1338
|
-
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
1339
|
-
}
|
|
1340
|
-
function clampDimension(value) {
|
|
1341
|
-
return nonNegativeFinite(value ?? 0, 0);
|
|
1342
|
-
}
|
|
1343
|
-
function fitSize(size, maxWidth) {
|
|
1344
|
-
const width = nonNegativeFinite(size.width, 0);
|
|
1345
|
-
const height = nonNegativeFinite(size.height, 0);
|
|
1346
|
-
if (width === 0 || maxWidth <= 0 || width <= maxWidth) return { width, height };
|
|
1347
|
-
const scale = maxWidth / width;
|
|
1348
|
-
return { width: maxWidth, height: height * scale };
|
|
1217
|
+
ctx.down([["DATA", facts]]);
|
|
1218
|
+
},
|
|
1219
|
+
{ name: opts.name ?? "measurements" }
|
|
1220
|
+
);
|
|
1349
1221
|
}
|
|
1350
|
-
function
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1353
|
-
if (
|
|
1354
|
-
|
|
1222
|
+
function blockAdaptersProvider(opts) {
|
|
1223
|
+
const deps = [];
|
|
1224
|
+
const positions = {};
|
|
1225
|
+
if (opts.text) {
|
|
1226
|
+
positions.text = deps.length;
|
|
1227
|
+
deps.push(opts.text);
|
|
1228
|
+
}
|
|
1229
|
+
if (opts.svg) {
|
|
1230
|
+
positions.svg = deps.length;
|
|
1231
|
+
deps.push(opts.svg);
|
|
1232
|
+
}
|
|
1233
|
+
if (opts.image) {
|
|
1234
|
+
positions.image = deps.length;
|
|
1235
|
+
deps.push(opts.image);
|
|
1236
|
+
}
|
|
1237
|
+
return opts.graph.node(
|
|
1238
|
+
deps,
|
|
1239
|
+
(ctx) => {
|
|
1240
|
+
const adapters = {
|
|
1241
|
+
text: positions.text === void 0 ? void 0 : depLatest(ctx, positions.text),
|
|
1242
|
+
svg: positions.svg === void 0 ? void 0 : depLatest(ctx, positions.svg),
|
|
1243
|
+
image: positions.image === void 0 ? void 0 : depLatest(ctx, positions.image)
|
|
1244
|
+
};
|
|
1245
|
+
ctx.down([["DATA", adapters]]);
|
|
1246
|
+
},
|
|
1247
|
+
{ name: opts.name ?? "block-adapters" }
|
|
1248
|
+
);
|
|
1355
1249
|
}
|
|
1356
|
-
function
|
|
1357
|
-
const
|
|
1358
|
-
|
|
1359
|
-
|
|
1250
|
+
function blockMeasurementProvider(opts) {
|
|
1251
|
+
const targetId = opts.targetId ?? "blocks";
|
|
1252
|
+
const name = opts.name ?? `${targetId}-measurements`;
|
|
1253
|
+
const source = opts.source ?? name;
|
|
1254
|
+
const cache = /* @__PURE__ */ new Map();
|
|
1255
|
+
let activeTextAdapter;
|
|
1256
|
+
const deps = [opts.blocks, opts.maxWidth, opts.adapters];
|
|
1257
|
+
if (opts.font) deps.push(opts.font);
|
|
1258
|
+
if (opts.lineHeight) deps.push(opts.lineHeight);
|
|
1259
|
+
if (opts.segmentAdapter) deps.push(opts.segmentAdapter);
|
|
1260
|
+
return opts.graph.node(
|
|
1261
|
+
deps,
|
|
1262
|
+
(ctx) => {
|
|
1263
|
+
const flush = () => {
|
|
1264
|
+
cache.clear();
|
|
1265
|
+
const adapters = depLatest(ctx, 2);
|
|
1266
|
+
adapters.text?.clearCache?.();
|
|
1267
|
+
};
|
|
1268
|
+
ctx.onDeactivation(flush);
|
|
1269
|
+
ctx.onInvalidate(flush);
|
|
1270
|
+
try {
|
|
1271
|
+
const blocks = depLatest(ctx, 0);
|
|
1272
|
+
const maxWidth = nonNegativeFinite(depLatest(ctx, 1), 0);
|
|
1273
|
+
const adapters = depLatest(ctx, 2);
|
|
1274
|
+
if (adapters.text !== activeTextAdapter) {
|
|
1275
|
+
cache.clear();
|
|
1276
|
+
activeTextAdapter = adapters.text;
|
|
1277
|
+
}
|
|
1278
|
+
let depIndex = 3;
|
|
1279
|
+
const font = opts.font ? depLatest(ctx, depIndex++) : void 0;
|
|
1280
|
+
const lineHeight = opts.lineHeight ? nonNegativeFinite(depLatest(ctx, depIndex++), 0) : void 0;
|
|
1281
|
+
const segmentAdapter = opts.segmentAdapter ? depLatest(ctx, depIndex) : getDefaultSegmentAdapter();
|
|
1282
|
+
const measured = [];
|
|
1283
|
+
const issues = [];
|
|
1284
|
+
for (let i = 0; i < blocks.length; i += 1) {
|
|
1285
|
+
const block = blocks[i];
|
|
1286
|
+
const subjectId = block?.id ?? `${targetId}:${i}`;
|
|
1287
|
+
try {
|
|
1288
|
+
if (block === void 0) {
|
|
1289
|
+
throw new Error(`Missing content block at index ${i}`);
|
|
1290
|
+
}
|
|
1291
|
+
const blockFont = block.kind === "text" ? block.font ?? font ?? "16px sans-serif" : void 0;
|
|
1292
|
+
const hyphenWidth = block.kind === "text" && adapters.text ? tryMeasureHyphenWidth(adapters.text, blockFont ?? "16px sans-serif") : void 0;
|
|
1293
|
+
measured.push(
|
|
1294
|
+
measureBlock(block, {
|
|
1295
|
+
adapters,
|
|
1296
|
+
font,
|
|
1297
|
+
hyphenWidth,
|
|
1298
|
+
lineHeight,
|
|
1299
|
+
maxWidth,
|
|
1300
|
+
cache,
|
|
1301
|
+
segmentAdapter
|
|
1302
|
+
})
|
|
1303
|
+
);
|
|
1304
|
+
if (block.kind === "text" && adapters.text) {
|
|
1305
|
+
if (hyphenWidth === void 0) {
|
|
1306
|
+
issues.push(
|
|
1307
|
+
measurementIssue(
|
|
1308
|
+
"measurement.hyphen.failed",
|
|
1309
|
+
`Hyphen measurement failed for '${subjectId}'`,
|
|
1310
|
+
subjectId,
|
|
1311
|
+
BLOCKS_MEASUREMENT_KIND,
|
|
1312
|
+
{
|
|
1313
|
+
source,
|
|
1314
|
+
details: { targetId, index: i },
|
|
1315
|
+
severity: "warning"
|
|
1316
|
+
}
|
|
1317
|
+
)
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
} catch (error) {
|
|
1322
|
+
issues.push(
|
|
1323
|
+
measurementIssue(
|
|
1324
|
+
"measurement.block.failed",
|
|
1325
|
+
`Block measurement failed for '${subjectId}'`,
|
|
1326
|
+
subjectId,
|
|
1327
|
+
BLOCKS_MEASUREMENT_KIND,
|
|
1328
|
+
{
|
|
1329
|
+
source,
|
|
1330
|
+
details: { error, targetId, index: i, blockKind: block?.kind },
|
|
1331
|
+
severity: "error"
|
|
1332
|
+
}
|
|
1333
|
+
)
|
|
1334
|
+
);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
ctx.down([
|
|
1338
|
+
[
|
|
1339
|
+
"DATA",
|
|
1340
|
+
[
|
|
1341
|
+
measurementOk(
|
|
1342
|
+
targetId,
|
|
1343
|
+
BLOCKS_MEASUREMENT_KIND,
|
|
1344
|
+
{ blocks: measured },
|
|
1345
|
+
{ source }
|
|
1346
|
+
),
|
|
1347
|
+
...issues
|
|
1348
|
+
]
|
|
1349
|
+
]
|
|
1350
|
+
]);
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
ctx.down([
|
|
1353
|
+
[
|
|
1354
|
+
"DATA",
|
|
1355
|
+
[
|
|
1356
|
+
measurementIssue(
|
|
1357
|
+
"measurement.failed",
|
|
1358
|
+
`Block measurement failed for '${targetId}'`,
|
|
1359
|
+
targetId,
|
|
1360
|
+
BLOCKS_MEASUREMENT_KIND,
|
|
1361
|
+
{ source, details: error, severity: "error" }
|
|
1362
|
+
)
|
|
1363
|
+
]
|
|
1364
|
+
]
|
|
1365
|
+
]);
|
|
1366
|
+
}
|
|
1367
|
+
},
|
|
1368
|
+
{ name }
|
|
1369
|
+
);
|
|
1360
1370
|
}
|
|
1371
|
+
|
|
1372
|
+
// src/solutions/reactive-layout/block.ts
|
|
1361
1373
|
function measureBlock(block, opts) {
|
|
1362
1374
|
const maxWidth = nonNegativeFinite(opts.maxWidth ?? 800, 800);
|
|
1363
1375
|
const marginTop = nonNegativeFinite(block.marginTop ?? 0, 0);
|
|
@@ -1449,6 +1461,8 @@ function computeTotalHeight(blocks) {
|
|
|
1449
1461
|
}
|
|
1450
1462
|
return bottom;
|
|
1451
1463
|
}
|
|
1464
|
+
|
|
1465
|
+
// src/solutions/reactive-layout/flow.ts
|
|
1452
1466
|
function columnGeometry(container, columns) {
|
|
1453
1467
|
const paddingX = nonNegativeFinite(container.paddingX ?? 0, 0);
|
|
1454
1468
|
const paddingY = nonNegativeFinite(container.paddingY ?? 0, 0);
|
|
@@ -1574,6 +1588,8 @@ function computeFlowLines(segments, opts) {
|
|
|
1574
1588
|
done: cursor.segmentIndex >= segments.length
|
|
1575
1589
|
};
|
|
1576
1590
|
}
|
|
1591
|
+
|
|
1592
|
+
// src/solutions/reactive-layout/bundles.ts
|
|
1577
1593
|
function reactiveLayout(opts) {
|
|
1578
1594
|
const { measurements, segmentAdapter: segmentAdapterOpt, name = "reactive-layout" } = opts;
|
|
1579
1595
|
const targetId = opts.targetId ?? "text";
|
|
@@ -1842,17 +1858,47 @@ function reactiveFlowLayout(opts) {
|
|
|
1842
1858
|
}
|
|
1843
1859
|
|
|
1844
1860
|
export {
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1861
|
+
kinsokuStart,
|
|
1862
|
+
leftStickyPunctuation,
|
|
1863
|
+
isCJK,
|
|
1864
|
+
normalizeWhitespace,
|
|
1865
|
+
segmentText,
|
|
1866
|
+
createDefaultSegmentAdapter,
|
|
1867
|
+
getDefaultSegmentAdapter,
|
|
1868
|
+
measuredWidth,
|
|
1869
|
+
metricKey,
|
|
1870
|
+
nonNegativeFinite,
|
|
1871
|
+
finiteNumber,
|
|
1872
|
+
emitLayoutError,
|
|
1873
|
+
positiveFinite,
|
|
1874
|
+
clampDimension,
|
|
1875
|
+
fitSize,
|
|
1876
|
+
blockMaxWidth,
|
|
1877
|
+
resolveTextAdapter,
|
|
1850
1878
|
InjectedMeasureAdapter,
|
|
1851
1879
|
PrecomputedMeasureAdapter,
|
|
1852
1880
|
CellMeasureAdapter,
|
|
1853
1881
|
CapabilityMeasureAdapter,
|
|
1854
1882
|
SvgBoundsAdapter,
|
|
1855
1883
|
ImageSizeAdapter,
|
|
1884
|
+
analyzeAndMeasure,
|
|
1885
|
+
computeLineBreaks,
|
|
1886
|
+
layoutNextLine,
|
|
1887
|
+
carveTextLineSlots,
|
|
1888
|
+
computeCharPositions,
|
|
1889
|
+
TEXT_SEGMENTS_MEASUREMENT_KIND,
|
|
1890
|
+
BLOCKS_MEASUREMENT_KIND,
|
|
1891
|
+
READINESS_MEASUREMENT_KIND,
|
|
1892
|
+
IMAGE_SIZE_MEASUREMENT_KIND,
|
|
1893
|
+
SVG_BOUNDS_MEASUREMENT_KIND,
|
|
1894
|
+
measurementIssue,
|
|
1895
|
+
measurementOk,
|
|
1896
|
+
latestMeasurementValue,
|
|
1897
|
+
tryMeasureHyphenWidth,
|
|
1898
|
+
validMeasurementSize,
|
|
1899
|
+
textMeasurementFacts,
|
|
1900
|
+
inputNode,
|
|
1901
|
+
scopedName,
|
|
1856
1902
|
textMeasurementProvider,
|
|
1857
1903
|
injectedTextMeasurements,
|
|
1858
1904
|
precomputedTextMeasurements,
|
|
@@ -1865,20 +1911,20 @@ export {
|
|
|
1865
1911
|
mergeMeasurements,
|
|
1866
1912
|
blockAdaptersProvider,
|
|
1867
1913
|
blockMeasurementProvider,
|
|
1868
|
-
analyzeAndMeasure,
|
|
1869
|
-
computeLineBreaks,
|
|
1870
|
-
layoutNextLine,
|
|
1871
|
-
carveTextLineSlots,
|
|
1872
|
-
computeCharPositions,
|
|
1873
1914
|
measureBlock,
|
|
1874
1915
|
measureBlocks,
|
|
1875
1916
|
computeBlockFlow,
|
|
1876
1917
|
computeTotalHeight,
|
|
1918
|
+
columnGeometry,
|
|
1919
|
+
sanitizeFlowContainer,
|
|
1920
|
+
sanitizeFlowColumns,
|
|
1921
|
+
sanitizeObstacles,
|
|
1877
1922
|
circleIntervalForBand,
|
|
1878
1923
|
rectIntervalForBand,
|
|
1924
|
+
blockedIntervalsForBand,
|
|
1879
1925
|
computeFlowLines,
|
|
1880
1926
|
reactiveLayout,
|
|
1881
1927
|
reactiveBlockLayout,
|
|
1882
1928
|
reactiveFlowLayout
|
|
1883
1929
|
};
|
|
1884
|
-
//# sourceMappingURL=chunk-
|
|
1930
|
+
//# sourceMappingURL=chunk-4M37FH2I.js.map
|