@moku-labs/game 0.15.18 → 0.15.22

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.
Files changed (37) hide show
  1. package/dist/app/page.d.mts +1 -1
  2. package/dist/app/page.mjs +1 -1
  3. package/dist/app/system.d.mts +3 -3
  4. package/dist/app.d.mts +3 -3
  5. package/dist/app.mjs +1 -1
  6. package/dist/assets.d.mts +1 -1
  7. package/dist/{capture-D7XvoHdH.mjs → capture-PTJXDpxK.mjs} +117 -16
  8. package/dist/{commands-CQt3jo0G.d.mts → commands-BvNp27KS.d.mts} +5 -5
  9. package/dist/control.d.mts +4 -4
  10. package/dist/control.mjs +1 -1
  11. package/dist/{define-BAuGN0UM.d.mts → define-DAVDb7dr.d.mts} +2 -2
  12. package/dist/{headless-uUUH54Ij.d.mts → headless-BCwsb1wR.d.mts} +1 -1
  13. package/dist/{headless-BA6ffzqD.mjs → headless-Bxxl_mQX.mjs} +1 -1
  14. package/dist/{index-ChqvcZwY.d.mts → index-CKXNW8_t.d.mts} +26 -4
  15. package/dist/index.d.mts +5 -5
  16. package/dist/index.mjs +3 -3
  17. package/dist/inspect.d.mts +6 -6
  18. package/dist/inspect.mjs +1 -1
  19. package/dist/jsx-dev-runtime.d.mts +1 -1
  20. package/dist/jsx-runtime.d.mts +1 -1
  21. package/dist/{run-BqYmcNo7.mjs → run-DRcc2SKF.mjs} +2 -2
  22. package/dist/{runtime-BNP4wbDk.d.mts → runtime-Dt7VdhqR.d.mts} +1 -1
  23. package/dist/{sources-BYKXYPhd.mjs → sources-Dpc4NXvG.mjs} +1 -1
  24. package/dist/{src-B6WrtDtL.mjs → src-BcfQy5vB.mjs} +1302 -280
  25. package/dist/testing.d.mts +4 -4
  26. package/dist/testing.mjs +2 -2
  27. package/dist/{types-C4igewxk.d.mts → types-B02c7d6g.d.mts} +21 -5
  28. package/dist/{types-bwefoJES.d.mts → types-BFGyVykz.d.mts} +213 -19
  29. package/dist/{types-DMsvVZZT.d.mts → types-C8JK9u1Y.d.mts} +2 -2
  30. package/dist/{types-BP99ij9v.d.mts → types-COWBfy2L.d.mts} +8 -5
  31. package/dist/{types-DGvpNGxm.d.mts → types-YxQts-fd.d.mts} +4 -4
  32. package/dist/{visual-BdapVgBW.d.mts → visual-Dv67ITPu.d.mts} +6 -6
  33. package/dist/{visual-DNM5oFYx.mjs → visual-kEC9nb-o.mjs} +20 -2
  34. package/dist/visual.d.mts +1 -1
  35. package/dist/visual.mjs +2 -2
  36. package/llms.txt +2 -2
  37. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
- import { Qn as AnyFlow, Xn as FeaturePlugin, cr as Descriptor, fr as Hint, gr as ClockSource, ir as NodeTable, pr as NodeFx, vr as FakeClock, wr as Json } from "./types-bwefoJES.mjs";
2
- import { t as createApp } from "./index-ChqvcZwY.mjs";
3
- import { b as saveOf, v as WithGameState, y as memory } from "./types-DGvpNGxm.mjs";
4
- import { a as createHeadless, i as ReproResult, n as HeadlessGame, o as runRepro, r as Repro, s as stepFrames, t as HeadlessApp } from "./headless-uUUH54Ij.mjs";
1
+ import { $n as AnyFlow, Tr as Json, Zn as FeaturePlugin, _r as ClockSource, ar as NodeTable, lr as Descriptor, mr as NodeFx, pr as Hint, yr as FakeClock } from "./types-BFGyVykz.mjs";
2
+ import { t as createApp } from "./index-CKXNW8_t.mjs";
3
+ import { b as saveOf, v as WithGameState, y as memory } from "./types-YxQts-fd.mjs";
4
+ import { a as createHeadless, i as ReproResult, n as HeadlessGame, o as runRepro, r as Repro, s as stepFrames, t as HeadlessApp } from "./headless-BCwsb1wR.mjs";
5
5
  import { AnyPluginInstance } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/clock/fake.d.ts
package/dist/testing.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { $t as exit, Qt as refuseStart, m as flattenFeatures, nn as type, t as createApp } from "./src-B6WrtDtL.mjs";
1
+ import { $t as refuseStart, en as exit, m as flattenFeatures, rn as type, t as createApp } from "./src-BcfQy5vB.mjs";
2
2
  import { n as saveOf, t as memory } from "./memory-CWlqhS7l.mjs";
3
3
  import { t as fakeClock } from "./fake-6mazmHK3.mjs";
4
- import { i as stepFrames, r as runRepro, t as createHeadless } from "./headless-BA6ffzqD.mjs";
4
+ import { i as stepFrames, r as runRepro, t as createHeadless } from "./headless-Bxxl_mQX.mjs";
5
5
  //#region src/testing/fake-fx.ts
6
6
  /** The node path a refused `fx.start` names when the test gives none. */
7
7
  const defaultPath = "test";
@@ -1,4 +1,4 @@
1
- import { $t as Api$2, An as ReducedMotion, Cn as Ease, Dn as NumericFields, En as MotionHandle, K as Api$3, Nn as ViewHandle, On as ProjectionMotion, Pn as Api$1, Tn as MotionCause, U as TransformValue, Wr as Api, an as AnyComponentType, bn as TagType, cr as Descriptor, ct as ViewportSize, dn as Entity, ei as Require, fr as Hint, hr as Api$5, in as AnyComponent, ln as ComponentType, mr as Answer, on as AnyComponentValue, s as Events$1, t as Api$4, wn as Motion, wr as Json, xn as ChangeHook } from "./types-bwefoJES.mjs";
1
+ import { Dn as MotionHandle, En as MotionCause, Fn as Api$1, Gr as Api, On as NumericFields, Pn as ViewHandle, Sn as ChangeHook, Tn as Motion, Tr as Json, W as TransformValue, an as AnyComponent, en as Api$2, fn as Entity, gr as Api$5, hr as Answer, jn as ReducedMotion, kn as ProjectionMotion, lr as Descriptor, lt as ViewportSize, on as AnyComponentType, pr as Hint, q as Api$3, s as Events$1, sn as AnyComponentValue, t as Api$4, ti as Require, un as ComponentType, wn as Ease, xn as TagType } from "./types-BFGyVykz.mjs";
2
2
  import { Log } from "@moku-labs/common/browser";
3
3
  import { PluginCtx } from "@moku-labs/core";
4
4
  import { Node, Yoga } from "yoga-layout/load";
@@ -157,7 +157,21 @@ type VisualStyle<Asset extends string = string> = {
157
157
  * but `image`, `icon` and `text` takes it; a clipping element (`scroll`, `overflow: "hidden"`)
158
158
  * keeps its rectangle, which carries the clip.
159
159
  */
160
- nineSlice?: Asset; /** Multiplies the colour of a nine-slice or an image. */
160
+ nineSlice?: Asset;
161
+ /**
162
+ * Draws the nine-slice of the style as its rim alone: the eight border pieces, never the
163
+ * centre, so a frame or a glass panel with an empty middle fills no pixel there. `false` by
164
+ * default. Does nothing without `nineSlice`; `lint()` reports it as
165
+ * `hollow-without-nine-slice`. A tap in the middle still lands on the element.
166
+ *
167
+ * @example
168
+ * ```tsx
169
+ * // The frost frame of the memory screen: its rim is drawn, its centre shows the board under it.
170
+ * <stack key="memFrost" style={{ nineSlice: "glass.frost", hollow: true, width: 960, height: 1400 }} />;
171
+ * app.world.ecs.get(app.ui.find("memFrost") ?? 0, NineSlice)?.hollow; // true
172
+ * ```
173
+ */
174
+ hollow?: boolean; /** Multiplies the colour of a nine-slice or an image. */
161
175
  tint?: number;
162
176
  /**
163
177
  * Outlines the nine-slice of the style: its bounds and the four slice lines, cyan, red when
@@ -2685,7 +2699,8 @@ type Element = {
2685
2699
  height: number;
2686
2700
  };
2687
2701
  measuredWidth?: number | undefined; /** True once the text wrapped at its box: from then on `ui` writes its box, 0 when it fits. */
2688
- boxed?: boolean;
2702
+ boxed?: boolean; /** True once its nine-slice was hollow: from then on `ui` writes `hollow`, false when the style drops it. */
2703
+ hollowed?: boolean;
2689
2704
  basis?: StyleBasis; /** The motions of its hooks that started a `repeat: "forever"` track; made with the first one. */
2690
2705
  endless?: Set<MotionHandle>; /** What its enter hook did at the `Box`, until `ui.enter` keeps the play or plays it again (F49). */
2691
2706
  posed?: PosedEnter | undefined;
@@ -2895,7 +2910,8 @@ type JsxState = {
2895
2910
  byIdentity: Map<string, Entity>;
2896
2911
  byKey: Map<Entity, Map<string, Entity>>;
2897
2912
  instances: Map<string, Instance>;
2898
- exiting: Set<Entity>;
2913
+ exiting: Set<Entity>; /** The tops of roots that left with their screen and whose own exit plays: each goes when that exit ends (F55). */
2914
+ leading: Set<Entity>;
2899
2915
  removing: Set<Entity>;
2900
2916
  hosts: Set<Entity>;
2901
2917
  hosted: Map<Entity, Entity>;
@@ -3016,7 +3032,7 @@ type UiNode = {
3016
3032
  * ```
3017
3033
  */
3018
3034
  type Finding = {
3019
- rule: "tap-target" | "text-overflow" | "absolute-without-reason" | "nine-slice-clipped" | "z-index-on-root";
3035
+ rule: "tap-target" | "text-overflow" | "absolute-without-reason" | "nine-slice-clipped" | "hollow-without-nine-slice" | "z-index-on-root";
3020
3036
  key: string;
3021
3037
  detail: string;
3022
3038
  };
@@ -7681,6 +7681,15 @@ type HostInternal = {
7681
7681
  * @returns True when it called Pixi.
7682
7682
  */
7683
7683
  renderProbe(container: PixiContainer, target?: PixiRenderTexture): boolean;
7684
+ /**
7685
+ * Puts a texture source on the GPU now with Pixi's public `renderer.texture.initSource(source)`: the GPU texture is
7686
+ * made and the pixels are uploaded, once; a source Pixi made already costs a lookup. Called by the upload queue of
7687
+ * `sync` before the stage pass of a drawn frame. A no-op while nothing draws. What Pixi throws is thrown on: the
7688
+ * caller logs it and counts the source done.
7689
+ *
7690
+ * @param source - The source of a texture `assets` loaded.
7691
+ */
7692
+ initSource(source: PixiTextureSource): void;
7684
7693
  /**
7685
7694
  * Tells whether the stage pass clears the canvas before it draws (`renderer.background.clearBeforeRender`, Pixi's
7686
7695
  * default, which the engine never turns off): only then may a probe draw onto the canvas.
@@ -7911,7 +7920,17 @@ type KeptRecord = {
7911
7920
  depth: number; /** Bytes of s1, s2, s3 (estimate, P6.1). */
7912
7921
  bytes: number; /** A settle retake is owed: the view came to rest off its picture's grid (P2.5). */
7913
7922
  settle: boolean; /** Bytes a refused take asked for; the record is not offered again until they fit (P6.3). */
7914
- refused: number; /** A view of kind `"Display"` hangs in the subtree; `undefined` until a take attempt walks it (P4.1). */
7923
+ refused: number;
7924
+ /**
7925
+ * The picture was cut to the canvas at its take (F53): a move or another canvas size would show what it left out,
7926
+ * so either takes it again.
7927
+ */
7928
+ cut: boolean;
7929
+ /**
7930
+ * The quad draws the subtree picture itself at the stack's alpha, with no stage 3 (F54): every enabled filter is an
7931
+ * `AlphaFilter` at the canvas resolution.
7932
+ */
7933
+ direct: boolean; /** A view of kind `"Display"` hangs in the subtree; `undefined` until a take attempt walks it (P4.1). */
7915
7934
  displays: boolean | undefined;
7916
7935
  };
7917
7936
  /** One picture of an overlay's range (P7), keyed by the owner overlay's entity. */
@@ -9017,7 +9036,7 @@ type PictureRequest = {
9017
9036
  reject: (error: Error) => void;
9018
9037
  };
9019
9038
  declare namespace types_d_exports$2 {
9020
- export { AdaptiveScale, Api$1 as Api, AspectRange, BitmapFontData, CaptureOptions, Captured, Config$2 as Config, CountingClasses, CoverFrame, CreateTextureOptions$1 as CreateTextureOptions, DebugApi, DebugSwitches, DemandFrame, DemandModule, DemandReason, DemandState, Deps$2 as Deps, DisplayAdapter, DisplayEntry, DisplaysApi, DrawCounter, Events$2 as Events, FilterCache, FilterSlot, FilterSlotInputs, FiltersApi, FontsApi, FrameColumns, FrameReadResult, FrameReadout, FrameRecord, FrameRing, HitBox, HostApi, HostInternal, HostModule, HostState, HudPartValue, KeptInternal, KeptModule, KeptRange, KeptState, KeptStats, KernelSlice$2 as KernelSlice, LayerEntry, LegendEntry, LongFrameEntry, Modules, MonitorApi, MonitorConfig, MonitorCounts, MonitorDeps, MonitorInternal, MonitorModule, MonitorSections, MonitorState, NineBorders$1 as NineBorders, Orientation, OverlayEventDetail, OverlayLevelValue, OverlayMode, OverlayPhase, OverlayReport, OverlayValue, OverlayWhat, PassKind, PassRecord, PerfCause, PerfChange, PerfChangeEntry, PerfCollectorLine, PerfCounts, PerfDisplay, PerfEventLine, PerfEventName, PerfGapLine, PerfHeaderLine, PerfLogLine, PerfLongFrameLine, PerfMarkLine, PerfMeasured, PerfMonitorApi, PerfSampleLine, PerfSpikeLine, PerfStartupLine, PerfTelemetryLine, PerfThermalLine, PictureRect, PixiApplication, PixiBitmapFont, PixiBounds, PixiContainer, PixiFilter, PixiFilterManager, PixiGraphics, PixiMatrix, PixiModule, PixiNineSliceSprite, PixiRectangle, PixiRenderTexture, PixiSprite, PixiTexture, Point, PoolTrim, PoolTrimDetail, ProblemEventDetail, ProblemRule, Rect, RenderStats, RendererCtx, RendererKind, SafeArea, ShaderEventDetail, ShaderWhat, SliceFrame, State$2 as State, SyncApi, SyncCounts, SyncInternal, SyncModule, SyncState, TeardownScope, TextureProvider, TextureUsage, TexturesApi, Under, View, ViewKind, ViewportApi, ViewportInternal, ViewportModule, ViewportSize, ViewportState, WarmDetail };
9039
+ export { AdaptiveScale, Api$1 as Api, AspectRange, BitmapFontData, CaptureOptions, Captured, Config$2 as Config, CountingClasses, CoverFrame, CreateTextureOptions$1 as CreateTextureOptions, DebugApi, DebugSwitches, DemandFrame, DemandModule, DemandReason, DemandState, Deps$2 as Deps, DisplayAdapter, DisplayEntry, DisplaysApi, DrawCounter, Events$2 as Events, FilterCache, FilterSlot, FilterSlotInputs, FiltersApi, FontsApi, FrameColumns, FrameReadResult, FrameReadout, FrameRecord, FrameRing, HitBox, HostApi, HostInternal, HostModule, HostState, HudPartValue, KeptInternal, KeptModule, KeptRange, KeptState, KeptStats, KernelSlice$2 as KernelSlice, LayerEntry, LegendEntry, LongFrameEntry, Modules, MonitorApi, MonitorConfig, MonitorCounts, MonitorDeps, MonitorInternal, MonitorModule, MonitorSections, MonitorState, NineBorders$1 as NineBorders, Orientation, OverlayEventDetail, OverlayLevelValue, OverlayMode, OverlayPhase, OverlayReport, OverlayValue, OverlayWhat, PassKind, PassRecord, PerfCause, PerfChange, PerfChangeEntry, PerfCollectorLine, PerfCounts, PerfDisplay, PerfEventLine, PerfEventName, PerfGapLine, PerfHeaderLine, PerfLogLine, PerfLongFrameLine, PerfMarkLine, PerfMeasured, PerfMonitorApi, PerfSampleLine, PerfSpikeLine, PerfStartupLine, PerfTelemetryLine, PerfThermalLine, PictureRect, PixiApplication, PixiBitmapFont, PixiBounds, PixiContainer, PixiFilter, PixiFilterManager, PixiGraphics, PixiMatrix, PixiMesh, PixiModule, PixiNineSliceSprite, PixiRectangle, PixiRenderTexture, PixiSprite, PixiTexture, PixiTextureSource, Point, PoolTrim, PoolTrimDetail, ProblemEventDetail, ProblemRule, Rect, RenderStats, RendererCtx, RendererKind, SafeArea, ShaderEventDetail, ShaderWhat, SliceFrame, State$2 as State, SyncApi, SyncCounts, SyncInternal, SyncModule, SyncState, TeardownScope, TextureProvider, TextureUsage, TexturesApi, Under, View, ViewKind, ViewportApi, ViewportInternal, ViewportModule, ViewportSize, ViewportState, WarmDetail };
9021
9040
  }
9022
9041
  /**
9023
9042
  * The part of Pixi the engine uses: the classes `sync` builds views from (a `Rectangle` frames the
@@ -9031,7 +9050,8 @@ declare namespace types_d_exports$2 {
9031
9050
  * batched distance-field text `host` installs: Pixi's `Batcher` with its geometry and buffers, the bitmap text pipe
9032
9051
  * and the batcher pipe it subclasses, and the WGSL and GLSL shader pieces of the batch's SDF shader, and the WebGPU
9033
9052
  * render target system with its adaptor, the pipeline system and the stencil system the lazy canvas pass of `host`
9034
- * subclasses or registers again (`host/render-pass.ts`). The module object
9053
+ * subclasses or registers again (`host/render-pass.ts`), and the mesh and its geometry the rim-only nine-slice of
9054
+ * `sync` is drawn with (`sync/hollow.ts`). The module object
9035
9055
  * never arrives through a static import: `config.loadPixi()` returns it, so a game without a screen carries no
9036
9056
  * Pixi in its bundle.
9037
9057
  *
@@ -9047,7 +9067,7 @@ declare namespace types_d_exports$2 {
9047
9067
  * pixi.defaultFilterVert.startsWith("in vec2 aPosition;"); // true
9048
9068
  * ```
9049
9069
  */
9050
- type PixiModule = Pick<typeof import("pixi.js"), "AlphaFilter" | "Application" | "Batcher" | "BatcherPipe" | "BitmapFont" | "BitmapText" | "BitmapTextPipe" | "BlurFilter" | "Bounds" | "Buffer" | "BufferUsage" | "Cache" | "ColorMatrixFilter" | "Container" | "DefaultBatcher" | "DisplacementFilter" | "ExtensionType" | "Filter" | "FilterSystem" | "Geometry" | "GlProgram" | "GlTextureSystem" | "GpuBatchAdaptor" | "GpuEncoderSystem" | "GpuGraphicsAdaptor" | "GpuProgram" | "GpuRenderTargetAdaptor" | "GpuRenderTargetSystem" | "GpuStencilSystem" | "GpuTextureSystem" | "Graphics" | "Matrix" | "NineSliceSprite" | "NoiseFilter" | "Particle" | "ParticleContainer" | "PipelineSystem" | "Rectangle" | "RenderGroupPipe" | "RenderTexture" | "Shader" | "Sprite" | "Texture" | "TexturePool" | "UniformGroup" | "bitmapFontTextParser" | "bitmapFontXMLStringParser" | "colorBit" | "colorBitGl" | "compileHighShaderGlProgram" | "compileHighShaderGpuProgram" | "defaultFilterVert" | "extensions" | "generateTextureBatchBit" | "generateTextureBatchBitGl" | "getBatchSamplersUniformGroup" | "mSDFBit" | "mSDFBitGl" | "roundPixelsBit" | "roundPixelsBitGl">;
9070
+ type PixiModule = Pick<typeof import("pixi.js"), "AlphaFilter" | "Application" | "Batcher" | "BatcherPipe" | "BitmapFont" | "BitmapText" | "BitmapTextPipe" | "BlurFilter" | "Bounds" | "Buffer" | "BufferUsage" | "Cache" | "ColorMatrixFilter" | "Container" | "DefaultBatcher" | "DisplacementFilter" | "ExtensionType" | "Filter" | "FilterSystem" | "Geometry" | "GlProgram" | "GlTextureSystem" | "GpuBatchAdaptor" | "GpuEncoderSystem" | "GpuGraphicsAdaptor" | "GpuProgram" | "GpuRenderTargetAdaptor" | "GpuRenderTargetSystem" | "GpuStencilSystem" | "GpuTextureSystem" | "Graphics" | "Matrix" | "Mesh" | "MeshGeometry" | "NineSliceSprite" | "NoiseFilter" | "Particle" | "ParticleContainer" | "PipelineSystem" | "Rectangle" | "RenderGroupPipe" | "RenderTexture" | "Shader" | "Sprite" | "Texture" | "TexturePool" | "UniformGroup" | "bitmapFontTextParser" | "bitmapFontXMLStringParser" | "colorBit" | "colorBitGl" | "compileHighShaderGlProgram" | "compileHighShaderGpuProgram" | "defaultFilterVert" | "extensions" | "generateTextureBatchBit" | "generateTextureBatchBitGl" | "getBatchSamplersUniformGroup" | "mSDFBit" | "mSDFBitGl" | "roundPixelsBit" | "roundPixelsBitGl">;
9051
9071
  /**
9052
9072
  * One Pixi application: renderer, canvas and stage.
9053
9073
  */
@@ -9069,6 +9089,10 @@ type PixiSprite = InstanceType<PixiModule["Sprite"]>;
9069
9089
  * A Pixi nine-slice sprite.
9070
9090
  */
9071
9091
  type PixiNineSliceSprite = InstanceType<PixiModule["NineSliceSprite"]>;
9092
+ /**
9093
+ * A Pixi mesh: what the rim-only nine-slice of a `NineSlice` with `hollow: true` is drawn with.
9094
+ */
9095
+ type PixiMesh = InstanceType<PixiModule["Mesh"]>;
9072
9096
  /**
9073
9097
  * A Pixi graphics object: what a `Shape` component is drawn with, and what clips its children.
9074
9098
  */
@@ -9077,6 +9101,11 @@ type PixiGraphics = InstanceType<PixiModule["Graphics"]>;
9077
9101
  * A Pixi texture. `assets` owns its lifetime; the renderer only makes and destroys it on request.
9078
9102
  */
9079
9103
  type PixiTexture = InstanceType<PixiModule["Texture"]>;
9104
+ /**
9105
+ * The source of a Pixi texture: the pixels the GPU holds once, shared by every slice of an atlas page. What the
9106
+ * upload queue of `sync.textures.upload` hands to Pixi's texture system.
9107
+ */
9108
+ type PixiTextureSource = PixiTexture["source"];
9080
9109
  /**
9081
9110
  * A texture Pixi renders into: what a kept picture is drawn into, engine-owned and destroyed by the engine.
9082
9111
  */
@@ -9206,6 +9235,8 @@ type AdaptiveScale = {
9206
9235
  * createApp({ pluginConfigs: { renderer: { mount: "#game", keptMb: 32 } } }); // a game with small art
9207
9236
  * // A short splash: two probe draws a frame create the pipelines sooner.
9208
9237
  * createApp({ pluginConfigs: { renderer: { mount: "#game", onDemand: true, warm: 2 } } });
9238
+ * // A desktop game with a fast GPU: `assets.warm` puts two textures a drawn frame on the GPU instead of one.
9239
+ * createApp({ pluginConfigs: { renderer: { mount: "#game", uploads: 2 } } });
9209
9240
  * // A game whose art must stay sharp: the adaptive frame rate drops the rate, never the resolution.
9210
9241
  * createApp({ pluginConfigs: { renderer: { mount: "#game", adaptiveScale: false } } });
9211
9242
  * ```
@@ -9255,6 +9286,22 @@ type Config$2 = {
9255
9286
  * created in the first frame that draws with it, as before. A whole number from 0 to 16; default 1.
9256
9287
  */
9257
9288
  warm: number;
9289
+ /**
9290
+ * Textures `sync.textures.upload` (what `assets.warm` calls) puts on the GPU per drawn frame, before the stage pass,
9291
+ * so the frame that first shows them does not upload them all at once. One upload costs about 9 ms on a Galaxy A26
9292
+ * whatever its size (median, 41 ms at worst): the show frame of 6 cold textures (9.4 MB) took 55 ms there, 8 ms with
9293
+ * them uploaded before. So the budget counts textures, not bytes. 0 turns the queue off: `upload` answers false and
9294
+ * the first draw of a texture uploads it, as before. A whole number from 0 to 8; default 1.
9295
+ *
9296
+ * @example
9297
+ * ```ts
9298
+ * // The memory screen's 6 textures, warmed while the board still shows: 3 drawn frames at 2 a frame.
9299
+ * const app = createApp({ pluginConfigs: { renderer: { mount: "#game", uploads: 2 } } });
9300
+ * await app.start();
9301
+ * await app.assets.warm("ep01.memory"); // resolves after the third drawn frame
9302
+ * ```
9303
+ */
9304
+ uploads: number;
9258
9305
  /**
9259
9306
  * The render scale of the adaptive frame rate on a GPU-bound screen: `{ floor: 0.75, devices: "phone" }` by default,
9260
9307
  * `false` keeps the resolution. Needs `time.adaptive`. A player's `monitor.setResolution` wins over it. Every change
@@ -9539,7 +9586,8 @@ type SpriteValue = {
9539
9586
  * strokes the bounds and the four cut lines over the panel: cyan, red when the corners overlap or
9540
9587
  * the texture is missing. `clip` masks the children of the entity to the `width × height` box,
9541
9588
  * the same rule as `Shape.clip`: the mask is a filled rectangle and is never drawn, and the panel
9542
- * itself is never masked. `alpha` fades the panel and the entity's children.
9589
+ * itself is never masked. `alpha` fades the panel and the entity's children. `hollow` draws the
9590
+ * rim alone: the eight border pieces, never the centre.
9543
9591
  *
9544
9592
  * @example
9545
9593
  * ```ts
@@ -9555,6 +9603,10 @@ type SpriteValue = {
9555
9603
  * const field: NineSliceValue = {
9556
9604
  * ...value, texture: "ui.field", width: 480, height: 96, clip: true
9557
9605
  * };
9606
+ * // The frost frame of the memory screen: its rim is drawn, its empty centre costs no pixel.
9607
+ * const frost: NineSliceValue = {
9608
+ * ...value, texture: "glass.frost", width: 960, height: 1400, hollow: true
9609
+ * };
9558
9610
  * ```
9559
9611
  */
9560
9612
  type NineSliceValue = {
@@ -9565,6 +9617,20 @@ type NineSliceValue = {
9565
9617
  tint: number;
9566
9618
  debug: boolean;
9567
9619
  clip: boolean;
9620
+ /**
9621
+ * Draws the rim alone: the four corners and the four edges of the slicing, never the centre cell, so a frame or a
9622
+ * glass panel whose middle is empty fills no pixel there. The hit box stays the whole `width × height`, and `debug`
9623
+ * and `clip` work as on a filled panel. Absent by default, read as `false`, so a panel that never sets it keeps the
9624
+ * values it had before the field existed.
9625
+ *
9626
+ * @example
9627
+ * ```ts
9628
+ * // A 960 x 1400 frame over the memory board, its slices 48 u wide: 8 rim pieces are drawn, the 864 x 1304 centre
9629
+ * // is not, and a tap in the middle still lands on the frame's entity.
9630
+ * world.ecs.spawn(owner, [Layer({ name: "ui" }), Transform(), NineSlice({ texture: "glass.frost", width: 960, height: 1400, hollow: true })]);
9631
+ * ```
9632
+ */
9633
+ hollow?: boolean;
9568
9634
  };
9569
9635
  /**
9570
9636
  * The escape hatch: the game owns a Pixi object and `sync` only attaches and detaches it.
@@ -9712,16 +9778,9 @@ declare const Sprite: ComponentType<SpriteValue>;
9712
9778
  /**
9713
9779
  * A stretchable panel, sized in reference units, with its own alpha and tint. `debug: true` draws
9714
9780
  * the slice outline over it. `clip: true` masks the children of the entity to the panel box.
9781
+ * `hollow: true` draws its rim alone, never the centre cell.
9715
9782
  */
9716
- declare const NineSlice$1: ComponentType<{
9717
- texture: string;
9718
- width: number;
9719
- height: number;
9720
- alpha: number;
9721
- tint: number;
9722
- debug: boolean;
9723
- clip: boolean;
9724
- }>;
9783
+ declare const NineSlice$1: ComponentType<NineSliceValue>;
9725
9784
  /**
9726
9785
  * The entity this view moves with. `0` means no parent.
9727
9786
  */
@@ -10084,6 +10143,29 @@ type TexturesApi = {
10084
10143
  * ```
10085
10144
  */
10086
10145
  invalidate(keys: readonly string[]): void;
10146
+ /**
10147
+ * Puts textures on the GPU before a screen shows them: each texture's source is queued once and uploaded with Pixi's
10148
+ * `renderer.texture.initSource` before the stage pass of a drawn frame, `renderer.uploads` a frame (one by default),
10149
+ * and the renderer asks for the next frame while sources wait. The slices of one atlas page share its source, so the
10150
+ * page is uploaded once. On a Galaxy A26 one upload costs about 9 ms whatever its size: the frame that showed 6 cold
10151
+ * textures took 55 ms, 8 ms once they were uploaded before. Answers `true` once every source of this call went
10152
+ * through, at once when they all did on this device; `false` at once while nothing draws (headless, a lost device)
10153
+ * or with `uploads: 0`, and `false` when the renderer stops or the device is lost before the queue reached them. A
10154
+ * source whose upload throws is logged (`renderer:upload-failed`) and counted done: its first draw uploads it, as
10155
+ * before. A source destroyed while it waits is skipped. The renderer never destroys a texture it was handed.
10156
+ *
10157
+ * @param textures - The textures; `assets` hands every texture and page of a bundle it loaded.
10158
+ * @returns Whether every source is on the GPU.
10159
+ * @example
10160
+ * ```ts
10161
+ * // `assets.warm("ep01.memory")`: the bundle is loaded; its 6 textures go to the GPU while the board still shows.
10162
+ * const renderer = ctx.require(rendererPlugin);
10163
+ * const textures = [...record.textures.values(), ...record.pages.values()];
10164
+ * const uploaded = await renderer.sync.textures.upload(textures); // true 6 drawn frames later (uploads: 1)
10165
+ * await renderer.sync.textures.upload(textures); // true at once: they are on this device already
10166
+ * ```
10167
+ */
10168
+ upload(textures: readonly PixiTexture[]): Promise<boolean>;
10087
10169
  };
10088
10170
  /**
10089
10171
  * The display registry a plugin above extends, `app.renderer.sync.displays`. `Sprite`,
@@ -10720,6 +10802,14 @@ type SyncInternal = {
10720
10802
  * @returns True when it drew a probe in this frame: the frame is then no sample of the adaptive rate.
10721
10803
  */
10722
10804
  warmStep(): boolean;
10805
+ /**
10806
+ * Uploads up to `renderer.uploads` queued texture sources (F60), in a drawn frame, right after the warm-up's probes
10807
+ * and before the stage pass. Asks for the next frame while sources wait. One compare and no allocation while the
10808
+ * queue is empty.
10809
+ *
10810
+ * @returns True when it uploaded a source in this frame: the frame is then no sample of the adaptive rate.
10811
+ */
10812
+ uploadStep(): boolean;
10723
10813
  /**
10724
10814
  * Subscribes to the end of a warm-up run: the queue became empty (the monitor of an agent build writes the `warm`
10725
10815
  * event line). Emptied by `stopSync`.
@@ -10838,6 +10928,60 @@ type WarmState = {
10838
10928
  reported: Set<unknown>;
10839
10929
  listeners: WarmListener[];
10840
10930
  };
10931
+ /**
10932
+ * One call of `textures.upload` that waits: how many of its sources are still queued, and its answer. Not public.
10933
+ */
10934
+ type UploadWaiter = {
10935
+ left: number;
10936
+ resolve: (ok: boolean) => void;
10937
+ };
10938
+ /**
10939
+ * The texture upload queue (F60): the sources not yet uploaded from `head` on, emptied when the head reaches the end
10940
+ * (the warm-up's pattern); for each queued source the calls that wait for it; the sources uploaded on this device. A
10941
+ * step with an empty queue reads two numbers. Not public.
10942
+ */
10943
+ type UploadState = {
10944
+ /** The sources to upload, from `head` on; each queued once. */queue: PixiTextureSource[];
10945
+ head: number;
10946
+ /**
10947
+ * The calls each queued source is waited for by, in call order: a source in it is in the queue, and every call that
10948
+ * waits is in it under one of its sources. Answered `false` when the renderer stops or the device is lost.
10949
+ */
10950
+ waiting: Map<PixiTextureSource, UploadWaiter[]>;
10951
+ /**
10952
+ * The sources that went through `initSource` on this device, or threw there: a call naming only these answers at
10953
+ * once.
10954
+ */
10955
+ done: WeakSet<PixiTextureSource>;
10956
+ };
10957
+ /**
10958
+ * What a nine-slice view's object offers `sync`, whichever class draws it: Pixi's `NineSliceSprite`, or the engine's
10959
+ * rim-only mesh of a `hollow` one (`hollow.ts`). The six numbers rebuild the panel when written, the tint and the
10960
+ * texture are written as on a sprite. Not public.
10961
+ */
10962
+ type SliceLike = PixiContainer & {
10963
+ leftWidth: number;
10964
+ topHeight: number;
10965
+ rightWidth: number;
10966
+ bottomHeight: number;
10967
+ width: number;
10968
+ height: number;
10969
+ tint: number;
10970
+ texture: PixiTexture;
10971
+ };
10972
+ /**
10973
+ * The engine's rim-only nine-slice (F59): a Pixi `Mesh` of 16 vertices and 48 indices, the eight border cells of the
10974
+ * slicing and never the centre, driven through the same numbers as a `NineSliceSprite`. `hollow` tells it apart. Not
10975
+ * public.
10976
+ */
10977
+ type HollowSlice = SliceLike & {
10978
+ readonly hollow: true;
10979
+ };
10980
+ /**
10981
+ * The class of the rim-only nine-slice, made once over the Pixi module the renderer loaded (Pixi arrives lazily, so
10982
+ * the class cannot be declared at import). Built with the texture it draws first. Not public.
10983
+ */
10984
+ type HollowClass = new (texture: PixiTexture) => HollowSlice;
10841
10985
  /**
10842
10986
  * Where the overlay step's event lines go: the monitor's `event`. Private to the renderer.
10843
10987
  */
@@ -11012,7 +11156,9 @@ type SyncState = {
11012
11156
  * view, so a still frame walks no entry.
11013
11157
  */
11014
11158
  viewlessEntries: boolean; /** The pipeline warm-up (F4). */
11015
- warm: WarmState;
11159
+ warm: WarmState; /** The texture upload queue (F60). */
11160
+ upload: UploadState; /** The class of the rim-only nine-slice (F59), made at the first hollow view over the loaded Pixi module. */
11161
+ hollowClass: HollowClass | undefined;
11016
11162
  /**
11017
11163
  * The kind of each Pixi filter a slot named, for the performance log of an agent build; a
11018
11164
  * blur's two passes are filters of their own and are in it too. Empty in a production build.
@@ -11410,7 +11556,7 @@ type RunContext = {
11410
11556
  signal: AbortSignal;
11411
11557
  };
11412
11558
  declare namespace types_d_exports {
11413
- export { Api, AssetKind, AssetStamps, AssetsCtx, AssetsIo, AtlasFrame, AtlasPage, AudioAsset, AudioMime, BundleCompanion, BundleMap, BundleRecord, BundleRelease, BundleSpec, BundleUsage, Config, CreateTextureOptions, DecodedImage, DefineBundles, Deps, Events, FetchResponse, FlowRest, FontAsset, FontPage, HotSwap, Inflight, KernelSlice, LoadBundles, LoadReason, LoadResult, LoadedAssets, LoadedFont, Manifest, ManifestBundle, ManifestFile, NineBorders, NineSlice, PreloadQueue, State, Texture, Tier, Usage };
11559
+ export { Api, AssetKind, AssetStamps, AssetsCtx, AssetsIo, AtlasFrame, AtlasPage, AudioAsset, AudioMime, BundleCompanion, BundleMap, BundleRecord, BundleRelease, BundleSpec, BundleUsage, Config, CreateTextureOptions, DecodedImage, DefineBundles, Deps, Events, FetchResponse, FlowRest, FontAsset, FontPage, HotSwap, Inflight, KernelSlice, LoadBundles, LoadReason, LoadResult, LoadedAssets, LoadedFont, Manifest, ManifestBundle, ManifestFile, NineBorders, NineSlice, PreloadQueue, ReadyBundles, State, Texture, Tier, Usage, WarmEntry };
11414
11560
  }
11415
11561
  /**
11416
11562
  * When a bundle is loaded. `boot` and `core` stay for the whole session, `scene` and `feature`
@@ -11808,6 +11954,18 @@ type DefineBundles<Key extends string> = (map: Partial<Record<Key, BundleSpec>>)
11808
11954
  * ```
11809
11955
  */
11810
11956
  type LoadBundles<Key extends string> = (bundle: Key | readonly Key[]) => Descriptor<LoadResult | undefined>;
11957
+ /**
11958
+ * The `ready` descriptor helper bound to the bundle keys of one game (F52). The descriptor resolves
11959
+ * `true` when every bundle is loaded and on the GPU, `false` while the node should rest until the
11960
+ * inbox event `ready`, or `undefined` in an app without `assets`.
11961
+ *
11962
+ * @example
11963
+ * ```ts
11964
+ * const readyGameBundle: ReadyBundles<"board" | "board.chains"> = ready;
11965
+ * readyGameBundle("board"); // { kind: "ready", payload: { bundles: ["board"] } }
11966
+ * ```
11967
+ */
11968
+ type ReadyBundles<Key extends string> = (bundle: Key | readonly Key[]) => Descriptor<boolean | undefined>;
11811
11969
  /**
11812
11970
  * What the `load` effect resolves with, so a loading node can write its own progress.
11813
11971
  *
@@ -11912,6 +12070,15 @@ type PreloadQueue = {
11912
12070
  bundles: string[];
11913
12071
  controller: AbortController;
11914
12072
  };
12073
+ /**
12074
+ * One warm of a bundle (F60): the promise every caller of `warm` joins, and `done` once it
12075
+ * resolved, so the `ready` effect answers without waiting. Dropped when the bundle unloads, and
12076
+ * when the warm fails, so the next call tries again.
12077
+ */
12078
+ type WarmEntry = {
12079
+ promise: Promise<void>;
12080
+ done: boolean;
12081
+ };
11915
12082
  /**
11916
12083
  * What the keys watch of `moku-game dev` knows about the asset files of a game: the default export
11917
12084
  * of the generated `.moku/assets-stamp.ts`. The dev hot swap compares it with the map it applied
@@ -11968,8 +12135,8 @@ type State = {
11968
12135
  useCounter: number; /** Keys already reported missing, so one key warns and starts its background load once. */
11969
12136
  warned: Set<string>;
11970
12137
  /**
11971
- * `onEnter`, the `load` handler, the texture provider, the start and the end of an exit in `world`, and the system
11972
- * `assets.leave` of phase `sync`.
12138
+ * `onEnter`, the `load` and `ready` handlers, the texture provider, the start and the end of an exit in `world`,
12139
+ * and the system `assets.leave` of phase `sync`.
11973
12140
  */
11974
12141
  removers: Array<() => void>; /** The `files` map of the stamp the dev hot swap applied last. `undefined` until the first swap. */
11975
12142
  stamps: Readonly<Record<string, string>> | undefined; /** The running dev hot swap. The next one waits for it, so two swaps never overlap. */
@@ -11983,6 +12150,12 @@ type State = {
11983
12150
  exiting: number; /** Registered companions, in registration order. */
11984
12151
  companions: BundleCompanion[]; /** A live rest was announced; the arriving node's `load` stage runs the release. */
11985
12152
  restPending: boolean;
12153
+ /**
12154
+ * Bundles whose warm for a `ready` effect failed (not an abort): `ready` counts them as there, so a node never
12155
+ * hangs on them, until a later load of the bundle succeeds (F52).
12156
+ */
12157
+ readyFailed: Set<string>; /** One running or finished warm per bundle, joined by a second `warm`; dropped when the bundle unloads (F60). */
12158
+ warmed: Map<string, WarmEntry>;
11986
12159
  };
11987
12160
  /**
11988
12161
  * What `usage()` reports about one loaded bundle.
@@ -12110,6 +12283,27 @@ type Api = {
12110
12283
  * ```
12111
12284
  */
12112
12285
  load(bundle: string): Promise<void>;
12286
+ /**
12287
+ * Puts the textures of a bundle on the GPU before a scene shows them (F60): loads the bundle when
12288
+ * it is not loaded, then hands every texture and atlas page of it to
12289
+ * `renderer.sync.textures.upload`, which uploads `renderer.uploads` of them a drawn frame. A
12290
+ * second call joins the running or finished warm of the same bundle; an unload forgets it, so a
12291
+ * reload warms again. It resolves also when the renderer could not upload (no device,
12292
+ * `uploads: 0`, a stop): the first draw uploads then, as before. Headless it resolves at once,
12293
+ * as `load` does. The `ready` effect waits for it.
12294
+ *
12295
+ * @param bundle - Name of a bundle of the manifest.
12296
+ * @returns A promise that resolves once the bundle is loaded and its textures went to the GPU.
12297
+ * @throws {Error} When the manifest has no such bundle, and when a file fails to load.
12298
+ * @example
12299
+ * ```ts
12300
+ * // Outside a node: the board's art goes to the GPU while the menu still shows.
12301
+ * await app.assets.warm("ep01.board"); // the board's textures are on the GPU, 1 per drawn frame
12302
+ * app.assets.isLoaded("ep01.board"); // true
12303
+ * await app.assets.warm("ep01.board"); // at once: the same warm, nothing is uploaded twice
12304
+ * ```
12305
+ */
12306
+ warm(bundle: string): Promise<void>;
12113
12307
  /**
12114
12308
  * Destroys the textures of a bundle and tells `renderer` that its keys are gone; every
12115
12309
  * companion's `unload` runs. A pinned bundle and the tiers `boot` and `core` are refused with a
@@ -12337,4 +12531,4 @@ type BundleCompanion = {
12337
12531
  unload(bundle: string): void;
12338
12532
  };
12339
12533
  //#endregion
12340
- export { PoolTrim as $, Bookmark as $n, Events$8 as $r, Api$2 as $t, HudPart as A, ReducedMotion as An, ProviderCall as Ar, PerfCounts as At, SpriteOptions as B, Position as Bn, Events$6 as Br, PerfSampleLine as Bt, State$1 as C, Ease as Cn, Events$5 as Cr, PROBLEM_RULES as Ct, FilterSlotInputs as D, NumericFields as Dn, types_d_exports$6 as Dr, PerfChange as Dt, FilterSlot as E, MotionHandle as En, State$6 as Er, PerfCause as Et, OverlayValue as F, BundlesOf as Fn, StoreApi as Fr, PerfHeaderLine as Ft, AdaptiveScale as G, exit as Gn, Config$8 as Gr, PoolTrimDetail as Gt, Transform as H, TextStylesOf as Hn, State$7 as Hr, PerfStartupLine as Ht, Parent as I, Config$4 as In, RngApi as Ir, PerfLogLine as It, MonitorConfig as J, type as Jn, State$8 as Jr, SHADER_WHATS as Jt, Api$1 as K, slot as Kn, FrameRate as Kr, ProblemEventDetail as Kt, Shape as L, EmitterIdOf as Ln, RngState as Lr, PerfLongFrameLine as Lt, NineSlice$1 as M, TrackSegment as Mn, SaveUnreadableError as Mr, PerfEventLine as Mt, NineSliceValue as N, ViewHandle as Nn, Snapshot as Nr, PerfEventName as Nt, SyncApi as O, ProjectionMotion as On, Patch as Or, PerfChangeEntry as Ot, Overlay as P, Api$3 as Pn, SnapshotOf as Pr, PerfGapLine as Pt, PixiTexture as Q, AnyFlow as Qn, Config$9 as Qr, DEMAND_REASONS as Qt, ShapeValue as R, GameTypes as Rn, Api$6 as Rr, PerfMarkLine as Rt, ScenesApi as S, DescriptionNode as Sn, Config$6 as Sr, PERF_LOG_VERSION as St, DebugSwitches as T, MotionCause as Tn, Root as Tr, PassRecord as Tt, TransformValue as U, types_d_exports$4 as Un, types_d_exports$7 as Ur, PerfTelemetryLine as Ut, SpriteValue as V, State$4 as Vn, PauseReason as Vr, PerfSpikeLine as Vt, sprite as W, defineFlow as Wn, Api$7 as Wr, PerfThermalLine as Wt, PixiModule as X, FeaturePlugin as Xn, Time as Xr, ShaderWhat as Xt, PixiFilter as Y, FeatureDescription as Yn, ThermalReading as Yr, ShaderEventDetail as Yt, PixiSprite as Z, FeatureTree as Zn, types_d_exports$8 as Zr, WarmDetail as Zt, DefineScene as _, ResourceType as _n, Config$5 as _r, MonitorSections as _t, Config as a, AnyComponentType as an, RouteStep as ar, RenderStats as at, SceneDefinition as b, TagType as bn, types_d_exports$5 as br, PERF_CAUSES as bt, LoadBundles as c, ComponentSchema as cn, Descriptor as cr, ViewportSize as ct, Manifest as d, Entity as dn, GuideOptions as dr, FrameReadResult as dt, Require as ei, Config$3 as en, DefineNode as er, State$2 as et, State as f, EntitySnapshot as fn, Hint as fr, FrameReadout as ft, AnySceneProjection as g, QueryTerm as gn, ClockSource as gr, MONITOR_SECTIONS as gt, types_d_exports as h, Narrowed as hn, Api$4 as hr, LongFrameEntry as ht, BundleSpec as i, AnyComponent as in, NodeTable as ir, MonitorCounts as it, HudPartValue as j, TrackOptions as jn, SaveDoc as jr, PerfDisplay as jt, Display as k, ProjectionSpec as kn, PlayerStateProvider as kr, PerfCollectorLine as kt, LoadReason as l, ComponentType as ln, Effect as lr, FilterCache as lt, Usage as m, Mut as mn, Answer as mr, FrameRing as mt, AssetsIo as n, State$3 as nn, FlowState as nr, types_d_exports$2 as nt, DefineBundles as o, AnyComponentValue as on, SceneIdOf as or, Orientation as ot, Tier as p, FrameDiff as pn, NodeFx as pr, FrameRecord as pt, Config$2 as q, to as qn, RateChange as qr, ProblemRule as qt, BundleMap as r, types_d_exports$3 as rn, JournalEntry as rr, Captured as rt, Events as s, ComponentHandle as sn, TypeTag as sr, Point as st, Api as t, Explained as tn, FlowGraph as tr, Under as tt, LoadResult as u, ComponentValue as un, EffectOptions as ur, FrameColumns as ut, Events$1 as v, SystemDefinition as vn, FakeClock as vr, OverlayEventDetail as vt, types_d_exports$1 as w, Motion as wn, Json as wr, PassKind as wt, SceneSpec as x, ChangeHook as xn, Api$5 as xr, PERF_GAP_BUCKETS as xt, LayerMap as y, SystemFor as yn, State$5 as yr, OverlayWhat as yt, Sprite as z, HudKeysOf as zn, Config$7 as zr, PerfMeasured as zt };
12534
+ export { PixiTexture as $, AnyFlow as $n, Config$9 as $r, DEMAND_REASONS as $t, Display as A, ProjectionSpec as An, PlayerStateProvider as Ar, PerfCollectorLine as At, Sprite as B, HudKeysOf as Bn, Config$7 as Br, PerfMeasured as Bt, ScenesApi as C, DescriptionNode as Cn, Config$6 as Cr, PERF_LOG_VERSION as Ct, FilterSlot as D, MotionHandle as Dn, State$6 as Dr, PerfCause as Dt, DebugSwitches as E, MotionCause as En, Root as Er, PassRecord as Et, Overlay as F, Api$3 as Fn, SnapshotOf as Fr, PerfGapLine as Ft, sprite as G, defineFlow as Gn, Api$7 as Gr, PerfThermalLine as Gt, SpriteValue as H, State$4 as Hn, PauseReason as Hr, PerfSpikeLine as Ht, OverlayValue as I, BundlesOf as In, StoreApi as Ir, PerfHeaderLine as It, Config$2 as J, to as Jn, RateChange as Jr, ProblemRule as Jt, AdaptiveScale as K, exit as Kn, Config$8 as Kr, PoolTrimDetail as Kt, Parent as L, Config$4 as Ln, RngApi as Lr, PerfLogLine as Lt, HudPartValue as M, TrackOptions as Mn, SaveDoc as Mr, PerfDisplay as Mt, NineSlice$1 as N, TrackSegment as Nn, SaveUnreadableError as Nr, PerfEventLine as Nt, FilterSlotInputs as O, NumericFields as On, types_d_exports$6 as Or, PerfChange as Ot, NineSliceValue as P, ViewHandle as Pn, Snapshot as Pr, PerfEventName as Pt, PixiSprite as Q, FeatureTree as Qn, types_d_exports$8 as Qr, WarmDetail as Qt, Shape as R, EmitterIdOf as Rn, RngState as Rr, PerfLongFrameLine as Rt, SceneSpec as S, ChangeHook as Sn, Api$5 as Sr, PERF_GAP_BUCKETS as St, types_d_exports$1 as T, Motion as Tn, Json as Tr, PassKind as Tt, Transform as U, TextStylesOf as Un, State$7 as Ur, PerfStartupLine as Ut, SpriteOptions as V, Position as Vn, Events$6 as Vr, PerfSampleLine as Vt, TransformValue as W, types_d_exports$4 as Wn, types_d_exports$7 as Wr, PerfTelemetryLine as Wt, PixiFilter as X, FeatureDescription as Xn, ThermalReading as Xr, ShaderEventDetail as Xt, MonitorConfig as Y, type as Yn, State$8 as Yr, SHADER_WHATS as Yt, PixiModule as Z, FeaturePlugin as Zn, Time as Zr, ShaderWhat as Zt, AnySceneProjection as _, QueryTerm as _n, ClockSource as _r, MONITOR_SECTIONS as _t, Config as a, AnyComponent as an, NodeTable as ar, MonitorCounts as at, LayerMap as b, SystemFor as bn, State$5 as br, OverlayWhat as bt, LoadBundles as c, ComponentHandle as cn, TypeTag as cr, Point as ct, Manifest as d, ComponentValue as dn, EffectOptions as dr, FrameColumns as dt, Events$8 as ei, Api$2 as en, Bookmark as er, PoolTrim as et, ReadyBundles as f, Entity as fn, GuideOptions as fr, FrameReadResult as ft, types_d_exports as g, Narrowed as gn, Api$4 as gr, LongFrameEntry as gt, Usage as h, Mut as hn, Answer as hr, FrameRing as ht, BundleSpec as i, types_d_exports$3 as in, JournalEntry as ir, Captured as it, HudPart as j, ReducedMotion as jn, ProviderCall as jr, PerfCounts as jt, SyncApi as k, ProjectionMotion as kn, Patch as kr, PerfChangeEntry as kt, LoadReason as l, ComponentSchema as ln, Descriptor as lr, ViewportSize as lt, Tier as m, FrameDiff as mn, NodeFx as mr, FrameRecord as mt, AssetsIo as n, Explained as nn, FlowGraph as nr, Under as nt, DefineBundles as o, AnyComponentType as on, RouteStep as or, RenderStats as ot, State as p, EntitySnapshot as pn, Hint as pr, FrameReadout as pt, Api$1 as q, slot as qn, FrameRate as qr, ProblemEventDetail as qt, BundleMap as r, State$3 as rn, FlowState as rr, types_d_exports$2 as rt, Events as s, AnyComponentValue as sn, SceneIdOf as sr, Orientation as st, Api as t, Require as ti, Config$3 as tn, DefineNode as tr, State$2 as tt, LoadResult as u, ComponentType as un, Effect as ur, FilterCache as ut, DefineScene as v, ResourceType as vn, Config$5 as vr, MonitorSections as vt, State$1 as w, Ease as wn, Events$5 as wr, PROBLEM_RULES as wt, SceneDefinition as x, TagType as xn, types_d_exports$5 as xr, PERF_CAUSES as xt, Events$1 as y, SystemDefinition as yn, FakeClock as yr, OverlayEventDetail as yt, ShapeValue as z, GameTypes as zn, Api$6 as zr, PerfMarkLine as zt };
@@ -1,5 +1,5 @@
1
- import { Nr as Snapshot, wr as Json } from "./types-bwefoJES.mjs";
2
- import { t as HeadlessApp } from "./headless-uUUH54Ij.mjs";
1
+ import { Pr as Snapshot, Tr as Json } from "./types-BFGyVykz.mjs";
2
+ import { t as HeadlessApp } from "./headless-BCwsb1wR.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
 
5
5
  //#region src/plugins/flow/doors/types.d.ts
@@ -1,5 +1,5 @@
1
- import { $r as Events$2, $t as Api$3, An as ReducedMotion, Br as Events$5, Cn as Ease, Cr as Events$3, D as FilterSlotInputs, Dn as NumericFields, E as FilterSlot, En as MotionHandle, K as Api$4, Mn as TrackSegment, O as SyncApi, Pn as Api$2, Q as PixiTexture, Wr as Api$1, X as PixiModule, Y as PixiFilter, Z as PixiSprite, cr as Descriptor, dn as Entity, ei as Require, in as AnyComponent, jn as TrackOptions, ln as ComponentType, lt as FilterCache, on as AnyComponentValue, s as Events$1, sn as ComponentHandle, sr as TypeTag, st as Point, t as Api$5, v as Events$4, wr as Json, xr as Api$6 } from "./types-bwefoJES.mjs";
2
- import { N as InputApi, R as I18nApi, X as StylesState, c as UiNode, i as Finding, l as LayoutState, n as ElementChange, o as JsxState, r as ElementMotion, w as TextApi } from "./types-C4igewxk.mjs";
1
+ import { $ as PixiTexture, D as FilterSlot, Dn as MotionHandle, Fn as Api$2, Gr as Api$1, Mn as TrackOptions, Nn as TrackSegment, O as FilterSlotInputs, On as NumericFields, Q as PixiSprite, Sr as Api$6, Tr as Json, Vr as Events$5, X as PixiFilter, Z as PixiModule, an as AnyComponent, cn as ComponentHandle, cr as TypeTag, ct as Point, ei as Events$2, en as Api$3, fn as Entity, jn as ReducedMotion, k as SyncApi, lr as Descriptor, q as Api$4, s as Events$1, sn as AnyComponentValue, t as Api$5, ti as Require, un as ComponentType, ut as FilterCache, wn as Ease, wr as Events$3, y as Events$4 } from "./types-BFGyVykz.mjs";
2
+ import { N as InputApi, R as I18nApi, X as StylesState, c as UiNode, i as Finding, l as LayoutState, n as ElementChange, o as JsxState, r as ElementMotion, w as TextApi } from "./types-B02c7d6g.mjs";
3
3
  import { Log } from "@moku-labs/common/browser";
4
4
  import { PluginCtx } from "@moku-labs/core";
5
5
 
@@ -2984,11 +2984,12 @@ type UiApi = {
2984
2984
  */
2985
2985
  find(key: string): Entity | undefined;
2986
2986
  /**
2987
- * Reads the live screen against the five rules: a tap target under `tapTargetPt` at the size
2987
+ * Reads the live screen against the six rules: a tap target under `tapTargetPt` at the size
2988
2988
  * it is drawn (a `fit: "contain"` on it or above it shrinks it), a text that does not fit its
2989
2989
  * box in some registered locale, an absolute element with no `reason`, a clipping element
2990
- * (`scroll`, `overflow: "hidden"`) whose style names a nine-slice it never draws, and a root
2991
- * element whose style sets a `zIndex` it ignores. Never throws; empty when nothing is mounted.
2990
+ * (`scroll`, `overflow: "hidden"`) whose style names a nine-slice it never draws, a style that
2991
+ * is `hollow` with no nine-slice to hollow, and a root element whose style sets a `zIndex` it
2992
+ * ignores. Never throws; empty when nothing is mounted.
2992
2993
  *
2993
2994
  * @returns One finding per rule and element.
2994
2995
  * @example
@@ -2997,6 +2998,8 @@ type UiApi = {
2997
2998
  * app.ui.lint(); // [{ rule: "tap-target", key: "cell", detail: "39 x 39 pt" }]
2998
2999
  * // A list styled with a nine-slice: the clip keeps it from drawing.
2999
3000
  * app.ui.lint(); // [{ rule: "nine-slice-clipped", key: "orders", detail: "scroll" }]
3001
+ * // A frame made hollow before its nine-slice was named: there is no rim to draw.
3002
+ * app.ui.lint(); // [{ rule: "hollow-without-nine-slice", key: "memFrost", detail: "stack" }]
3000
3003
  * // A screen root that asks to be drawn over the others: the layer decides that.
3001
3004
  * app.ui.lint(); // [{ rule: "z-index-on-root", key: "board", detail: "zIndex 2" }]
3002
3005
  * ```
@@ -1,7 +1,7 @@
1
- import { Ar as ProviderCall, In as Config$1, Pr as SnapshotOf, Qn as AnyFlow, Sr as Config, X as PixiModule, Xn as FeaturePlugin, a as Config$3, d as Manifest, gr as ClockSource, jr as SaveDoc, kr as PlayerStateProvider, n as AssetsIo, ot as Orientation, q as Config$2, sr as TypeTag, vr as FakeClock, wr as Json } from "./types-bwefoJES.mjs";
2
- import { o as AudioContextLike, s as Config$4 } from "./types-BP99ij9v.mjs";
3
- import { R as I18nApi, U as StringTable, W as TextKey } from "./types-C4igewxk.mjs";
4
- import { ft as platformPlugin, i as screen, mt as PlatformProvider, t as createApp, wt as audioPlugin, xt as effectsPlugin } from "./index-ChqvcZwY.mjs";
1
+ import { $n as AnyFlow, Ar as PlayerStateProvider, Cr as Config, Fr as SnapshotOf, J as Config$2, Ln as Config$1, Mr as SaveDoc, Tr as Json, Z as PixiModule, Zn as FeaturePlugin, _r as ClockSource, a as Config$3, cr as TypeTag, d as Manifest, jr as ProviderCall, n as AssetsIo, st as Orientation, yr as FakeClock } from "./types-BFGyVykz.mjs";
2
+ import { o as AudioContextLike, s as Config$4 } from "./types-COWBfy2L.mjs";
3
+ import { R as I18nApi, U as StringTable, W as TextKey } from "./types-B02c7d6g.mjs";
4
+ import { St as effectsPlugin, Tt as audioPlugin, ht as PlatformProvider, i as screen, pt as platformPlugin, t as createApp } from "./index-CKXNW8_t.mjs";
5
5
  import { AnyPluginInstance } from "@moku-labs/core";
6
6
 
7
7
  //#region src/plugins/model/store/providers/memory.d.ts
@@ -1,9 +1,9 @@
1
- import { $t as Api$1, K as Api, Rr as Api$3, xr as Api$2 } from "./types-bwefoJES.mjs";
2
- import { P as AnimApi, r as UiApi } from "./types-BP99ij9v.mjs";
3
- import { N as InputApi } from "./types-C4igewxk.mjs";
4
- import { r as Repro } from "./headless-uUUH54Ij.mjs";
5
- import { a as InputOf, r as ControlApp } from "./types-DMsvVZZT.mjs";
6
- import { t as commands } from "./commands-CQt3jo0G.mjs";
1
+ import { Sr as Api$2, en as Api$1, q as Api, zr as Api$3 } from "./types-BFGyVykz.mjs";
2
+ import { P as AnimApi, r as UiApi } from "./types-COWBfy2L.mjs";
3
+ import { N as InputApi } from "./types-B02c7d6g.mjs";
4
+ import { r as Repro } from "./headless-BCwsb1wR.mjs";
5
+ import { a as InputOf, r as ControlApp } from "./types-C8JK9u1Y.mjs";
6
+ import { t as commands } from "./commands-BvNp27KS.mjs";
7
7
 
8
8
  //#region src/visual/types.d.ts
9
9
  /** The base commands of the `/control` door, keyed by their short names. */