@almadar/ui 6.13.0 → 6.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/{UserContext-g_LcDiGN.d.cts → CurrentPagePathContext-J1lqjvAq.d.cts} +2 -97
  2. package/dist/{UserContext-g_LcDiGN.d.ts → CurrentPagePathContext-J1lqjvAq.d.ts} +2 -97
  3. package/dist/{EntityBindingContext-D5lRu6p1.d.cts → EntityBindingContext-BMz9xiBa.d.cts} +2 -3
  4. package/dist/{EntityBindingContext-D5lRu6p1.d.ts → EntityBindingContext-BMz9xiBa.d.ts} +2 -3
  5. package/dist/{GameAudioProvider-D8GynTNq.d.cts → GameAudioProvider-Cpw_lMPY.d.cts} +1 -1
  6. package/dist/{GameAudioProvider-Dozqx4sL.d.ts → GameAudioProvider-DIjFiy70.d.ts} +1 -1
  7. package/dist/UserContext-D566nfWA.d.cts +99 -0
  8. package/dist/UserContext-D566nfWA.d.ts +99 -0
  9. package/dist/avl/index.cjs +367 -61
  10. package/dist/avl/index.d.cts +1 -1
  11. package/dist/avl/index.d.ts +1 -1
  12. package/dist/avl/index.js +369 -63
  13. package/dist/{avl-schema-parser-PVu8rgsy.d.cts → avl-schema-parser-B25PL-a8.d.cts} +1 -1
  14. package/dist/{avl-schema-parser-DX-aVCCm.d.ts → avl-schema-parser-CM0pQo8E.d.ts} +1 -1
  15. package/dist/components/index.cjs +360 -108
  16. package/dist/components/index.d.cts +8 -24
  17. package/dist/components/index.d.ts +8 -24
  18. package/dist/components/index.js +362 -109
  19. package/dist/context/index.d.cts +2 -1
  20. package/dist/context/index.d.ts +2 -1
  21. package/dist/lib/drawable/three/index.cjs +126 -3
  22. package/dist/lib/drawable/three/index.d.cts +3 -3
  23. package/dist/lib/drawable/three/index.d.ts +3 -3
  24. package/dist/lib/drawable/three/index.js +126 -3
  25. package/dist/lib/index.cjs +1 -4
  26. package/dist/lib/index.d.cts +2 -2
  27. package/dist/lib/index.d.ts +2 -2
  28. package/dist/lib/index.js +1 -4
  29. package/dist/{offline-executor-QUdKOj7f.d.cts → offline-executor-DdV2o0Zu.d.cts} +4 -19
  30. package/dist/{offline-executor-QUdKOj7f.d.ts → offline-executor-DdV2o0Zu.d.ts} +4 -19
  31. package/dist/{paintDispatch-CK5uwYEq.d.cts → paintDispatch-Dh1pgljl.d.cts} +79 -1
  32. package/dist/{paintDispatch-CK5uwYEq.d.ts → paintDispatch-Dh1pgljl.d.ts} +79 -1
  33. package/dist/providers/index.cjs +354 -53
  34. package/dist/providers/index.d.cts +10 -9
  35. package/dist/providers/index.d.ts +10 -9
  36. package/dist/providers/index.js +355 -54
  37. package/dist/renderer/index.cjs +0 -15
  38. package/dist/renderer/index.d.cts +4 -9
  39. package/dist/renderer/index.d.ts +4 -9
  40. package/dist/renderer/index.js +1 -15
  41. package/dist/runtime/index.cjs +369 -72
  42. package/dist/runtime/index.d.cts +14 -11
  43. package/dist/runtime/index.d.ts +14 -11
  44. package/dist/runtime/index.js +371 -74
  45. package/dist/{verificationRegistry-D8bHWD8Q.d.ts → verificationRegistry-Cwa52VyK.d.ts} +1 -1
  46. package/dist/{verificationRegistry-BLsjb1oU.d.cts → verificationRegistry-DTrKDRoa.d.cts} +1 -1
  47. package/package.json +4 -4
@@ -1,6 +1,6 @@
1
1
  import * as React87 from 'react';
2
2
  import React87__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useSyncExternalStore, Suspense, useState, useLayoutEffect, lazy, useId } from 'react';
3
- import { EventBusContext, useTraitScopeChain, RenderSlotProvider, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, useEntitySchema, getAllPages, matchPathAmong, CurrentPagePathProvider, NavStackProvider, OrbitalProvider, TraitScopeProvider, useNavStack, ServerBridgeProvider, useCurrentPagePath, useRenderSlot, useGameAudioContextOptional, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, EntityBindingContext } from '@almadar/ui/providers';
3
+ import { EventBusContext, useTraitScopeChain, RenderSlotProvider, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, useEntitySchema, useUser, getAllPages, matchPathAmong, CurrentPagePathProvider, NavStackProvider, OrbitalProvider, TraitScopeProvider, useNavStack, ServerBridgeProvider, useCurrentPagePath, useRenderSlot, useGameAudioContextOptional, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, EntityBindingContext } from '@almadar/ui/providers';
4
4
  export { EntitySchemaProvider, ServerBridgeProvider, TraitContext, TraitProvider, useEntitySchema, useEntitySchemaOptional, useServerBridge, useTrait, useTraitContext } from '@almadar/ui/providers';
5
5
  import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
6
6
  import { perfStore, pushPerfEntry, wrapCallbackForEvent, perfStart, perfEnd, perfGauge, prepareSchemaForPreview, perfTimeAsync, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits } from '@almadar/runtime/ui';
@@ -78,7 +78,7 @@ import { CSS } from '@dnd-kit/utilities';
78
78
  import { ordered, lib } from 'emojilib';
79
79
  import { useNodeId, ReactFlowProvider, Handle, Position } from '@xyflow/react';
80
80
  import { forceSimulation, forceLink, forceManyBody, forceCollide, forceX, forceY } from 'd3-force';
81
- import { isDrawHostPattern, getPatternDefinition, getPatternFieldsContract, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
81
+ import { SELF_OVERLAY_PATTERN_TYPES, isDrawHostPattern, getPatternDefinition, getPatternFieldsContract, getComponentForPattern as getComponentForPattern$1 } from '@almadar/core/patterns';
82
82
  import { isKnownStdOperator } from '@almadar/std/registry';
83
83
  import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
84
84
 
@@ -8346,7 +8346,7 @@ var init_DialogueBubble = __esm({
8346
8346
  init_Typography();
8347
8347
  init_GameIcon();
8348
8348
  DEFAULT_PORTRAIT = {
8349
- url: "https://almadar-kflow-assets.web.app/shared/characters/archetypes/04_hero.png",
8349
+ url: "https://almadar-kflow-assets.web.app/shared/ui-winter-ski-board/default/units/hero/hero.png",
8350
8350
  role: "effect",
8351
8351
  category: "character"
8352
8352
  };
@@ -9563,6 +9563,14 @@ function createWebPainter(ctx, onAssetLoad) {
9563
9563
  ctx.drawImage(img, dest.x, dest.y, dw, dh);
9564
9564
  }
9565
9565
  },
9566
+ blitTransformed(tex, src, affine) {
9567
+ const img = imageByHandle.get(tex);
9568
+ if (!img) return;
9569
+ ctx.save();
9570
+ ctx.transform(affine[0], affine[1], affine[2], affine[3], affine[4], affine[5]);
9571
+ ctx.drawImage(img, src.x, src.y, src.w, src.h, src.x, src.y, src.w, src.h);
9572
+ ctx.restore();
9573
+ },
9566
9574
  fillRect(x, y, w, h, style) {
9567
9575
  ctx.fillStyle = toCanvasStyle(style);
9568
9576
  ctx.fillRect(x, y, w, h);
@@ -10069,6 +10077,271 @@ var init_DrawGroup = __esm({
10069
10077
  init_registry();
10070
10078
  }
10071
10079
  });
10080
+
10081
+ // lib/skinning.ts
10082
+ function composeAffine(a, b) {
10083
+ return [
10084
+ a[0] * b[0] + a[2] * b[1],
10085
+ a[1] * b[0] + a[3] * b[1],
10086
+ a[0] * b[2] + a[2] * b[3],
10087
+ a[1] * b[2] + a[3] * b[3],
10088
+ a[0] * b[4] + a[2] * b[5] + a[4],
10089
+ a[1] * b[4] + a[3] * b[5] + a[5]
10090
+ ];
10091
+ }
10092
+ function invertAffine(m) {
10093
+ const det = m[0] * m[3] - m[1] * m[2];
10094
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return IDENTITY;
10095
+ const inv = 1 / det;
10096
+ return [
10097
+ m[3] * inv,
10098
+ -m[1] * inv,
10099
+ -m[2] * inv,
10100
+ m[0] * inv,
10101
+ (m[2] * m[5] - m[3] * m[4]) * inv,
10102
+ (m[1] * m[4] - m[0] * m[5]) * inv
10103
+ ];
10104
+ }
10105
+ function applyAffine(m, x, y) {
10106
+ return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
10107
+ }
10108
+ function rotationAbout(pivot, degrees) {
10109
+ const r = degrees * Math.PI / 180;
10110
+ const cos = Math.cos(r);
10111
+ const sin = Math.sin(r);
10112
+ const [px, py] = pivot;
10113
+ return [cos, sin, -sin, cos, px - cos * px + sin * py, py - sin * px - cos * py];
10114
+ }
10115
+ function computeWorldMatrices(bones, pose) {
10116
+ const indexByName = /* @__PURE__ */ new Map();
10117
+ bones.forEach((b, i) => indexByName.set(b.name, i));
10118
+ const world = new Array(bones.length);
10119
+ const visiting = /* @__PURE__ */ new Set();
10120
+ const resolve = (i) => {
10121
+ const cached = world[i];
10122
+ if (cached) return cached;
10123
+ if (visiting.has(i)) return IDENTITY;
10124
+ visiting.add(i);
10125
+ const b = bones[i];
10126
+ const parentIndex = b.parent === null ? void 0 : indexByName.get(b.parent);
10127
+ const parentWorld = parentIndex === void 0 ? IDENTITY : resolve(parentIndex);
10128
+ const local = rotationAbout(b.pivot, pose[b.name] ?? 0);
10129
+ const m = composeAffine(parentWorld, local);
10130
+ visiting.delete(i);
10131
+ world[i] = m;
10132
+ return m;
10133
+ };
10134
+ return bones.map((_, i) => resolve(i));
10135
+ }
10136
+ function skinVertices(mesh, bindWorld, curWorld) {
10137
+ const skinMats = /* @__PURE__ */ new Map();
10138
+ const skinMat = (bone) => {
10139
+ let m = skinMats.get(bone);
10140
+ if (!m) {
10141
+ m = composeAffine(curWorld[bone] ?? IDENTITY, invertAffine(bindWorld[bone] ?? IDENTITY));
10142
+ skinMats.set(bone, m);
10143
+ }
10144
+ return m;
10145
+ };
10146
+ return mesh.vertices.map((v) => {
10147
+ if (v.weights.length === 0) return [v.x, v.y];
10148
+ let x = 0;
10149
+ let y = 0;
10150
+ for (const { bone, w } of v.weights) {
10151
+ const [bx, by] = applyAffine(skinMat(bone), v.x, v.y);
10152
+ x += w * bx;
10153
+ y += w * by;
10154
+ }
10155
+ return [x, y];
10156
+ });
10157
+ }
10158
+ function triangleAffine(src, dst) {
10159
+ const [s0, s1, s2] = src;
10160
+ const det = s0[0] * (s1[1] - s2[1]) + s1[0] * (s2[1] - s0[1]) + s2[0] * (s0[1] - s1[1]);
10161
+ if (!Number.isFinite(det) || Math.abs(det) < 1e-12) return null;
10162
+ const [d0, d1, d2] = dst;
10163
+ const a = (d0[0] * (s1[1] - s2[1]) + d1[0] * (s2[1] - s0[1]) + d2[0] * (s0[1] - s1[1])) / det;
10164
+ const c = (d0[0] * (s2[0] - s1[0]) + d1[0] * (s0[0] - s2[0]) + d2[0] * (s1[0] - s0[0])) / det;
10165
+ const e = (d0[0] * (s1[0] * s2[1] - s2[0] * s1[1]) + d1[0] * (s2[0] * s0[1] - s0[0] * s2[1]) + d2[0] * (s0[0] * s1[1] - s1[0] * s0[1])) / det;
10166
+ const b = (d0[1] * (s1[1] - s2[1]) + d1[1] * (s2[1] - s0[1]) + d2[1] * (s0[1] - s1[1])) / det;
10167
+ const d = (d0[1] * (s2[0] - s1[0]) + d1[1] * (s0[0] - s2[0]) + d2[1] * (s1[0] - s0[0])) / det;
10168
+ const f3 = (d0[1] * (s1[0] * s2[1] - s2[0] * s1[1]) + d1[1] * (s2[0] * s0[1] - s0[0] * s2[1]) + d2[1] * (s0[0] * s1[1] - s1[0] * s0[1])) / det;
10169
+ return [a, b, c, d, e, f3];
10170
+ }
10171
+ function isRigBundle(json) {
10172
+ return json.mesh !== void 0 || json.bones !== void 0;
10173
+ }
10174
+ function getRigBundle(url, onReady) {
10175
+ if (meshCache.has(url)) return meshCache.get(url) ?? void 0;
10176
+ meshCache.set(url, void 0);
10177
+ fetch(url).then((r) => {
10178
+ if (!r.ok) throw new Error(`rigbundle fetch failed: HTTP ${r.status}`);
10179
+ return r.json();
10180
+ }).then((json) => {
10181
+ const ok = isRigBundle(json) || Array.isArray(json.vertices);
10182
+ if (!ok) throw new Error("rigbundle payload is neither a SkinMesh nor a rigbundle");
10183
+ meshCache.set(url, json);
10184
+ onReady();
10185
+ }).catch(() => {
10186
+ meshCache.set(url, null);
10187
+ onReady();
10188
+ });
10189
+ return void 0;
10190
+ }
10191
+ function skinMeshFailed(url) {
10192
+ return meshCache.get(url) === null;
10193
+ }
10194
+ function vertexBounds(points) {
10195
+ if (points.length === 0) return null;
10196
+ let minX = Infinity;
10197
+ let minY = Infinity;
10198
+ let maxX = -Infinity;
10199
+ let maxY = -Infinity;
10200
+ for (const [x, y] of points) {
10201
+ if (x < minX) minX = x;
10202
+ if (y < minY) minY = y;
10203
+ if (x > maxX) maxX = x;
10204
+ if (y > maxY) maxY = y;
10205
+ }
10206
+ return { minX, minY, maxX, maxY };
10207
+ }
10208
+ var IDENTITY, meshCache;
10209
+ var init_skinning = __esm({
10210
+ "lib/skinning.ts"() {
10211
+ IDENTITY = [1, 0, 0, 1, 0, 0];
10212
+ meshCache = /* @__PURE__ */ new Map();
10213
+ }
10214
+ });
10215
+ function warnMissingOnce2(reason, node) {
10216
+ const key = `${reason}:${node.asset.url}:${String(node.meshUrl)}`;
10217
+ if (loggedMissing2.has(key)) return;
10218
+ loggedMissing2.add(key);
10219
+ skinnedLog.warn("draw-skinned-mesh unresolvable \u2014 painting fallback", { reason, url: node.asset.url, meshUrl: node.meshUrl });
10220
+ }
10221
+ function dominantBone(v) {
10222
+ let best = -1;
10223
+ let bestW = 0;
10224
+ for (const { bone, w } of v.weights) {
10225
+ if (w > bestW) {
10226
+ bestW = w;
10227
+ best = bone;
10228
+ }
10229
+ }
10230
+ return best;
10231
+ }
10232
+ function resolveSkinPose(node, clip) {
10233
+ const effectiveClip = clip ?? node.clip;
10234
+ if (effectiveClip && node.frame !== void 0 && effectiveClip.frames.length > 0) {
10235
+ return effectiveClip.frames[node.frame % effectiveClip.frames.length];
10236
+ }
10237
+ return node.pose ?? {};
10238
+ }
10239
+ function resolveRig(node, dctx) {
10240
+ const fetched = node.meshUrl ? getRigBundle(node.meshUrl, dctx.invalidate) : void 0;
10241
+ if (node.meshUrl && fetched === void 0) return void 0;
10242
+ const rb = fetched && isRigBundle(fetched) ? fetched : void 0;
10243
+ const mesh = node.mesh ?? rb?.mesh ?? (!rb ? fetched : void 0);
10244
+ if (!mesh) return void 0;
10245
+ const bones = node.bones.length > 0 ? node.bones : rb?.bones ?? [];
10246
+ if (bones.length === 0) return void 0;
10247
+ const clip = node.clip ?? (node.clipName ? rb?.clips?.[node.clipName] : void 0);
10248
+ return { mesh, bones, clip };
10249
+ }
10250
+ function meshHasPixelUVs(mesh) {
10251
+ const cached = pixelUVByMesh.get(mesh);
10252
+ if (cached !== void 0) return cached;
10253
+ let pixel = false;
10254
+ for (const v of mesh.vertices) {
10255
+ if (v.u < 0 || v.u > 1 || v.v < 0 || v.v > 1) {
10256
+ pixel = true;
10257
+ break;
10258
+ }
10259
+ }
10260
+ pixelUVByMesh.set(mesh, pixel);
10261
+ return pixel;
10262
+ }
10263
+ function paintMeshPass(painter, node, bones, mesh, tex, dctx, pose, opacity) {
10264
+ const bindWorld = computeWorldMatrices(bones, {});
10265
+ const curWorld = computeWorldMatrices(bones, pose);
10266
+ const skinned = skinVertices(mesh, bindWorld, curWorld);
10267
+ const origin = dctx.projector.project(node.position);
10268
+ const tw = dctx.projector.tileWidth;
10269
+ painter.save();
10270
+ if (opacity !== 1) painter.setAlpha(opacity);
10271
+ for (const [i0, i1, i2] of mesh.triangles) {
10272
+ const v0 = mesh.vertices[i0];
10273
+ const v1 = mesh.vertices[i1];
10274
+ const v2 = mesh.vertices[i2];
10275
+ const p0 = skinned[i0];
10276
+ const p1 = skinned[i1];
10277
+ const p2 = skinned[i2];
10278
+ if (!v0 || !v1 || !v2 || !p0 || !p1 || !p2) continue;
10279
+ const dst = [
10280
+ [origin.x + p0[0] * tw, origin.y + p0[1] * tw],
10281
+ [origin.x + p1[0] * tw, origin.y + p1[1] * tw],
10282
+ [origin.x + p2[0] * tw, origin.y + p2[1] * tw]
10283
+ ];
10284
+ if (node.weightsOverlay || !tex) {
10285
+ if (!node.weightsOverlay) continue;
10286
+ const bone = dominantBone(v0);
10287
+ painter.fillPoly(
10288
+ dst.map(([x, y]) => ({ x, y })),
10289
+ WEIGHT_PALETTE[(bone % WEIGHT_PALETTE.length + WEIGHT_PALETTE.length) % WEIGHT_PALETTE.length]
10290
+ );
10291
+ continue;
10292
+ }
10293
+ const pixelUV = meshHasPixelUVs(mesh);
10294
+ const uv = pixelUV ? [[v0.u, v0.v], [v1.u, v1.v], [v2.u, v2.v]] : [
10295
+ [v0.u * tex.width, v0.v * tex.height],
10296
+ [v1.u * tex.width, v1.v * tex.height],
10297
+ [v2.u * tex.width, v2.v * tex.height]
10298
+ ];
10299
+ const affine = triangleAffine(uv, dst);
10300
+ if (!affine) continue;
10301
+ painter.save();
10302
+ painter.clipPath(`M ${dst[0][0]} ${dst[0][1]} L ${dst[1][0]} ${dst[1][1]} L ${dst[2][0]} ${dst[2][1]} Z`);
10303
+ painter.blitTransformed(tex, { x: 0, y: 0, w: tex.width, h: tex.height }, affine);
10304
+ painter.restore();
10305
+ }
10306
+ painter.restore();
10307
+ }
10308
+ function DrawSkinnedMesh(props) {
10309
+ const register = useContext(DrawableRegistryContext);
10310
+ if (register) register({ ...props, type: "draw-skinned-mesh" });
10311
+ return null;
10312
+ }
10313
+ var skinnedLog, loggedMissing2, WEIGHT_PALETTE, pixelUVByMesh, paintSkinnedMesh;
10314
+ var init_DrawSkinnedMesh = __esm({
10315
+ "components/game/atoms/DrawSkinnedMesh.tsx"() {
10316
+ "use client";
10317
+ init_imageCache();
10318
+ init_contract();
10319
+ init_registry();
10320
+ init_skinning();
10321
+ skinnedLog = createLogger("almadar:ui:draw-skinned-mesh");
10322
+ loggedMissing2 = /* @__PURE__ */ new Set();
10323
+ WEIGHT_PALETTE = Array.from({ length: 10 }, (_, i) => `hsl(${i * 36 % 360}, 70%, 55%)`);
10324
+ pixelUVByMesh = /* @__PURE__ */ new WeakMap();
10325
+ paintSkinnedMesh = (painter, node, dctx) => {
10326
+ if (!isValidScenePos(node.position)) return;
10327
+ const rig = resolveRig(node, dctx);
10328
+ if (!rig) {
10329
+ if (node.meshUrl && skinMeshFailed(node.meshUrl)) warnMissingOnce2("mesh-failed", node);
10330
+ else if (!node.mesh && !node.meshUrl) warnMissingOnce2("mesh-missing", node);
10331
+ return;
10332
+ }
10333
+ const tex = node.weightsOverlay ? null : painter.resolveTexture(node.asset.url);
10334
+ if (!node.weightsOverlay && !tex) {
10335
+ if (getImageStatus(node.asset.url) === "failed") warnMissingOnce2("texture-failed", node);
10336
+ return;
10337
+ }
10338
+ if (node.ghost && rig.clip && rig.clip.frames.length > 0) {
10339
+ paintMeshPass(painter, node, rig.bones, rig.mesh, tex, dctx, rig.clip.frames[node.ghost.frame % rig.clip.frames.length], node.ghost.opacity);
10340
+ }
10341
+ paintMeshPass(painter, node, rig.bones, rig.mesh, tex, dctx, resolveSkinPose(node, rig.clip), node.opacity ?? 1);
10342
+ };
10343
+ }
10344
+ });
10072
10345
  function applyMeshAnimation(node, timeMs) {
10073
10346
  const anim = node.animation;
10074
10347
  if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
@@ -10393,6 +10666,9 @@ function paintDrawable(painter, node, dctx) {
10393
10666
  case "draw-mesh":
10394
10667
  warnUnsupported2d("draw-mesh");
10395
10668
  break;
10669
+ case "draw-skinned-mesh":
10670
+ paintSkinnedMesh(painter, node, dctx);
10671
+ break;
10396
10672
  case "draw-sprite-layer":
10397
10673
  paintSpriteLayer(painter, node, dctx);
10398
10674
  break;
@@ -10417,6 +10693,7 @@ var init_paintDispatch = __esm({
10417
10693
  init_DrawShape();
10418
10694
  init_DrawText();
10419
10695
  init_DrawGroup();
10696
+ init_DrawSkinnedMesh();
10420
10697
  init_DrawMesh();
10421
10698
  init_DrawSpriteLayer();
10422
10699
  init_DrawShapeLayer();
@@ -10437,6 +10714,21 @@ function shapeDrawnItem(n) {
10437
10714
  if (n.shape !== "rect") return { pos: n.position, id: n.id };
10438
10715
  return { pos: n.position, id: n.id, anchor: n.anchor, width: n.width, height: n.height, rotation: n.rotate };
10439
10716
  }
10717
+ function skinnedMeshDrawnItem(n) {
10718
+ const mesh = n.mesh;
10719
+ if (!mesh || n.bones.length === 0) return { pos: n.position, id: n.id };
10720
+ const bindWorld = computeWorldMatrices(n.bones, {});
10721
+ const curWorld = computeWorldMatrices(n.bones, resolveSkinPose(n));
10722
+ const bounds = vertexBounds(skinVertices(mesh, bindWorld, curWorld));
10723
+ if (!bounds) return { pos: n.position, id: n.id };
10724
+ return {
10725
+ pos: { ...n.position, x: n.position.x + bounds.minX, y: n.position.y + bounds.minY },
10726
+ id: n.id,
10727
+ anchor: "top-left",
10728
+ width: bounds.maxX - bounds.minX,
10729
+ height: bounds.maxY - bounds.minY
10730
+ };
10731
+ }
10440
10732
  function collectDrawnItems(nodes) {
10441
10733
  const out = [];
10442
10734
  for (const n of nodes) {
@@ -10447,6 +10739,9 @@ function collectDrawnItems(nodes) {
10447
10739
  case "draw-shape":
10448
10740
  if (isValidScenePos(n.position)) out.push(shapeDrawnItem(n));
10449
10741
  break;
10742
+ case "draw-skinned-mesh":
10743
+ if (isValidScenePos(n.position)) out.push(skinnedMeshDrawnItem(n));
10744
+ break;
10450
10745
  case "draw-text":
10451
10746
  case "draw-group":
10452
10747
  case "draw-mesh":
@@ -10514,6 +10809,8 @@ function rotatePoint(p, center, radians) {
10514
10809
  var init_hitTest = __esm({
10515
10810
  "lib/drawable/hitTest.ts"() {
10516
10811
  init_contract();
10812
+ init_DrawSkinnedMesh();
10813
+ init_skinning();
10517
10814
  }
10518
10815
  });
10519
10816
  function normalizeBackdrop(bg) {
@@ -11703,7 +12000,7 @@ var init_StateIndicator = __esm({
11703
12000
  init_cn();
11704
12001
  init_GameIcon();
11705
12002
  DEFAULT_ASSET_URL = {
11706
- url: "https://almadar-kflow-assets.web.app/shared/isometric-dungeon/Isometric/chestClosed_E.png",
12003
+ url: "https://almadar-kflow-assets.web.app/shared/ui-topdown-dungeon-board/default/features/chest/chest.png",
11707
12004
  role: "ui",
11708
12005
  category: "state"
11709
12006
  };
@@ -15670,7 +15967,6 @@ var init_avl_atom_types = __esm({
15670
15967
  "persist": "data",
15671
15968
  "fetch": "data",
15672
15969
  "emit": "communication",
15673
- "notify": "communication",
15674
15970
  "call-service": "communication",
15675
15971
  "spawn": "lifecycle",
15676
15972
  "despawn": "lifecycle",
@@ -15818,12 +16114,6 @@ function effectIcon(type, x, y, s, color) {
15818
16114
  /* @__PURE__ */ jsx("line", { x1: x - s, y1: y, x2: x + s * 0.6, y2: y, stroke: color, strokeWidth: 1.5 }),
15819
16115
  /* @__PURE__ */ jsx("polyline", { points: `${x + s * 0.1},${y - s * 0.5} ${x + s},${y} ${x + s * 0.1},${y + s * 0.5}`, fill: "none", stroke: color, strokeWidth: 1.5, strokeLinejoin: "round" })
15820
16116
  ] });
15821
- case "notify":
15822
- return /* @__PURE__ */ jsxs("g", { children: [
15823
- /* @__PURE__ */ jsx("path", { d: `M${x - s * 0.7},${y + s * 0.3} Q${x - s * 0.7},${y - s} ${x},${y - s} Q${x + s * 0.7},${y - s} ${x + s * 0.7},${y + s * 0.3} Z`, fill: "none", stroke: color, strokeWidth: 1.5 }),
15824
- /* @__PURE__ */ jsx("line", { x1: x - s * 0.8, y1: y + s * 0.3, x2: x + s * 0.8, y2: y + s * 0.3, stroke: color, strokeWidth: 1.5 }),
15825
- /* @__PURE__ */ jsx("circle", { cx: x, cy: y + s * 0.7, r: s * 0.2, fill: color })
15826
- ] });
15827
16117
  case "call-service":
15828
16118
  return /* @__PURE__ */ jsxs("g", { children: [
15829
16119
  /* @__PURE__ */ jsx("line", { x1: x - s, y1: y - s * 0.3, x2: x + s, y2: y - s * 0.3, stroke: color, strokeWidth: 1.5 }),
@@ -21027,9 +21317,6 @@ function getEffectSummary(effects) {
21027
21317
  case "emit":
21028
21318
  summaries.push(`\u2191 ${effect[1] || "event"}`);
21029
21319
  break;
21030
- case "notify":
21031
- summaries.push(`\u{1F4E7} ${effect[1] || ""}`);
21032
- break;
21033
21320
  case "persist":
21034
21321
  summaries.push(`\u{1F4BE} ${effect[1] || "save"}`);
21035
21322
  break;
@@ -21055,7 +21342,7 @@ function extractOutputsFromTransitions(transitions) {
21055
21342
  t.effects.forEach((effect) => {
21056
21343
  if (Array.isArray(effect)) {
21057
21344
  const op = effect[0];
21058
- if (["emit", "notify", "persist", "navigate", "call-service"].includes(op)) {
21345
+ if (["emit", "persist", "navigate", "call-service"].includes(op)) {
21059
21346
  if (isArraySExpr(effect)) {
21060
21347
  const humanText = formatSExprEffectToDomain(effect);
21061
21348
  outputs.add(humanText);
@@ -27998,7 +28285,9 @@ function DataGrid({
27998
28285
  const cardClickAction = actionDefs.find((a) => a.variant !== "danger");
27999
28286
  const handleCardClick = cardClickAction ? (itemData) => () => fireAction(cardClickAction, itemData) : void 0;
28000
28287
  const stopCardClick = handleCardClick ? (e) => e.stopPropagation() : void 0;
28001
- const hasRenderProp = typeof children === "function";
28288
+ const renderItemFn = typeof schemaRenderItem === "function" ? schemaRenderItem : void 0;
28289
+ const itemRenderer = typeof children === "function" ? children : renderItemFn;
28290
+ const hasRenderProp = typeof itemRenderer === "function";
28002
28291
  useEffect(() => {
28003
28292
  if (data.length > 0 && !hasRenderProp && fieldDefs.length === 0) {
28004
28293
  const schemaArr = Array.isArray(schemaRenderItem) ? schemaRenderItem : null;
@@ -28072,7 +28361,7 @@ function DataGrid({
28072
28361
  onClick: handleCardClick?.(itemData),
28073
28362
  className: cn("relative group/rowactions", handleCardClick && "cursor-pointer", isSelected && "ring-2 ring-primary rounded-lg"),
28074
28363
  children: [
28075
- children(itemData, index),
28364
+ itemRenderer(itemData, index),
28076
28365
  actionDefs.length > 0 && /* @__PURE__ */ jsx(Box, { onClick: stopCardClick, className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: [
28077
28366
  inlineCardActions.map((action, idx) => /* @__PURE__ */ jsxs(
28078
28367
  Button,
@@ -28405,7 +28694,9 @@ function DataList({
28405
28694
  );
28406
28695
  const data = pageSize > 0 ? allData.slice(0, visibleCount) : allData;
28407
28696
  const hasMoreLocal = pageSize > 0 && visibleCount < allData.length;
28408
- const hasRenderProp = typeof children === "function";
28697
+ const renderItemFn = typeof schemaRenderItem === "function" ? schemaRenderItem : void 0;
28698
+ const itemRenderer = typeof children === "function" ? children : renderItemFn;
28699
+ const hasRenderProp = typeof itemRenderer === "function";
28409
28700
  React87__default.useEffect(() => {
28410
28701
  const renderItemTypeOf = typeof schemaRenderItem;
28411
28702
  const childrenTypeOf = typeof children;
@@ -28623,7 +28914,7 @@ function DataList({
28623
28914
  const actions = renderItemActions(itemData);
28624
28915
  return wrapDnd(
28625
28916
  /* @__PURE__ */ jsxs(Box, { "data-entity-row": true, "data-entity-id": id2, onClick: rowClickEvent ? handleRowClick(itemData) : void 0, className: cn("relative group/rowactions", rowClickEvent && "cursor-pointer"), children: [
28626
- children(itemData, index),
28917
+ itemRenderer(itemData, index),
28627
28918
  actions && /* @__PURE__ */ jsxs(Box, { className: "absolute top-2 right-2 z-10 opacity-0 group-hover/rowactions:opacity-100 focus-within:opacity-100 [@media(pointer:coarse)]:opacity-100 transition-opacity duration-fast", children: [
28628
28919
  /* @__PURE__ */ jsx(Box, { className: "rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5 [@media(pointer:coarse)]:hidden", children: actions }),
28629
28920
  /* @__PURE__ */ jsx(Box, { className: "hidden [@media(pointer:coarse)]:block rounded-md border border-border bg-card/95 backdrop-blur-sm shadow-sm p-0.5", children: /* @__PURE__ */ jsx(
@@ -34997,7 +35288,7 @@ function TableView({
34997
35288
  columns,
34998
35289
  fields,
34999
35290
  itemActions,
35000
- maxInlineActions: _maxInlineActions,
35291
+ maxInlineActions,
35001
35292
  itemClickEvent = "",
35002
35293
  selectable = false,
35003
35294
  selectEvent,
@@ -35030,6 +35321,12 @@ function TableView({
35030
35321
  const [localSelected, setLocalSelected] = React87__default.useState(/* @__PURE__ */ new Set());
35031
35322
  const colDefs = (Array.isArray(columns) ? columns : void 0) ?? (Array.isArray(fields) ? fields : void 0) ?? [];
35032
35323
  const actionDefs = Array.isArray(itemActions) ? itemActions : [];
35324
+ const inlineActions = maxInlineActions != null ? actionDefs.slice(0, maxInlineActions) : [];
35325
+ const overflowActions = maxInlineActions != null ? actionDefs.slice(maxInlineActions) : actionDefs;
35326
+ const fireAction = (action, row) => eventBus.emit(`UI:${action.event}`, {
35327
+ id: row.id,
35328
+ row
35329
+ });
35033
35330
  const allDataRaw = Array.isArray(entity) ? entity : entity ? [entity] : [];
35034
35331
  const dnd = useDataDnd({
35035
35332
  items: allDataRaw,
@@ -35205,7 +35502,7 @@ function TableView({
35205
35502
  }
35206
35503
  return /* @__PURE__ */ jsx(Box, { role: "cell", className: cellBase, children: /* @__PURE__ */ jsx("span", { className: "truncate text-foreground", children: formatCell(raw, col.format) }) }, col.key);
35207
35504
  }),
35208
- hasActions && /* @__PURE__ */ jsx(
35505
+ hasActions && /* @__PURE__ */ jsxs(
35209
35506
  HStack,
35210
35507
  {
35211
35508
  gap: "xs",
@@ -35219,23 +35516,38 @@ function TableView({
35219
35516
  "border-l border-[var(--color-border)]",
35220
35517
  lk.striped && index % 2 === 1 ? "bg-[var(--color-surface-subtle)]" : "bg-[var(--color-card)] group-hover:bg-[var(--color-surface-subtle)]"
35221
35518
  ),
35222
- children: /* @__PURE__ */ jsx(
35223
- Menu,
35224
- {
35225
- position: "bottom-end",
35226
- trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
35227
- items: actionDefs.map((action) => ({
35228
- label: action.label,
35229
- icon: action.icon,
35230
- event: action.event,
35231
- variant: action.variant === "danger" ? "danger" : "default",
35232
- onClick: () => eventBus.emit(`UI:${action.event}`, {
35233
- id: row.id,
35234
- row
35235
- })
35236
- }))
35237
- }
35238
- )
35519
+ children: [
35520
+ inlineActions.map((action) => /* @__PURE__ */ jsxs(
35521
+ Button,
35522
+ {
35523
+ variant: action.variant ?? "ghost",
35524
+ size: "sm",
35525
+ onClick: () => fireAction(action, row),
35526
+ "data-testid": `action-${action.event}`,
35527
+ "data-row-id": String(row.id),
35528
+ className: cn(action.variant === "danger" && "text-error hover:bg-error/10"),
35529
+ children: [
35530
+ action.icon && renderIconInput3(action.icon, { size: "xs", className: "mr-1" }),
35531
+ action.label
35532
+ ]
35533
+ },
35534
+ action.event
35535
+ )),
35536
+ overflowActions.length > 0 && /* @__PURE__ */ jsx(
35537
+ Menu,
35538
+ {
35539
+ position: "bottom-end",
35540
+ trigger: /* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", "aria-label": t("common.actions"), "data-testid": "action-overflow", "data-row-id": String(row.id), children: /* @__PURE__ */ jsx(Icon, { name: "more-horizontal", size: "xs" }) }),
35541
+ items: overflowActions.map((action) => ({
35542
+ label: action.label,
35543
+ icon: action.icon,
35544
+ event: action.event,
35545
+ variant: action.variant === "danger" ? "danger" : "default",
35546
+ onClick: () => fireAction(action, row)
35547
+ }))
35548
+ }
35549
+ )
35550
+ ]
35239
35551
  }
35240
35552
  )
35241
35553
  ]
@@ -50948,6 +51260,7 @@ var init_component_registry_generated = __esm({
50948
51260
  init_DrawMesh();
50949
51261
  init_DrawShape();
50950
51262
  init_DrawShapeLayer();
51263
+ init_DrawSkinnedMesh();
50951
51264
  init_DrawSprite();
50952
51265
  init_DrawSpriteLayer();
50953
51266
  init_DrawText();
@@ -51226,6 +51539,7 @@ var init_component_registry_generated = __esm({
51226
51539
  "DrawMesh": DrawMesh,
51227
51540
  "DrawShape": DrawShape,
51228
51541
  "DrawShapeLayer": DrawShapeLayer,
51542
+ "DrawSkinnedMesh": DrawSkinnedMesh,
51229
51543
  "DrawSprite": DrawSprite,
51230
51544
  "DrawSpriteLayer": DrawSpriteLayer,
51231
51545
  "DrawText": DrawText,
@@ -51554,7 +51868,7 @@ function renderContainedPortal(t, slot, content, onDismiss) {
51554
51868
  const slotId = `slot-${slot}`;
51555
51869
  switch (slot) {
51556
51870
  case "modal":
51557
- if (SELF_OVERLAY_PATTERNS.has(content.pattern)) {
51871
+ if (SELF_OVERLAY_PATTERN_TYPES.has(content.pattern)) {
51558
51872
  return /* @__PURE__ */ jsx(Box, { id: slotId, className: "contents", children: slotContent });
51559
51873
  }
51560
51874
  return /* @__PURE__ */ jsx(
@@ -51897,7 +52211,7 @@ function CompiledPortal({ slot, className, pattern, sourceTrait, children }) {
51897
52211
  children
51898
52212
  }
51899
52213
  );
51900
- wrapper = pattern !== void 0 && SELF_OVERLAY_PATTERNS.has(pattern) ? innerContent : /* @__PURE__ */ jsx(Modal, { isOpen: true, onClose: handleDismiss, showCloseButton: true, size: "lg", children: innerContent });
52214
+ wrapper = pattern !== void 0 && SELF_OVERLAY_PATTERN_TYPES.has(pattern) ? innerContent : /* @__PURE__ */ jsx(Modal, { isOpen: true, onClose: handleDismiss, showCloseButton: true, size: "lg", children: innerContent });
51901
52215
  break;
51902
52216
  }
51903
52217
  case "drawer":
@@ -51957,7 +52271,7 @@ function SlotPortal({
51957
52271
  let wrapper;
51958
52272
  switch (slot) {
51959
52273
  case "modal":
51960
- wrapper = SELF_OVERLAY_PATTERNS.has(content.pattern) ? /* @__PURE__ */ jsx(Box, { id: slotId, children: slotContent }) : /* @__PURE__ */ jsx(
52274
+ wrapper = SELF_OVERLAY_PATTERN_TYPES.has(content.pattern) ? /* @__PURE__ */ jsx(Box, { id: slotId, children: slotContent }) : /* @__PURE__ */ jsx(
51961
52275
  Modal,
51962
52276
  {
51963
52277
  isOpen: true,
@@ -52464,7 +52778,7 @@ function UISlotRenderer({
52464
52778
  }
52465
52779
  return wrapped;
52466
52780
  }
52467
- var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, SELF_OVERLAY_PATTERNS, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
52781
+ var scopeWrapLog, TRAIT_BINDING_RE, SuspenseConfigContext, SlotContainedContext, SLOT_SKELETON_MAP, CONTENT_NODE_SLOTS, PATTERNS_WITH_CHILDREN, traitRefPresenceCache;
52468
52782
  var init_UISlotRenderer = __esm({
52469
52783
  "components/core/organisms/UISlotRenderer.tsx"() {
52470
52784
  "use client";
@@ -52495,7 +52809,6 @@ var init_UISlotRenderer = __esm({
52495
52809
  modal: "form",
52496
52810
  drawer: "form"
52497
52811
  };
52498
- SELF_OVERLAY_PATTERNS = /* @__PURE__ */ new Set(["modal", "confirm-dialog"]);
52499
52812
  CONTENT_NODE_SLOTS = /* @__PURE__ */ new Set([
52500
52813
  "logo",
52501
52814
  "master",
@@ -52608,7 +52921,7 @@ function runTickFrame(entityId, orderedWriters, store) {
52608
52921
  }
52609
52922
  var log3 = createLogger("almadar:ui:effects:client-handlers");
52610
52923
  function createClientEffectHandlers(options) {
52611
- const { eventBus, slotSetter, navigate, navigateBack, notify, callService, liveEntity, persistDelegated } = options;
52924
+ const { eventBus, slotSetter, navigate, navigateBack, callService, liveEntity, persistDelegated } = options;
52612
52925
  return {
52613
52926
  emit: (event, payload, source) => {
52614
52927
  const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
@@ -52664,9 +52977,6 @@ function createClientEffectHandlers(options) {
52664
52977
  }),
52665
52978
  navigateBack: navigateBack ?? (() => {
52666
52979
  log3.warn("No navigate-back handler, ignoring");
52667
- }),
52668
- notify: notify ?? ((msg, type) => {
52669
- log3.debug("notify", { type, message: msg });
52670
52980
  })
52671
52981
  };
52672
52982
  }
@@ -53037,6 +53347,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53037
53347
  sharedEntityLog.debug("useTraitStateMachine start", { traitBindingsCount: traitBindings.length, traitNames: traitBindings.map((b) => b.trait.name) });
53038
53348
  const eventBus = useEventBus();
53039
53349
  const { entities } = useEntitySchema();
53350
+ const { user: viewer } = useUser();
53040
53351
  const traitConfigsByName = options?.traitConfigsByName;
53041
53352
  const orbitalsByTrait = options?.orbitalsByTrait;
53042
53353
  const callsiteCaptureChildrenByTrait = options?.callsiteCaptureChildrenByTrait;
@@ -53350,7 +53661,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53350
53661
  },
53351
53662
  navigate: optionsRef.current?.navigate,
53352
53663
  navigateBack: optionsRef.current?.navigateBack,
53353
- notify: optionsRef.current?.notify,
53354
53664
  callService: optionsRef.current?.callService,
53355
53665
  // The canonical client `set` writes `(set @entity.X)` straight into
53356
53666
  // the trait's one live store — the same object bound below. This is
@@ -53417,8 +53727,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53417
53727
  emit: clientHandlers.emit,
53418
53728
  renderUI: clientHandlers.renderUI,
53419
53729
  navigate: clientHandlers.navigate,
53420
- navigateBack: clientHandlers.navigateBack,
53421
- notify: clientHandlers.notify
53730
+ navigateBack: clientHandlers.navigateBack
53422
53731
  };
53423
53732
  }
53424
53733
  const sharedWrites = [];
@@ -53443,7 +53752,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53443
53752
  const bindingCtx = {
53444
53753
  entity: liveEntity,
53445
53754
  payload: payload || {},
53446
- state: previousState
53755
+ state: previousState,
53756
+ ...viewer ? { user: viewer } : {}
53447
53757
  };
53448
53758
  if (callsitePayload) {
53449
53759
  bindingCtx.callsitePayload = callsitePayload;
@@ -53540,7 +53850,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53540
53850
  });
53541
53851
  }
53542
53852
  return { emitted: emittedDuringExec, serverEffectResults };
53543
- }, [eventBus, flushSlot, sharedEntityStore, publishBindingSnapshot, orbitalsByTrait]);
53853
+ }, [eventBus, flushSlot, sharedEntityStore, publishBindingSnapshot, orbitalsByTrait, viewer]);
53544
53854
  const reRenderCallsiteCaptureChildren = useCallback(async (traitName, callsitePayload, entityByTrait, log11, visited = /* @__PURE__ */ new Set()) => {
53545
53855
  const children = callsiteCaptureChildrenByTrait?.get(traitName);
53546
53856
  if (!children || children.size === 0) return;
@@ -53585,7 +53895,8 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53585
53895
  const guardCtx = {
53586
53896
  entity,
53587
53897
  payload: {},
53588
- state: currentState
53898
+ state: currentState,
53899
+ ...viewer ? { user: viewer } : {}
53589
53900
  };
53590
53901
  const bindingCfg = getBindingConfig(binding) ?? traitConfigsByName?.[traitName];
53591
53902
  if (bindingCfg) {
@@ -53613,7 +53924,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
53613
53924
  const emitFromSharedWriter = useCallback((event, payload, source) => {
53614
53925
  const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
53615
53926
  eventBus.emit(prefixedEvent, payload, source);
53616
- }, [eventBus]);
53927
+ }, [eventBus, viewer]);
53617
53928
  useEffect(() => {
53618
53929
  const scheduler = createTickScheduler();
53619
53930
  const timedTick = (key, fn) => () => perfTimeAsync(key, fn);
@@ -54583,7 +54894,8 @@ function OrbPreview({
54583
54894
  transport,
54584
54895
  getAccessToken,
54585
54896
  initialPagePath,
54586
- isolated = false
54897
+ isolated = false,
54898
+ user = null
54587
54899
  }) {
54588
54900
  if (serverUrl && transport) {
54589
54901
  throw new Error("OrbPreview accepts serverUrl OR transport, not both");
@@ -54593,11 +54905,7 @@ function OrbPreview({
54593
54905
  const handleLocalFallback = useCallback(() => {
54594
54906
  if (localFallback) return;
54595
54907
  setLocalFallback(true);
54596
- eventBus.emit("UI:NOTIFY", {
54597
- message: "Preview server unreachable \u2014 running locally without server-side state.",
54598
- severity: "warning"
54599
- });
54600
- }, [localFallback, eventBus]);
54908
+ }, [localFallback]);
54601
54909
  const parseResult = useMemo(() => {
54602
54910
  let parsed;
54603
54911
  if (typeof schema === "string") {
@@ -54756,7 +55064,7 @@ function OrbPreview({
54756
55064
  storageKey: `almadar:navstack:${parseResult.schema.name ?? "preview"}`,
54757
55065
  children: [
54758
55066
  /* @__PURE__ */ jsx(NavStackRefBridge, { apiRef: navStackRef }),
54759
- /* @__PURE__ */ jsx(OrbitalProvider, { initialData: effectiveMockData, skipTheme: true, verification: true, isolated, children: /* @__PURE__ */ jsx(UISlotProvider, { children: /* @__PURE__ */ jsx(
55067
+ /* @__PURE__ */ jsx(OrbitalProvider, { initialData: effectiveMockData, skipTheme: true, verification: true, isolated, user, children: /* @__PURE__ */ jsx(UISlotProvider, { children: /* @__PURE__ */ jsx(
54760
55068
  SchemaRunner,
54761
55069
  {
54762
55070
  schema: parseResult.schema,
@@ -54931,7 +55239,7 @@ function useOrbitalPluginHost() {
54931
55239
  return { getState: ctx.getState, lastEvent: ctx.lastEvent, errors: ctx.errors };
54932
55240
  }
54933
55241
  function buildMockEffectHandlers(opts) {
54934
- const { pluginId, denySet, slotsRef, renderedSlotsRef, navigateRef, notifyRef } = opts;
55242
+ const { pluginId, denySet, slotsRef, renderedSlotsRef, navigateRef } = opts;
54935
55243
  const handlers = {
54936
55244
  renderUI: (slot, pattern, props, priority) => {
54937
55245
  if (!isUISlot(slot)) {
@@ -54951,11 +55259,6 @@ function buildMockEffectHandlers(opts) {
54951
55259
  } else if (navigateRef.current) {
54952
55260
  handlers.navigate = (path) => navigateRef.current?.(path);
54953
55261
  }
54954
- if (denySet.has("notify")) {
54955
- handlers.notify = (message, type) => log10.warn("notify:denied", { pluginId, message, type });
54956
- } else if (notifyRef.current) {
54957
- handlers.notify = (message, type) => notifyRef.current?.(message, type);
54958
- }
54959
55262
  if (denySet.has("persist")) {
54960
55263
  handlers.persist = async (action, entityType) => {
54961
55264
  log10.warn("persist:denied", { pluginId, action, entityType });
@@ -54976,7 +55279,6 @@ function PluginRuntimeMount({
54976
55279
  transport,
54977
55280
  deny,
54978
55281
  navigate,
54979
- notify,
54980
55282
  onTransition,
54981
55283
  onDispatched,
54982
55284
  onError
@@ -54988,8 +55290,6 @@ function PluginRuntimeMount({
54988
55290
  const renderedSlotsRef = useRef(/* @__PURE__ */ new Set());
54989
55291
  const navigateRef = useRef(navigate);
54990
55292
  navigateRef.current = navigate;
54991
- const notifyRef = useRef(notify);
54992
- notifyRef.current = notify;
54993
55293
  const [mockRuntime] = useState(() => {
54994
55294
  if (mode !== "mock") return void 0;
54995
55295
  return new OrbitalServerRuntime({
@@ -55000,8 +55300,7 @@ function PluginRuntimeMount({
55000
55300
  denySet: new Set(deny ?? []),
55001
55301
  slotsRef,
55002
55302
  renderedSlotsRef,
55003
- navigateRef,
55004
- notifyRef
55303
+ navigateRef
55005
55304
  })
55006
55305
  });
55007
55306
  });
@@ -55160,7 +55459,6 @@ function OrbitalPluginHost({
55160
55459
  transport,
55161
55460
  deny,
55162
55461
  navigate,
55163
- notify,
55164
55462
  onTransition,
55165
55463
  children
55166
55464
  }) {
@@ -55211,7 +55509,6 @@ function OrbitalPluginHost({
55211
55509
  transport,
55212
55510
  deny,
55213
55511
  navigate,
55214
- notify,
55215
55512
  onTransition,
55216
55513
  onDispatched: handleDispatched,
55217
55514
  onError: handleError