@edv4h/usketch-plugin-map 0.2.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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/autotile.d.ts +42 -0
  4. package/dist/autotile.d.ts.map +1 -0
  5. package/dist/autotile.js +96 -0
  6. package/dist/autotile.js.map +1 -0
  7. package/dist/gen-state.d.ts +20 -0
  8. package/dist/gen-state.d.ts.map +1 -0
  9. package/dist/gen-state.js +16 -0
  10. package/dist/gen-state.js.map +1 -0
  11. package/dist/generate.d.ts +28 -0
  12. package/dist/generate.d.ts.map +1 -0
  13. package/dist/generate.js +93 -0
  14. package/dist/generate.js.map +1 -0
  15. package/dist/generators/index.d.ts +34 -0
  16. package/dist/generators/index.d.ts.map +1 -0
  17. package/dist/generators/index.js +138 -0
  18. package/dist/generators/index.js.map +1 -0
  19. package/dist/generators/noise.d.ts +6 -0
  20. package/dist/generators/noise.d.ts.map +1 -0
  21. package/dist/generators/noise.js +39 -0
  22. package/dist/generators/noise.js.map +1 -0
  23. package/dist/generators/rng.d.ts +7 -0
  24. package/dist/generators/rng.d.ts.map +1 -0
  25. package/dist/generators/rng.js +31 -0
  26. package/dist/generators/rng.js.map +1 -0
  27. package/dist/icons.d.ts +17 -0
  28. package/dist/icons.d.ts.map +1 -0
  29. package/dist/icons.js +949 -0
  30. package/dist/icons.js.map +1 -0
  31. package/dist/index.d.ts +11 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +10 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/lod.d.ts +27 -0
  36. package/dist/lod.d.ts.map +1 -0
  37. package/dist/lod.js +73 -0
  38. package/dist/lod.js.map +1 -0
  39. package/dist/map-icon-shape.d.ts +14 -0
  40. package/dist/map-icon-shape.d.ts.map +1 -0
  41. package/dist/map-icon-shape.js +106 -0
  42. package/dist/map-icon-shape.js.map +1 -0
  43. package/dist/map-layer.d.ts +24 -0
  44. package/dist/map-layer.d.ts.map +1 -0
  45. package/dist/map-layer.js +167 -0
  46. package/dist/map-layer.js.map +1 -0
  47. package/dist/map-tool-id.d.ts +3 -0
  48. package/dist/map-tool-id.d.ts.map +1 -0
  49. package/dist/map-tool-id.js +3 -0
  50. package/dist/map-tool-id.js.map +1 -0
  51. package/dist/map-tool.d.ts +3 -0
  52. package/dist/map-tool.d.ts.map +1 -0
  53. package/dist/map-tool.js +308 -0
  54. package/dist/map-tool.js.map +1 -0
  55. package/dist/palette.d.ts +8 -0
  56. package/dist/palette.d.ts.map +1 -0
  57. package/dist/palette.js +92 -0
  58. package/dist/palette.js.map +1 -0
  59. package/dist/plugin.d.ts +18 -0
  60. package/dist/plugin.d.ts.map +1 -0
  61. package/dist/plugin.js +137 -0
  62. package/dist/plugin.js.map +1 -0
  63. package/dist/range-erase-state.d.ts +9 -0
  64. package/dist/range-erase-state.d.ts.map +1 -0
  65. package/dist/range-erase-state.js +12 -0
  66. package/dist/range-erase-state.js.map +1 -0
  67. package/dist/range-erase-tool.d.ts +4 -0
  68. package/dist/range-erase-tool.d.ts.map +1 -0
  69. package/dist/range-erase-tool.js +58 -0
  70. package/dist/range-erase-tool.js.map +1 -0
  71. package/dist/range-erase.d.ts +14 -0
  72. package/dist/range-erase.d.ts.map +1 -0
  73. package/dist/range-erase.js +74 -0
  74. package/dist/range-erase.js.map +1 -0
  75. package/dist/reactive-store.d.ts +7 -0
  76. package/dist/reactive-store.d.ts.map +1 -0
  77. package/dist/reactive-store.js +33 -0
  78. package/dist/reactive-store.js.map +1 -0
  79. package/dist/render-config.d.ts +19 -0
  80. package/dist/render-config.d.ts.map +1 -0
  81. package/dist/render-config.js +16 -0
  82. package/dist/render-config.js.map +1 -0
  83. package/dist/svg-nodes.d.ts +12 -0
  84. package/dist/svg-nodes.d.ts.map +1 -0
  85. package/dist/svg-nodes.js +34 -0
  86. package/dist/svg-nodes.js.map +1 -0
  87. package/dist/team/enter-banner.d.ts +6 -0
  88. package/dist/team/enter-banner.d.ts.map +1 -0
  89. package/dist/team/enter-banner.js +111 -0
  90. package/dist/team/enter-banner.js.map +1 -0
  91. package/dist/team/team-layer.d.ts +6 -0
  92. package/dist/team/team-layer.d.ts.map +1 -0
  93. package/dist/team/team-layer.js +121 -0
  94. package/dist/team/team-layer.js.map +1 -0
  95. package/dist/team/team-map-shape.d.ts +20 -0
  96. package/dist/team/team-map-shape.d.ts.map +1 -0
  97. package/dist/team/team-map-shape.js +74 -0
  98. package/dist/team/team-map-shape.js.map +1 -0
  99. package/dist/team/team-ops.d.ts +50 -0
  100. package/dist/team/team-ops.d.ts.map +1 -0
  101. package/dist/team/team-ops.js +176 -0
  102. package/dist/team/team-ops.js.map +1 -0
  103. package/dist/team/team-state.d.ts +9 -0
  104. package/dist/team/team-state.d.ts.map +1 -0
  105. package/dist/team/team-state.js +13 -0
  106. package/dist/team/team-state.js.map +1 -0
  107. package/dist/terrain.d.ts +15 -0
  108. package/dist/terrain.d.ts.map +1 -0
  109. package/dist/terrain.js +309 -0
  110. package/dist/terrain.js.map +1 -0
  111. package/dist/tilemap-shape.d.ts +16 -0
  112. package/dist/tilemap-shape.d.ts.map +1 -0
  113. package/dist/tilemap-shape.js +77 -0
  114. package/dist/tilemap-shape.js.map +1 -0
  115. package/dist/tool-state.d.ts +12 -0
  116. package/dist/tool-state.d.ts.map +1 -0
  117. package/dist/tool-state.js +14 -0
  118. package/dist/tool-state.js.map +1 -0
  119. package/dist/ui/palette.d.ts +7 -0
  120. package/dist/ui/palette.d.ts.map +1 -0
  121. package/dist/ui/palette.js +178 -0
  122. package/dist/ui/palette.js.map +1 -0
  123. package/dist/ui/range-erase-palette.d.ts +5 -0
  124. package/dist/ui/range-erase-palette.d.ts.map +1 -0
  125. package/dist/ui/range-erase-palette.js +42 -0
  126. package/dist/ui/range-erase-palette.js.map +1 -0
  127. package/package.json +49 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-erase-tool.d.ts","sourceRoot":"","sources":["../src/range-erase-tool.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAmC,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAO7F,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAqBjD,wBAAgB,8BAA8B,CAAC,IAAI,GAAE,MAAqB,GAAG,cAAc,CAkD1F"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { genStateStore } from "./gen-state.js";
3
+ import { eraseRangeBox } from "./range-erase.js";
4
+ import { rangeEraseStore } from "./range-erase-state.js";
5
+ import { DEFAULT_TILE } from "./tilemap-shape.js";
6
+ export const RANGE_ERASE_TOOL_ID = "range-erase";
7
+ function RangeEraseIcon() {
8
+ return (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 20 20", fill: "none", children: [_jsx("rect", { x: "2.5", y: "2.5", width: "15", height: "15", rx: "2", fill: "none", stroke: "#EF5350", strokeWidth: "1.6", strokeDasharray: "3 2.4" }), _jsx("path", { d: "M6 6 L14 14 M14 6 L6 14", stroke: "#EF5350", strokeWidth: "1.6", strokeLinecap: "round" })] }));
9
+ }
10
+ export function createRangeEraseToolDefinition(tile = DEFAULT_TILE) {
11
+ let drag = null;
12
+ return {
13
+ icon: RangeEraseIcon,
14
+ cursor: "crosshair",
15
+ shortcut: "x",
16
+ order: 46,
17
+ onPointerDown(_ctx, event) {
18
+ drag = { x0: event.worldPoint.x, y0: event.worldPoint.y };
19
+ genStateStore.set({
20
+ pendingRect: { x: event.worldPoint.x, y: event.worldPoint.y, w: 0, h: 0 },
21
+ });
22
+ },
23
+ onPointerMove(_ctx, event) {
24
+ if (!drag)
25
+ return;
26
+ const x = Math.min(drag.x0, event.worldPoint.x);
27
+ const y = Math.min(drag.y0, event.worldPoint.y);
28
+ const w = Math.abs(event.worldPoint.x - drag.x0);
29
+ const h = Math.abs(event.worldPoint.y - drag.y0);
30
+ genStateStore.set({ pendingRect: { x, y, w, h } });
31
+ },
32
+ onPointerUp(ctx) {
33
+ if (!drag)
34
+ return;
35
+ const rect = genStateStore.get().pendingRect;
36
+ drag = null;
37
+ genStateStore.set({ pendingRect: null });
38
+ if (rect && rect.w >= tile / 2 && rect.h >= tile / 2) {
39
+ // Right/bottom edges exclusive → ceil-1 so a boundary drag doesn't grab
40
+ // an extra cell (matches the generate tool).
41
+ const box = {
42
+ minC: Math.floor(rect.x / tile),
43
+ minR: Math.floor(rect.y / tile),
44
+ maxC: Math.ceil((rect.x + rect.w) / tile) - 1,
45
+ maxR: Math.ceil((rect.y + rect.h) / tile) - 1,
46
+ };
47
+ eraseRangeBox({ store: ctx.store, commands: ctx.commands, tile }, box, rangeEraseStore.get());
48
+ }
49
+ },
50
+ onDeactivate() {
51
+ if (drag) {
52
+ drag = null;
53
+ genStateStore.set({ pendingRect: null });
54
+ }
55
+ },
56
+ };
57
+ }
58
+ //# sourceMappingURL=range-erase-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-erase-tool.js","sourceRoot":"","sources":["../src/range-erase-tool.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { BoardStore, CommandRegistry } from "@edv4h/usketch-shared";
2
+ import { type CellBox } from "./autotile.js";
3
+ import type { RangeEraseTargets } from "./range-erase-state.js";
4
+ export interface RangeEraseDeps {
5
+ store: BoardStore;
6
+ commands: CommandRegistry;
7
+ tile: number;
8
+ }
9
+ /**
10
+ * Clear the selected targets (terrain and/or team ownership) inside `box` as one
11
+ * undoable command (no-op if nothing is selected or nothing changes).
12
+ */
13
+ export declare function eraseRangeBox(deps: RangeEraseDeps, box: CellBox, targets: RangeEraseTargets): void;
14
+ //# sourceMappingURL=range-erase.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-erase.d.ts","sourceRoot":"","sources":["../src/range-erase.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACX,UAAU,EAGV,eAAe,EAEf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,OAAO,EAA6B,MAAM,eAAe,CAAC;AACxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAIhE,MAAM,WAAW,cAAc;IAC9B,KAAK,EAAE,UAAU,CAAC;IAClB,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;CACb;AAkCD;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,cAAc,EACpB,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,iBAAiB,GACxB,IAAI,CAkCN"}
@@ -0,0 +1,74 @@
1
+ import { cellsBounds, parseCellKey } from "./autotile.js";
2
+ import { isTeamMap, ownerBounds } from "./team/team-map-shape.js";
3
+ import { isTileMap } from "./tilemap-shape.js";
4
+ // One shape's box-clear: sparse-scan existing keys, remove those in `box`. Returns
5
+ // the store patch pair (or null when nothing changes). `field` is the intrinsic
6
+ // sparse map ("cells" for tilemap, "owner" for team-map).
7
+ function boxClearOp(shapeId, map, field, box, bounds) {
8
+ const toDelete = [];
9
+ for (const key of Object.keys(map)) {
10
+ const [c, r] = parseCellKey(key);
11
+ if (c >= box.minC && c <= box.maxC && r >= box.minR && r <= box.maxR)
12
+ toDelete.push(key);
13
+ }
14
+ if (toDelete.length === 0)
15
+ return null; // no-op → don't clone
16
+ const prevMap = { ...map };
17
+ const nextMap = { ...map };
18
+ for (const k of toDelete)
19
+ delete nextMap[k];
20
+ return {
21
+ id: shapeId,
22
+ prev: { [field]: prevMap, ...bounds(prevMap) },
23
+ next: { [field]: nextMap, ...bounds(nextMap) },
24
+ };
25
+ }
26
+ /**
27
+ * Clear the selected targets (terrain and/or team ownership) inside `box` as one
28
+ * undoable command (no-op if nothing is selected or nothing changes).
29
+ */
30
+ export function eraseRangeBox(deps, box, targets) {
31
+ const { store, commands, tile } = deps;
32
+ if (!targets.terrain && !targets.team)
33
+ return;
34
+ // tilemap / team-map are single shared substrates (like resolveTilemap /
35
+ // resolveTeamMap), so target the first of each.
36
+ let tilemap;
37
+ let teammap;
38
+ for (const [, s] of store.getShapes()) {
39
+ if (!tilemap && isTileMap(s))
40
+ tilemap = s;
41
+ else if (!teammap && isTeamMap(s))
42
+ teammap = s;
43
+ if (tilemap && teammap)
44
+ break;
45
+ }
46
+ const ops = [];
47
+ // Use each shape's own tile size (boards may differ from the tool default).
48
+ if (targets.terrain && tilemap) {
49
+ const t = tilemap.tile ?? tile;
50
+ const op = boxClearOp(tilemap.id, tilemap.cells, "cells", box, (m) => cellsBounds(m, t));
51
+ if (op)
52
+ ops.push(op);
53
+ }
54
+ if (targets.team && teammap) {
55
+ const t = teammap.tile ?? tile;
56
+ const op = boxClearOp(teammap.id, teammap.owner, "owner", box, (m) => ownerBounds(m, t));
57
+ if (op)
58
+ ops.push(op);
59
+ }
60
+ if (ops.length === 0)
61
+ return;
62
+ const command = {
63
+ execute: () => {
64
+ for (const o of ops)
65
+ store.updateShape(o.id, o.next);
66
+ },
67
+ undo: () => {
68
+ for (const o of ops)
69
+ store.updateShape(o.id, o.prev);
70
+ },
71
+ };
72
+ commands.execute(command);
73
+ }
74
+ //# sourceMappingURL=range-erase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range-erase.js","sourceRoot":"","sources":["../src/range-erase.ts"],"names":[],"mappings":"AASA,OAAO,EAAgB,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAExE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAyB,MAAM,0BAA0B,CAAC;AACzF,OAAO,EAAE,SAAS,EAAyB,MAAM,oBAAoB,CAAC;AActE,mFAAmF;AACnF,gFAAgF;AAChF,0DAA0D;AAC1D,SAAS,UAAU,CAClB,OAAe,EACf,GAAM,EACN,KAAwB,EACxB,GAAY,EACZ,MAA6B;IAE7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI;YAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,CAAC,sBAAsB;IAC9D,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,EAAE,GAAG,GAAG,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5C,OAAO;QACN,EAAE,EAAE,OAAO;QACX,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAwB;QACpE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,EAAwB;KACpE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC5B,IAAoB,EACpB,GAAY,EACZ,OAA0B;IAE1B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACvC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI;QAAE,OAAO;IAC9C,yEAAyE;IACzE,gDAAgD;IAChD,IAAI,OAAqC,CAAC;IAC1C,IAAI,OAAqC,CAAC;IAC1C,KAAK,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC;QACvC,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC,CAAC;aACrC,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC,CAAC;QAC/C,IAAI,OAAO,IAAI,OAAO;YAAE,MAAM;IAC/B,CAAC;IACD,MAAM,GAAG,GAAc,EAAE,CAAC;IAC1B,4EAA4E;IAC5E,IAAI,OAAO,CAAC,OAAO,IAAI,OAAO,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;QAC/B,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzF,IAAI,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;QAC/B,MAAM,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACzF,IAAI,EAAE;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC7B,MAAM,OAAO,GAAY;QACxB,OAAO,EAAE,GAAG,EAAE;YACb,KAAK,MAAM,CAAC,IAAI,GAAG;gBAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,EAAE,GAAG,EAAE;YACV,KAAK,MAAM,CAAC,IAAI,GAAG;gBAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;QACtD,CAAC;KACD,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,7 @@
1
+ export interface ReactiveStore<T> {
2
+ get(): T;
3
+ set(patch: Partial<T>): void;
4
+ subscribe(listener: () => void): () => void;
5
+ }
6
+ export declare function createReactiveStore<T extends object>(initial: T): ReactiveStore<T>;
7
+ //# sourceMappingURL=reactive-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactive-store.d.ts","sourceRoot":"","sources":["../src/reactive-store.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa,CAAC,CAAC;IAC/B,GAAG,IAAI,CAAC,CAAC;IACT,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;CAC5C;AAED,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,CA0BlF"}
@@ -0,0 +1,33 @@
1
+ // Minimal module-scoped reactive store (get/set/subscribe) for useSyncExternalStore.
2
+ // Used for plugin-local UI state (Tweaks, active tool mode) that is intentionally
3
+ // NOT synced across clients — it is presentation/interaction state, not board data.
4
+ export function createReactiveStore(initial) {
5
+ let state = initial;
6
+ const listeners = new Set();
7
+ return {
8
+ get: () => state,
9
+ set(patch) {
10
+ // Skip `undefined` keys so a partial update (e.g. only `lineStyle`) never
11
+ // clobbers an unrelated field with `undefined`.
12
+ const next = { ...state };
13
+ let changed = false;
14
+ for (const k of Object.keys(patch)) {
15
+ const v = patch[k];
16
+ if (v !== undefined && v !== state[k]) {
17
+ next[k] = v;
18
+ changed = true;
19
+ }
20
+ }
21
+ if (!changed)
22
+ return;
23
+ state = next;
24
+ for (const l of listeners)
25
+ l();
26
+ },
27
+ subscribe(listener) {
28
+ listeners.add(listener);
29
+ return () => listeners.delete(listener);
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=reactive-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reactive-store.js","sourceRoot":"","sources":["../src/reactive-store.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,kFAAkF;AAClF,oFAAoF;AAQpF,MAAM,UAAU,mBAAmB,CAAmB,OAAU;IAC/D,IAAI,KAAK,GAAG,OAAO,CAAC;IACpB,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IACxC,OAAO;QACN,GAAG,EAAE,GAAG,EAAE,CAAC,KAAK;QAChB,GAAG,CAAC,KAAK;YACR,0EAA0E;YAC1E,gDAAgD;YAChD,MAAM,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;YAC1B,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAgB,EAAE,CAAC;gBACnD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACnB,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAe,CAAC;oBAC1B,OAAO,GAAG,IAAI,CAAC;gBAChB,CAAC;YACF,CAAC;YACD,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,KAAK,GAAG,IAAI,CAAC;YACb,KAAK,MAAM,CAAC,IAAI,SAAS;gBAAE,CAAC,EAAE,CAAC;QAChC,CAAC;QACD,SAAS,CAAC,QAAQ;YACjB,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACzC,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ColorMode } from "./palette.js";
2
+ import type { TerrainKey } from "./terrain.js";
3
+ export type LineStyle = "wobble" | "clean";
4
+ export interface MapRenderConfig {
5
+ colorMode: ColorMode;
6
+ lineStyle: LineStyle;
7
+ /** Multiplier on the hand-drawn stroke width (design `--sw`, base 2.6px). */
8
+ strokeScale: number;
9
+ /**
10
+ * Terrain used for unset cells. When set (e.g. "water"), unpainted / off-map
11
+ * space renders and is judged as that terrain — an infinite sea with painted
12
+ * land on top. `null` = truly empty (transparent, prior behavior).
13
+ */
14
+ emptyTerrain: TerrainKey | null;
15
+ }
16
+ export declare const renderConfigStore: import("./reactive-store.js").ReactiveStore<MapRenderConfig>;
17
+ /** Subscribe a component to the current Tweaks config. */
18
+ export declare function useRenderConfig(): MapRenderConfig;
19
+ //# sourceMappingURL=render-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-config.d.ts","sourceRoot":"","sources":["../src/render-config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC/B,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,SAAS,CAAC;IACrB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,YAAY,EAAE,UAAU,GAAG,IAAI,CAAC;CAChC;AAED,eAAO,MAAM,iBAAiB,8DAK5B,CAAC;AAEH,0DAA0D;AAC1D,wBAAgB,eAAe,IAAI,eAAe,CAMjD"}
@@ -0,0 +1,16 @@
1
+ // Visual "Tweaks" for the map: colorful⇔mono, wobble⇔clean line, stroke width.
2
+ // Module-scoped so shapes/layers can subscribe before plugin setup runs. This is
3
+ // look-and-feel state (app-local), not synced board data.
4
+ import { useSyncExternalStore } from "react";
5
+ import { createReactiveStore } from "./reactive-store.js";
6
+ export const renderConfigStore = createReactiveStore({
7
+ colorMode: "color",
8
+ lineStyle: "wobble",
9
+ strokeScale: 1,
10
+ emptyTerrain: null,
11
+ });
12
+ /** Subscribe a component to the current Tweaks config. */
13
+ export function useRenderConfig() {
14
+ return useSyncExternalStore(renderConfigStore.subscribe, renderConfigStore.get, renderConfigStore.get);
15
+ }
16
+ //# sourceMappingURL=render-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-config.js","sourceRoot":"","sources":["../src/render-config.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,iFAAiF;AACjF,0DAA0D;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAC;AAE7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAkB1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAmB,CAAkB;IACrE,SAAS,EAAE,OAAO;IAClB,SAAS,EAAE,QAAQ;IACnB,WAAW,EAAE,CAAC;IACd,YAAY,EAAE,IAAI;CAClB,CAAC,CAAC;AAEH,0DAA0D;AAC1D,MAAM,UAAU,eAAe;IAC9B,OAAO,oBAAoB,CAC1B,iBAAiB,CAAC,SAAS,EAC3B,iBAAiB,CAAC,GAAG,EACrB,iBAAiB,CAAC,GAAG,CACrB,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ReactElement } from "react";
2
+ export interface SvgNode {
3
+ /** Tag name (rect, g, path, circle, ellipse, line, polyline, polygon, …). */
4
+ t: string;
5
+ /** Presentational attributes, as authored (hyphenated names are converted). */
6
+ a: Record<string, string>;
7
+ /** Child nodes. */
8
+ c?: SvgNode[];
9
+ }
10
+ /** Render a list of SVG nodes to React elements. */
11
+ export declare function renderSvgNodes(nodes: readonly SvgNode[], keyPrefix?: string): ReactElement[];
12
+ //# sourceMappingURL=svg-nodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-nodes.d.ts","sourceRoot":"","sources":["../src/svg-nodes.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,WAAW,OAAO;IACvB,6EAA6E;IAC7E,CAAC,EAAE,MAAM,CAAC;IACV,+EAA+E;IAC/E,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1B,mBAAmB;IACnB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;CACd;AAuBD,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,EAAE,SAAS,SAAM,GAAG,YAAY,EAAE,CAMzF"}
@@ -0,0 +1,34 @@
1
+ // Renders a parsed SVG element tree (from terrain.ts / icons.ts) with
2
+ // React.createElement — deliberately NOT dangerouslySetInnerHTML, matching the
3
+ // repo's XSS-safe policy. The data is static bundled design markup; this keeps
4
+ // it as real React SVG elements with proper (camelCased) attributes.
5
+ import { createElement } from "react";
6
+ // Attribute names that must NOT be naively hyphen→camel converted the generic way.
7
+ const ATTR_MAP = {
8
+ class: "className",
9
+ "xlink:href": "xlinkHref",
10
+ };
11
+ /** Convert an SVG attribute name to its React (camelCase) form. */
12
+ function toReactAttr(name) {
13
+ if (ATTR_MAP[name])
14
+ return ATTR_MAP[name];
15
+ if (name.includes("-")) {
16
+ return name.replace(/-([a-z])/g, (_, ch) => ch.toUpperCase());
17
+ }
18
+ return name;
19
+ }
20
+ function toProps(a, key) {
21
+ const props = { key };
22
+ for (const [k, v] of Object.entries(a))
23
+ props[toReactAttr(k)] = v;
24
+ return props;
25
+ }
26
+ /** Render a list of SVG nodes to React elements. */
27
+ export function renderSvgNodes(nodes, keyPrefix = "n") {
28
+ return nodes.map((node, i) => {
29
+ const key = `${keyPrefix}-${i}`;
30
+ const children = node.c ? renderSvgNodes(node.c, key) : undefined;
31
+ return createElement(node.t, toProps(node.a, key), children);
32
+ });
33
+ }
34
+ //# sourceMappingURL=svg-nodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"svg-nodes.js","sourceRoot":"","sources":["../src/svg-nodes.tsx"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,+EAA+E;AAC/E,+EAA+E;AAC/E,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAqB,MAAM,OAAO,CAAC;AAWzD,mFAAmF;AACnF,MAAM,QAAQ,GAA2B;IACxC,KAAK,EAAE,WAAW;IAClB,YAAY,EAAE,WAAW;CACzB,CAAC;AAEF,mEAAmE;AACnE,SAAS,WAAW,CAAC,IAAY;IAChC,IAAI,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,OAAO,CAAC,CAAyB,EAAE,GAAW;IACtD,MAAM,KAAK,GAA4B,EAAE,GAAG,EAAE,CAAC;IAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC;AACd,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,cAAc,CAAC,KAAyB,EAAE,SAAS,GAAG,GAAG;IACxE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC5B,MAAM,GAAG,GAAG,GAAG,SAAS,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAClE,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { BoardStore } from "@edv4h/usketch-shared";
2
+ export declare function EnterBanner({ store, tile }: {
3
+ store: BoardStore;
4
+ tile: number;
5
+ }): import("react").JSX.Element | null;
6
+ //# sourceMappingURL=enter-banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter-banner.d.ts","sourceRoot":"","sources":["../../src/team/enter-banner.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAmBxD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,sCAiI/E"}
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { MAP_TOOL_ID } from "../map-tool-id.js";
4
+ import { useMapToolState } from "../tool-state.js";
5
+ import { getTeamMap, teamIdAtWorld } from "./team-ops.js";
6
+ const BANNER_MS = 2600;
7
+ /** World point the local user is "standing on" — the viewport centre. */
8
+ function viewportCenterWorld(store) {
9
+ if (typeof window === "undefined")
10
+ return null;
11
+ const vp = store.getViewport();
12
+ return {
13
+ x: (window.innerWidth / 2 - vp.x) / vp.zoom,
14
+ y: (window.innerHeight / 2 - vp.y) / vp.zoom,
15
+ };
16
+ }
17
+ export function EnterBanner({ store, tile }) {
18
+ const tool = useMapToolState();
19
+ const [activeTool, setActiveTool] = useState(store.getActiveToolId());
20
+ const [current, setCurrent] = useState(null);
21
+ const [banner, setBanner] = useState(null);
22
+ const [bannerKey, setBannerKey] = useState(0);
23
+ const prevRef = useRef(null);
24
+ const rafRef = useRef(0);
25
+ const timerRef = useRef(0);
26
+ // Only show the team indicator while actually in team mode (map tool + team submode).
27
+ useEffect(() => store.subscribe(() => setActiveTool(store.getActiveToolId())), [store]);
28
+ const inTeamMode = activeTool === MAP_TOOL_ID && tool.mode === "team";
29
+ // Leaving team mode clears any in-flight entry banner + timeout so a stale
30
+ // banner can't reappear when returning to team mode before it fades.
31
+ useEffect(() => {
32
+ if (!inTeamMode) {
33
+ clearTimeout(timerRef.current);
34
+ setBanner(null);
35
+ }
36
+ }, [inTeamMode]);
37
+ useEffect(() => {
38
+ const update = () => {
39
+ cancelAnimationFrame(rafRef.current);
40
+ rafRef.current = requestAnimationFrame(() => {
41
+ const team = getTeamMap(store);
42
+ let id = null;
43
+ const center = viewportCenterWorld(store);
44
+ if (team && center && Object.keys(team.owner).length > 0) {
45
+ id = teamIdAtWorld(team.owner, center.x, center.y, tile);
46
+ }
47
+ if (id === prevRef.current)
48
+ return;
49
+ prevRef.current = id;
50
+ const info = id && team ? (team.teams[id] ?? null) : null;
51
+ setCurrent(info);
52
+ if (info) {
53
+ setBanner(info);
54
+ setBannerKey((k) => k + 1); // restart the entrance animation
55
+ clearTimeout(timerRef.current);
56
+ timerRef.current = window.setTimeout(() => setBanner(null), BANNER_MS);
57
+ }
58
+ });
59
+ };
60
+ update();
61
+ const u = store.subscribe(update);
62
+ return () => {
63
+ u();
64
+ cancelAnimationFrame(rafRef.current);
65
+ clearTimeout(timerRef.current);
66
+ };
67
+ }, [store, tile]);
68
+ if (!inTeamMode || (!current && !banner))
69
+ return null;
70
+ return (_jsxs("div", { style: { position: "absolute", inset: 0, pointerEvents: "none" }, children: [_jsx("style", { children: "@keyframes uskmap-enter{0%{opacity:0;transform:translate(-50%,-16px)}12%{opacity:1;transform:translate(-50%,0)}88%{opacity:1}100%{opacity:0}}" }), banner && (_jsxs("div", { style: {
71
+ position: "absolute",
72
+ left: "50%",
73
+ top: 26,
74
+ transform: "translate(-50%,0)",
75
+ display: "flex",
76
+ alignItems: "center",
77
+ gap: 10,
78
+ padding: "10px 22px",
79
+ background: "rgba(255,255,255,.96)",
80
+ border: `3px solid ${banner.color}`,
81
+ borderRadius: 14,
82
+ font: "800 18px system-ui, sans-serif",
83
+ color: "#1c1c1c",
84
+ whiteSpace: "nowrap",
85
+ boxShadow: "0 8px 26px rgba(0,0,0,.2)",
86
+ animation: `uskmap-enter ${BANNER_MS}ms ease-out forwards`,
87
+ }, children: [_jsx("span", { style: { fontSize: 20 }, children: "\u2694" }), _jsxs("span", { children: [_jsx("span", { style: { color: banner.color }, children: banner.name }), " \u306E\u30A8\u30EA\u30A2\u306B\u5165\u3063\u305F"] })] }, bannerKey)), current && (_jsxs("div", { style: {
88
+ position: "absolute",
89
+ left: "50%",
90
+ bottom: 18,
91
+ transform: "translateX(-50%)",
92
+ display: "flex",
93
+ alignItems: "center",
94
+ gap: 7,
95
+ padding: "5px 13px",
96
+ background: "rgba(255,255,255,.9)",
97
+ border: `2px solid ${current.color}`,
98
+ borderRadius: 20,
99
+ font: "700 13px system-ui, sans-serif",
100
+ color: "#1c1c1c",
101
+ whiteSpace: "nowrap",
102
+ boxShadow: "0 2px 10px rgba(0,0,0,.14)",
103
+ }, children: [_jsx("span", { style: {
104
+ width: 11,
105
+ height: 11,
106
+ borderRadius: "50%",
107
+ background: current.color,
108
+ flex: "none",
109
+ } }), "\u73FE\u5728\u5730: ", current.name] }))] }));
110
+ }
111
+ //# sourceMappingURL=enter-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enter-banner.js","sourceRoot":"","sources":["../../src/team/enter-banner.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { BoardStore, RenderMode } from "@edv4h/usketch-shared";
2
+ export declare function TeamAreaLayer({ store, renderMode, }: {
3
+ store: BoardStore;
4
+ renderMode?: RenderMode;
5
+ }): import("react").JSX.Element | null;
6
+ //# sourceMappingURL=team-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-layer.d.ts","sourceRoot":"","sources":["../../src/team/team-layer.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAoGpE,wBAAgB,aAAa,CAAC,EAC7B,KAAK,EACL,UAAU,GACV,EAAE;IACF,KAAK,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,UAAU,CAAC;CACxB,sCAwEA"}
@@ -0,0 +1,121 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState } from "react";
3
+ import { exposedEdges, parseCellKey } from "../autotile.js";
4
+ import { blockFactor, downsampleCells, tileDetail } from "../lod.js";
5
+ import { visibleCellRange, visibleWorldRect } from "../map-layer.js";
6
+ import { getTeamMap, teamRegionAnchors } from "./team-ops.js";
7
+ const FILL_OPACITY = 0.24;
8
+ const BORDER_RATIO = 0.16; // border strip thickness, fraction of a tile
9
+ const BORDER_OPACITY = 0.85;
10
+ /** Full tier: per-cell translucent fill + team-coloured border on region edges. */
11
+ function renderFull(owner, teams, tile, visible) {
12
+ const nodes = [];
13
+ const asCells = owner; // exposedEdges only compares values
14
+ const bt = BORDER_RATIO * tile;
15
+ const range = visibleCellRange(visible, tile);
16
+ const emit = (c, r) => {
17
+ const teamId = owner[`${c},${r}`];
18
+ if (!teamId)
19
+ return;
20
+ const color = teams[teamId]?.color;
21
+ if (!color)
22
+ return;
23
+ const x = c * tile;
24
+ const y = r * tile;
25
+ nodes.push(_jsx("rect", { x: x, y: y, width: tile, height: tile, fill: color, fillOpacity: FILL_OPACITY }, `${c},${r}:f`));
26
+ const edge = exposedEdges(asCells, c, r);
27
+ const strip = (sx, sy, sw, sh, k) => (_jsx("rect", { x: sx, y: sy, width: sw, height: sh, fill: color, fillOpacity: BORDER_OPACITY }, k));
28
+ if (edge.n)
29
+ nodes.push(strip(x, y, tile, bt, `${c},${r}:n`));
30
+ if (edge.s)
31
+ nodes.push(strip(x, y + tile - bt, tile, bt, `${c},${r}:s`));
32
+ if (edge.w)
33
+ nodes.push(strip(x, y, bt, tile, `${c},${r}:w`));
34
+ if (edge.e)
35
+ nodes.push(strip(x + tile - bt, y, bt, tile, `${c},${r}:e`));
36
+ };
37
+ if (range) {
38
+ for (let r = range.r0; r <= range.r1; r++)
39
+ for (let c = range.c0; c <= range.c1; c++)
40
+ emit(c, r);
41
+ }
42
+ else {
43
+ for (const key of Object.keys(owner)) {
44
+ const [c, r] = parseCellKey(key);
45
+ emit(c, r);
46
+ }
47
+ }
48
+ return nodes;
49
+ }
50
+ /** Coarse tier: flat translucent blocks (downsampled by owning team). */
51
+ function renderCoarse(owner, teams, tile, screenTilePx, visible) {
52
+ const factor = blockFactor(screenTilePx);
53
+ const bt = factor * tile;
54
+ const nodes = [];
55
+ for (const [bk, teamId] of Object.entries(downsampleCells(owner, factor))) {
56
+ const color = teams[teamId]?.color;
57
+ if (!color)
58
+ continue;
59
+ const [bc, br] = parseCellKey(bk);
60
+ const x = bc * bt;
61
+ const y = br * bt;
62
+ if (visible &&
63
+ (x > visible.right || y > visible.bottom || x + bt < visible.left || y + bt < visible.top)) {
64
+ continue;
65
+ }
66
+ nodes.push(_jsx("rect", { x: x, y: y, width: bt, height: bt, fill: color, fillOpacity: FILL_OPACITY }, bk));
67
+ }
68
+ return nodes;
69
+ }
70
+ export function TeamAreaLayer({ store, renderMode, }) {
71
+ const [, force] = useState(0);
72
+ const rafRef = useRef(0);
73
+ useEffect(() => {
74
+ const rerender = () => {
75
+ cancelAnimationFrame(rafRef.current);
76
+ rafRef.current = requestAnimationFrame(() => force((n) => n + 1));
77
+ };
78
+ const u = store.subscribe(rerender);
79
+ return () => {
80
+ u();
81
+ cancelAnimationFrame(rafRef.current);
82
+ };
83
+ }, [store]);
84
+ const team = getTeamMap(store);
85
+ if (!team || Object.keys(team.owner).length === 0)
86
+ return null;
87
+ const vp = store.getViewport();
88
+ const visible = visibleWorldRect(store);
89
+ const tile = team.tile;
90
+ const screenTilePx = tile * vp.zoom;
91
+ const detail = tileDetail(screenTilePx, renderMode);
92
+ const cells = detail === "full"
93
+ ? renderFull(team.owner, team.teams, tile, visible)
94
+ : renderCoarse(team.owner, team.teams, tile, screenTilePx, visible);
95
+ // Labels: HTML chips at screen coords (crisp, constant size). Hidden when coarse.
96
+ const anchors = detail === "full" ? teamRegionAnchors(team.owner, team.teams, tile) : [];
97
+ return (_jsxs("div", { style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "hidden" }, children: [_jsx("svg", { width: "100%", height: "100%", style: { display: "block", overflow: "visible" }, children: _jsx("g", { transform: `translate(${vp.x} ${vp.y}) scale(${vp.zoom})`, children: cells }) }), anchors.map((a) => (_jsxs("div", { style: {
98
+ position: "absolute",
99
+ left: a.x * vp.zoom + vp.x,
100
+ top: a.y * vp.zoom + vp.y,
101
+ transform: "translate(-50%,-50%)",
102
+ display: "flex",
103
+ alignItems: "center",
104
+ gap: 5,
105
+ padding: "3px 9px",
106
+ background: "rgba(255,255,255,.9)",
107
+ border: `2px solid ${a.color}`,
108
+ borderRadius: 20,
109
+ font: "700 12px system-ui, sans-serif",
110
+ color: "#1c1c1c",
111
+ whiteSpace: "nowrap",
112
+ boxShadow: "0 2px 8px rgba(0,0,0,.14)",
113
+ }, children: [_jsx("span", { style: {
114
+ width: 10,
115
+ height: 10,
116
+ borderRadius: "50%",
117
+ background: a.color,
118
+ flex: "none",
119
+ } }), a.name] }, a.teamId)))] }));
120
+ }
121
+ //# sourceMappingURL=team-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-layer.js","sourceRoot":"","sources":["../../src/team/team-layer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { BoundingBox, ShapeData, ShapeDefinition } from "@edv4h/usketch-shared";
2
+ export declare const TEAM_MAP_TYPE = "team-map";
3
+ export interface TeamInfo {
4
+ name: string;
5
+ color: string;
6
+ }
7
+ /** cellKey("c,r") → teamId (sparse ownership map). */
8
+ export type OwnerMap = Record<string, string>;
9
+ export interface TeamMapShapeData extends ShapeData {
10
+ type: "team-map";
11
+ tile: number;
12
+ teams: Record<string, TeamInfo>;
13
+ owner: OwnerMap;
14
+ }
15
+ export declare function isTeamMap(shape: ShapeData): shape is TeamMapShapeData;
16
+ export declare function makeTeamMap(tile: number): TeamMapShapeData;
17
+ /** Bounds of all owned cells (keys are cellKeys). */
18
+ export declare function ownerBounds(owner: OwnerMap, tile: number): BoundingBox;
19
+ export declare function createTeamMapShapeDefinition(tile?: number): ShapeDefinition;
20
+ //# sourceMappingURL=team-map-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team-map-shape.d.ts","sourceRoot":"","sources":["../../src/team/team-map-shape.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAKrF,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC,MAAM,WAAW,QAAQ;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd;AAED,sDAAsD;AACtD,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IAClD,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,KAAK,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,IAAI,gBAAgB,CAErE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAc1D;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAGtE;AAED,wBAAgB,4BAA4B,CAAC,IAAI,GAAE,MAAqB,GAAG,eAAe,CA2CzF"}