castle-web-cli 0.4.119 → 0.4.121

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 (44) hide show
  1. package/dist/api.js +13 -2
  2. package/dist/castle-host/host.d.ts +16 -0
  3. package/dist/castle-host/host.js +249 -11
  4. package/dist/castle-host/leaderboardPanel.d.ts +73 -0
  5. package/dist/castle-host/leaderboardPanel.js +714 -0
  6. package/dist/ide.d.ts +3 -0
  7. package/dist/ide.js +79 -0
  8. package/dist/index.js +1 -6
  9. package/dist/init.js +1 -1
  10. package/dist/preview.d.ts +0 -1
  11. package/dist/preview.js +18 -23
  12. package/dist/save-deck.js +33 -2
  13. package/dist/serve.js +9 -4
  14. package/dist/shell/assets/index-BkJ87APM.css +1 -0
  15. package/dist/shell/assets/index-UEwjXWKI.js +434 -0
  16. package/dist/shell/index.html +2 -2
  17. package/kits/physics-2d/CLAUDE.md +64 -9
  18. package/kits/physics-2d/behaviors/AnalogStick.jsx +40 -9
  19. package/kits/physics-2d/behaviors/Collider.jsx +12 -0
  20. package/kits/physics-2d/behaviors/Draggable.jsx +67 -23
  21. package/kits/physics-2d/behaviors/Goal.jsx +2 -0
  22. package/kits/physics-2d/behaviors/Joints.jsx +5 -0
  23. package/kits/physics-2d/behaviors/RigidBody.jsx +16 -0
  24. package/kits/physics-2d/behaviors/Slingshot.jsx +48 -16
  25. package/kits/physics-2d/behaviors/Sound.jsx +11 -0
  26. package/kits/physics-2d/behaviors/Sprite.jsx +7 -0
  27. package/kits/physics-2d/behaviors/Tone.jsx +12 -0
  28. package/kits/physics-2d/behaviors/Video.jsx +6 -0
  29. package/kits/physics-2d/castle.json +1 -1
  30. package/kits/physics-2d/editors/SceneEditor.jsx +53 -8
  31. package/kits/physics-2d/editors/pixelInspector.jsx +30 -9
  32. package/kits/physics-2d/editors/pxArtTimeline.jsx +147 -18
  33. package/kits/physics-2d/engine/ScenePlayer.jsx +9 -3
  34. package/kits/physics-2d/engine/autoInspector.jsx +28 -3
  35. package/kits/physics-2d/engine/physics/PhysicsSystem.js +117 -0
  36. package/kits/physics-2d/engine/physics/controls.js +43 -19
  37. package/kits/physics-2d/engine/propertyRanges.js +27 -0
  38. package/kits/physics-2d/engine/scene.js +86 -4
  39. package/kits/physics-2d/engine/ui.jsx +14 -1
  40. package/kits/physics-2d/engine/ui.module.css +1 -0
  41. package/kits/physics-2d/package-lock.json +1 -1
  42. package/package.json +2 -1
  43. package/dist/shell/assets/index-WtgFx1s8.js +0 -144
  44. package/dist/shell/assets/index-Y6cJRRCX.css +0 -1
@@ -0,0 +1,714 @@
1
+ // GENERATED — do not edit. Vendored from castle-experimental-web/sdk/dist/
2
+ // Re-run `npm run copy-host` in castle-experimental-web after an SDK change.
3
+
4
+ // The default Castle leaderboard panel — host UI, never deck UI. One
5
+ // implementation, consumed two ways: mounted straight into a host page's DOM
6
+ // (web player, dev server shell) and served as a standalone document to the
7
+ // mobile app's overlay WebView (castleLeaderboardPanelPageBootstrap is that
8
+ // document's entry point).
9
+ //
10
+ // Geometry mirrors mobile/js/coreviews/LeaderboardCoreViews.tsx: an 800x1120
11
+ // design space whose unit is `--castle-lb-u`, derived from the mounted root's
12
+ // width. Its `fontSize` values convert through fontSize() below.
13
+ //
14
+ // IMPORTANT: this file must compile to zero runtime imports (keep every import
15
+ // type-only), and no string or comment in it may spell out a closing script
16
+ // tag: the build inlines the output into the mobile page's inline script, and
17
+ // the copy script rejects a source that would terminate it early.
18
+ export const CASTLE_LEADERBOARD_PAYLOAD_VERSION = 1;
19
+ const DEFAULT_AVATAR_URL = "https://image.castle.xyz/36a7bdff06fefd3da13194fdff873bc5?w=128&h=128";
20
+ const ROW_COUNT = 10;
21
+ const PARTY_COUNT = 3;
22
+ const COLOR_TEXT = "#E3E6FD";
23
+ const COLOR_MUTED = "#666666";
24
+ const COLOR_UNSIGNED = "#FFFC40";
25
+ const STYLE_ELEMENT_ID = "castle-leaderboard-panel-style";
26
+ // "Castle Overlay" is the embedded DM Sans Medium at the bottom of this file —
27
+ // the same face the engine registers as "Overlay"
28
+ // (core/src/behaviors/text_fonts.cpp). The rest of the stack only covers glyphs
29
+ // DM Sans doesn't have.
30
+ const FONT_STACK = "'Castle Overlay', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif";
31
+ // DM Sans' natural line height: (hhea ascender 992 + descender 310 + zero line
32
+ // gap) / 1000 upem. Used as `line-height` so a CSS line box is exactly the
33
+ // engine's, which also lands the baseline where the engine puts it (love draws
34
+ // a line's baseline one ascent below its top, and a zero line gap means CSS
35
+ // adds no half-leading to shift it).
36
+ const LINE_HEIGHT = 1.302;
37
+ // A coreview `fontSize: F` is NOT F% of the card width. The engine sizes text
38
+ // by line box: core_views.cpp takes worldFontSize = F/10 and scales the face by
39
+ // 100*worldFontSize/fontHeight, so the rendered line box is 10*F design units
40
+ // and the em is that divided by the face's line height. Off-by-4% otherwise.
41
+ function fontSize(coreViewFontSize) {
42
+ const em = (10 * coreViewFontSize) / LINE_HEIGHT;
43
+ return `calc(${em.toFixed(2)} * var(--castle-lb-u))`;
44
+ }
45
+ const CASTLE_LEADERBOARD_PANEL_CSS = `
46
+ .castle-lb-root {
47
+ position: absolute;
48
+ inset: 0;
49
+ overflow: hidden;
50
+ font-family: ${FONT_STACK};
51
+ font-weight: 500;
52
+ line-height: ${LINE_HEIGHT};
53
+ -webkit-text-size-adjust: 100%;
54
+ -webkit-user-select: none;
55
+ user-select: none;
56
+ -webkit-touch-callout: none;
57
+ -webkit-tap-highlight-color: transparent;
58
+ touch-action: manipulation;
59
+ }
60
+ .castle-lb-root * { box-sizing: border-box; }
61
+ .castle-lb-hidden { display: none !important; }
62
+ .castle-lb-panel {
63
+ position: absolute;
64
+ left: 10%;
65
+ top: 3%;
66
+ width: 80%;
67
+ height: 94%;
68
+ display: flex;
69
+ flex-direction: column;
70
+ background: #000;
71
+ border-radius: calc(24 * var(--castle-lb-u));
72
+ overflow: hidden;
73
+ }
74
+ .castle-lb-tabs {
75
+ position: relative;
76
+ flex: 0 0 auto;
77
+ width: 100%;
78
+ height: calc(50 * var(--castle-lb-u));
79
+ margin-top: calc(18 * var(--castle-lb-u));
80
+ }
81
+ .castle-lb-tab {
82
+ position: absolute;
83
+ top: 0;
84
+ height: 100%;
85
+ width: calc(120 * var(--castle-lb-u));
86
+ text-align: center;
87
+ font-size: ${fontSize(3.4)};
88
+ color: ${COLOR_MUTED};
89
+ cursor: pointer;
90
+ }
91
+ .castle-lb-tab-active { color: ${COLOR_TEXT}; }
92
+ .castle-lb-at-foryou { left: calc(30 * var(--castle-lb-u)); }
93
+ .castle-lb-at-global { left: calc(180 * var(--castle-lb-u)); }
94
+ .castle-lb-rule {
95
+ position: absolute;
96
+ bottom: 0;
97
+ left: 0;
98
+ width: 100%;
99
+ height: calc(3 * var(--castle-lb-u));
100
+ background: #555;
101
+ }
102
+ .castle-lb-indicator {
103
+ position: absolute;
104
+ bottom: 0;
105
+ width: calc(120 * var(--castle-lb-u));
106
+ height: calc(5 * var(--castle-lb-u));
107
+ background: ${COLOR_TEXT};
108
+ }
109
+ .castle-lb-close {
110
+ position: absolute;
111
+ right: 5%;
112
+ top: calc(4 * var(--castle-lb-u));
113
+ width: calc(30 * var(--castle-lb-u));
114
+ height: calc(30 * var(--castle-lb-u));
115
+ cursor: pointer;
116
+ }
117
+ .castle-lb-close svg { width: 100%; height: 100%; display: block; }
118
+ .castle-lb-header {
119
+ position: relative;
120
+ flex: 0 0 auto;
121
+ margin: calc(8 * var(--castle-lb-u)) 0 0 6%;
122
+ width: 88%;
123
+ height: calc(60 * var(--castle-lb-u));
124
+ color: ${COLOR_MUTED};
125
+ font-size: ${fontSize(3.4)};
126
+ }
127
+ .castle-lb-header-name {
128
+ position: absolute;
129
+ left: 0;
130
+ top: calc(10 * var(--castle-lb-u));
131
+ width: calc(300 * var(--castle-lb-u));
132
+ }
133
+ .castle-lb-header-label {
134
+ position: absolute;
135
+ right: 0;
136
+ top: calc(10 * var(--castle-lb-u));
137
+ width: calc(300 * var(--castle-lb-u));
138
+ text-align: right;
139
+ }
140
+ .castle-lb-rows {
141
+ flex: 0 0 auto;
142
+ width: 100%;
143
+ height: 90%;
144
+ overflow: hidden;
145
+ display: flex;
146
+ flex-direction: column;
147
+ }
148
+ .castle-lb-row {
149
+ position: relative;
150
+ flex: 0 0 auto;
151
+ display: flex;
152
+ flex-direction: row;
153
+ align-items: flex-start;
154
+ margin-left: 6%;
155
+ width: 88%;
156
+ height: calc(80 * var(--castle-lb-u));
157
+ }
158
+ .castle-lb-place {
159
+ flex: 0 0 auto;
160
+ width: calc(70 * var(--castle-lb-u));
161
+ margin-top: calc(15 * var(--castle-lb-u));
162
+ color: ${COLOR_TEXT};
163
+ font-size: ${fontSize(3.6)};
164
+ }
165
+ .castle-lb-avatar-box {
166
+ position: relative;
167
+ flex: 0 0 auto;
168
+ width: calc(56 * var(--castle-lb-u));
169
+ height: calc(56 * var(--castle-lb-u));
170
+ margin-top: calc(6 * var(--castle-lb-u));
171
+ cursor: pointer;
172
+ }
173
+ .castle-lb-avatar {
174
+ width: 100%;
175
+ height: 100%;
176
+ border-radius: 50%;
177
+ object-fit: contain;
178
+ background: #222;
179
+ }
180
+ .castle-lb-avatar-frame {
181
+ position: absolute;
182
+ left: calc(-14 * var(--castle-lb-u));
183
+ top: calc(-14 * var(--castle-lb-u));
184
+ width: calc(84 * var(--castle-lb-u));
185
+ height: calc(84 * var(--castle-lb-u));
186
+ object-fit: contain;
187
+ pointer-events: none;
188
+ }
189
+ .castle-lb-name-box {
190
+ position: relative;
191
+ flex: 0 1 auto;
192
+ min-width: 0;
193
+ margin-left: calc(20 * var(--castle-lb-u));
194
+ width: calc(320 * var(--castle-lb-u));
195
+ height: 100%;
196
+ }
197
+ .castle-lb-tappable { cursor: pointer; }
198
+ .castle-lb-name-row {
199
+ position: absolute;
200
+ left: 0;
201
+ top: calc(14 * var(--castle-lb-u));
202
+ display: flex;
203
+ flex-direction: row;
204
+ align-items: flex-start;
205
+ width: 100%;
206
+ }
207
+ .castle-lb-annotated .castle-lb-name-row { top: 0; }
208
+ .castle-lb-username {
209
+ flex: 0 1 auto;
210
+ min-width: 0;
211
+ color: ${COLOR_TEXT};
212
+ font-size: ${fontSize(3.4)};
213
+ white-space: nowrap;
214
+ overflow: hidden;
215
+ text-overflow: ellipsis;
216
+ }
217
+ .castle-lb-badge {
218
+ flex: 0 0 auto;
219
+ margin-left: calc(10 * var(--castle-lb-u));
220
+ width: calc(32 * var(--castle-lb-u));
221
+ height: calc(32 * var(--castle-lb-u));
222
+ object-fit: contain;
223
+ }
224
+ .castle-lb-annotation {
225
+ position: absolute;
226
+ left: 0;
227
+ top: calc(30 * var(--castle-lb-u));
228
+ width: 100%;
229
+ color: ${COLOR_MUTED};
230
+ font-size: ${fontSize(3.6)};
231
+ white-space: nowrap;
232
+ overflow: hidden;
233
+ }
234
+ .castle-lb-score {
235
+ position: absolute;
236
+ right: 0;
237
+ top: calc(14 * var(--castle-lb-u));
238
+ width: calc(150 * var(--castle-lb-u));
239
+ color: ${COLOR_TEXT};
240
+ font-size: ${fontSize(3.6)};
241
+ text-align: right;
242
+ }
243
+ .castle-lb-parties-header {
244
+ padding-top: calc(37 * var(--castle-lb-u));
245
+ color: ${COLOR_MUTED};
246
+ font-size: ${fontSize(3.4)};
247
+ }
248
+ .castle-lb-party-single {
249
+ flex: 0 0 auto;
250
+ width: calc(56 * var(--castle-lb-u));
251
+ height: calc(56 * var(--castle-lb-u));
252
+ margin-top: calc(6 * var(--castle-lb-u));
253
+ border-radius: 50%;
254
+ object-fit: contain;
255
+ }
256
+ .castle-lb-party-multi {
257
+ position: relative;
258
+ flex: 0 0 auto;
259
+ width: calc(56 * var(--castle-lb-u));
260
+ height: calc(56 * var(--castle-lb-u));
261
+ margin-top: calc(6 * var(--castle-lb-u));
262
+ }
263
+ .castle-lb-party-multi-slot {
264
+ position: absolute;
265
+ width: calc(40 * var(--castle-lb-u));
266
+ height: calc(40 * var(--castle-lb-u));
267
+ border-radius: 50%;
268
+ background: #000;
269
+ }
270
+ .castle-lb-party-multi-slot-a { left: 0; top: 0; }
271
+ .castle-lb-party-multi-slot-b { right: 0; bottom: 0; }
272
+ .castle-lb-party-multi img {
273
+ position: absolute;
274
+ width: calc(34 * var(--castle-lb-u));
275
+ height: calc(34 * var(--castle-lb-u));
276
+ border-radius: 50%;
277
+ object-fit: cover;
278
+ }
279
+ .castle-lb-party-multi-a { left: calc(3 * var(--castle-lb-u)); top: calc(3 * var(--castle-lb-u)); }
280
+ .castle-lb-party-multi-b { right: calc(3 * var(--castle-lb-u)); bottom: calc(3 * var(--castle-lb-u)); }
281
+ .castle-lb-party-name {
282
+ position: absolute;
283
+ left: 0;
284
+ top: calc(14 * var(--castle-lb-u));
285
+ width: 100%;
286
+ color: ${COLOR_TEXT};
287
+ font-size: ${fontSize(3.4)};
288
+ white-space: nowrap;
289
+ overflow: hidden;
290
+ text-overflow: ellipsis;
291
+ }
292
+ .castle-lb-party-time {
293
+ position: absolute;
294
+ right: 0;
295
+ top: calc(12 * var(--castle-lb-u));
296
+ height: calc(46 * var(--castle-lb-u));
297
+ padding: calc(6 * var(--castle-lb-u)) calc(15 * var(--castle-lb-u)) 0;
298
+ border-radius: calc(23 * var(--castle-lb-u));
299
+ background: #DCFEED;
300
+ color: #03AD33;
301
+ font-size: ${fontSize(3.2)};
302
+ display: flex;
303
+ justify-content: center;
304
+ }
305
+ .castle-lb-share {
306
+ position: absolute;
307
+ bottom: 5%;
308
+ left: 30%;
309
+ width: 40%;
310
+ height: 5.5%;
311
+ border-radius: calc(14 * var(--castle-lb-u));
312
+ background: #e3e6fd;
313
+ color: #242234;
314
+ font-size: ${fontSize(4)};
315
+ display: flex;
316
+ align-items: center;
317
+ justify-content: center;
318
+ cursor: pointer;
319
+ }
320
+ .castle-lb-share-narrow { left: 36%; width: 27%; }
321
+ .castle-lb-spinner {
322
+ position: absolute;
323
+ top: calc(300 * var(--castle-lb-u));
324
+ left: 50%;
325
+ width: calc(100 * var(--castle-lb-u));
326
+ height: calc(100 * var(--castle-lb-u));
327
+ margin-left: calc(-50 * var(--castle-lb-u));
328
+ border-radius: 50%;
329
+ background: conic-gradient(rgba(170, 170, 170, 0), rgba(170, 170, 170, 1));
330
+ -webkit-mask: radial-gradient(closest-side, transparent 79%, #000 80%);
331
+ mask: radial-gradient(closest-side, transparent 79%, #000 80%);
332
+ animation: castle-lb-spin 1.25s linear infinite;
333
+ }
334
+ @keyframes castle-lb-spin { to { transform: rotate(360deg); } }
335
+ `;
336
+ const CLOSE_ICON_SVG = '<svg viewBox="0 0 24 24" fill="none" stroke="#E3E6FD" stroke-width="2.5" ' +
337
+ 'stroke-linecap="round"><path d="M4 4 L20 20 M20 4 L4 20"/></svg>';
338
+ function el(doc, tag, className) {
339
+ const node = doc.createElement(tag);
340
+ node.className = className;
341
+ return node;
342
+ }
343
+ function setHidden(node, hidden) {
344
+ node.classList.toggle("castle-lb-hidden", hidden);
345
+ }
346
+ function setImage(node, url) {
347
+ setHidden(node, !url);
348
+ node.src = url ?? "";
349
+ }
350
+ function buildRow(doc) {
351
+ const root = el(doc, "div", "castle-lb-row");
352
+ const place = el(doc, "div", "castle-lb-place");
353
+ const avatarBox = el(doc, "div", "castle-lb-avatar-box castle-lb-tappable");
354
+ const avatar = el(doc, "img", "castle-lb-avatar");
355
+ const frame = el(doc, "img", "castle-lb-avatar-frame");
356
+ const nameBox = el(doc, "div", "castle-lb-name-box castle-lb-tappable");
357
+ const nameRow = el(doc, "div", "castle-lb-name-row");
358
+ const username = el(doc, "div", "castle-lb-username");
359
+ const badge = el(doc, "img", "castle-lb-badge");
360
+ const annotation = el(doc, "div", "castle-lb-annotation");
361
+ const score = el(doc, "div", "castle-lb-score");
362
+ avatarBox.append(avatar, frame);
363
+ nameRow.append(username, badge);
364
+ nameBox.append(nameRow, annotation);
365
+ root.append(place, avatarBox, nameBox, score);
366
+ return { root, place, avatarBox, avatar, frame, nameBox, username, badge, annotation, score };
367
+ }
368
+ function buildParty(doc) {
369
+ const root = el(doc, "div", "castle-lb-row");
370
+ const single = el(doc, "img", "castle-lb-party-single");
371
+ const multi = el(doc, "div", "castle-lb-party-multi");
372
+ const multiA = el(doc, "img", "castle-lb-party-multi-a");
373
+ const multiB = el(doc, "img", "castle-lb-party-multi-b");
374
+ const nameBox = el(doc, "div", "castle-lb-name-box");
375
+ const name = el(doc, "div", "castle-lb-party-name");
376
+ const time = el(doc, "div", "castle-lb-party-time");
377
+ multi.append(el(doc, "div", "castle-lb-party-multi-slot castle-lb-party-multi-slot-a"), multiA, el(doc, "div", "castle-lb-party-multi-slot castle-lb-party-multi-slot-b"), multiB);
378
+ nameBox.append(name);
379
+ root.append(single, multi, nameBox, time);
380
+ return { root, single, multi, multiA, multiB, name, time };
381
+ }
382
+ function buildTabs(doc) {
383
+ const root = el(doc, "div", "castle-lb-tabs");
384
+ const forYou = el(doc, "div", "castle-lb-tab castle-lb-at-foryou");
385
+ forYou.textContent = "FOR YOU";
386
+ const global = el(doc, "div", "castle-lb-tab castle-lb-at-global");
387
+ global.textContent = "GLOBAL";
388
+ const forYouIndicator = el(doc, "div", "castle-lb-indicator castle-lb-at-foryou");
389
+ const globalIndicator = el(doc, "div", "castle-lb-indicator castle-lb-at-global");
390
+ const close = el(doc, "div", "castle-lb-close");
391
+ close.innerHTML = CLOSE_ICON_SVG;
392
+ root.append(forYou, global, el(doc, "div", "castle-lb-rule"), forYouIndicator, globalIndicator, close);
393
+ return { root, forYou, global, forYouIndicator, globalIndicator, close };
394
+ }
395
+ function buildPanel(doc) {
396
+ const root = el(doc, "div", "castle-lb-root");
397
+ const panel = el(doc, "div", "castle-lb-panel");
398
+ const tabs = buildTabs(doc);
399
+ const header = el(doc, "div", "castle-lb-header");
400
+ const nameHeader = el(doc, "div", "castle-lb-header-name");
401
+ const labelHeader = el(doc, "div", "castle-lb-header-label");
402
+ header.append(nameHeader, labelHeader);
403
+ const rowsBox = el(doc, "div", "castle-lb-rows");
404
+ const rows = [];
405
+ for (let i = 0; i < ROW_COUNT; i += 1) {
406
+ const row = buildRow(doc);
407
+ rows.push(row);
408
+ rowsBox.append(row.root);
409
+ }
410
+ const partiesHeader = el(doc, "div", "castle-lb-row castle-lb-parties-header");
411
+ partiesHeader.textContent = "PARTIES TO PLAY WITH";
412
+ rowsBox.append(partiesHeader);
413
+ const parties = [];
414
+ for (let i = 0; i < PARTY_COUNT; i += 1) {
415
+ const party = buildParty(doc);
416
+ parties.push(party);
417
+ rowsBox.append(party.root);
418
+ }
419
+ const spinner = el(doc, "div", "castle-lb-spinner");
420
+ const share = el(doc, "div", "castle-lb-share");
421
+ panel.append(tabs.root, header, rowsBox, spinner);
422
+ root.append(panel, share);
423
+ return {
424
+ root,
425
+ panel,
426
+ tabs,
427
+ nameHeader,
428
+ labelHeader,
429
+ rows,
430
+ partiesHeader,
431
+ parties,
432
+ spinner,
433
+ share,
434
+ };
435
+ }
436
+ const MINUTE = 60;
437
+ const HOUR = MINUTE * 60;
438
+ const DAY = HOUR * 24;
439
+ const WEEK = DAY * 7;
440
+ const MONTH = (DAY * 365) / 12;
441
+ const YEAR = DAY * 365;
442
+ function formatTimeInterval(seconds) {
443
+ if (seconds === 0)
444
+ return "0";
445
+ const s = seconds > 0 ? seconds : 1;
446
+ const [value, unit] = s < MINUTE
447
+ ? [Math.round(s), "s"]
448
+ : s < HOUR
449
+ ? [Math.round(s / MINUTE), "m"]
450
+ : s < DAY
451
+ ? [Math.round(s / HOUR), "h"]
452
+ : s < WEEK
453
+ ? [Math.round(s / DAY), "d"]
454
+ : s < MONTH
455
+ ? [Math.round(s / WEEK), "w"]
456
+ : s < YEAR
457
+ ? [Math.round(s / MONTH), "mo"]
458
+ : [Math.round(s / YEAR), "yr"];
459
+ const plural = unit.length > 1 && value !== 1 ? `${unit}s` : unit;
460
+ return `${value}${plural}`;
461
+ }
462
+ function toRecentDate(time) {
463
+ const parsed = new Date(time).getTime();
464
+ if (!Number.isFinite(parsed))
465
+ return null;
466
+ return formatTimeInterval((Date.now() - parsed) / 1000);
467
+ }
468
+ // Mirrors loadLeaderboard in LeaderboardCoreViews: parties eat row slots, and
469
+ // the rows dropped to make room come off the bottom, skipping the entries the
470
+ // server marked required (the player's own row and its neighbours).
471
+ function visibleRows(rows, partyCount) {
472
+ const budget = partyCount > 0 ? ROW_COUNT - 1 - partyCount : ROW_COUNT;
473
+ if (rows.length <= budget)
474
+ return rows;
475
+ const trimmed = rows.slice();
476
+ while (trimmed.length > budget) {
477
+ let index = -1;
478
+ for (let i = trimmed.length - 1; i >= 0; i -= 1) {
479
+ if (!trimmed[i]?.isRequiredUser) {
480
+ index = i;
481
+ break;
482
+ }
483
+ }
484
+ if (index === -1)
485
+ break;
486
+ trimmed.splice(index, 1);
487
+ }
488
+ return trimmed.slice(0, budget);
489
+ }
490
+ function rowAnnotation(row) {
491
+ if (row.isDeckCreator)
492
+ return "Creator";
493
+ if (row.isLinkSharer)
494
+ return "Challenger";
495
+ if (row.user.isAnonymous)
496
+ return "Tap to save your score";
497
+ if (row.isRequiredUser)
498
+ return "You";
499
+ return null;
500
+ }
501
+ function fillRow(els, row, showPlace) {
502
+ setHidden(els.root, false);
503
+ setHidden(els.place, !showPlace);
504
+ els.place.textContent = row.place === null ? "" : `#${row.place}`;
505
+ els.score.textContent = row.score;
506
+ els.username.textContent = row.user.isAnonymous
507
+ ? "You are not signed in"
508
+ : (row.user.username ?? "");
509
+ els.username.style.color = row.user.isAnonymous
510
+ ? COLOR_UNSIGNED
511
+ : (row.user.color ?? (row.isRequiredUser ? "#FFFFFF" : COLOR_TEXT));
512
+ els.avatar.src = row.user.avatarUrl ?? DEFAULT_AVATAR_URL;
513
+ setImage(els.badge, row.user.badgeUrl);
514
+ setImage(els.frame, row.user.frameUrl);
515
+ const annotation = rowAnnotation(row);
516
+ els.annotation.textContent = annotation ?? "";
517
+ setHidden(els.annotation, !annotation);
518
+ els.nameBox.classList.toggle("castle-lb-annotated", Boolean(annotation));
519
+ }
520
+ function fillParty(els, party) {
521
+ setHidden(els.root, false);
522
+ els.name.textContent = party.name;
523
+ const first = party.avatarUrls[0] ?? null;
524
+ const second = party.avatarUrls[1] ?? null;
525
+ const isMulti = Boolean(first && second);
526
+ setImage(els.single, isMulti ? null : first);
527
+ setHidden(els.multi, !isMulti);
528
+ els.multiA.src = first ?? "";
529
+ els.multiB.src = second ?? "";
530
+ const recent = party.lastMessageTime ? toRecentDate(party.lastMessageTime) : null;
531
+ els.time.textContent = recent ?? "";
532
+ setHidden(els.time, !recent);
533
+ // Sized off the character count exactly as loadLeaderboard does, so the pill
534
+ // is the same width as the engine's rather than hugging the text.
535
+ els.time.style.width = recent
536
+ ? `calc(${30 + recent.length * 20} * var(--castle-lb-u))`
537
+ : "";
538
+ }
539
+ function clearPanel(els) {
540
+ setHidden(els.panel, true);
541
+ setHidden(els.share, true);
542
+ setHidden(els.spinner, true);
543
+ setHidden(els.partiesHeader, true);
544
+ els.nameHeader.textContent = "";
545
+ els.labelHeader.textContent = "";
546
+ els.rows.forEach((row) => setHidden(row.root, true));
547
+ els.parties.forEach((party) => setHidden(party.root, true));
548
+ }
549
+ // Re-bound on every paint because which row a slot shows changes with the tab;
550
+ // a handler kept from the previous paint would open the wrong profile.
551
+ function bindRowTaps(els, row, emit) {
552
+ const open = () => {
553
+ emit(row.user.isAnonymous
554
+ ? { type: "savePrompt", userId: row.user.userId }
555
+ : { type: "openProfile", userId: row.user.userId, username: row.user.username });
556
+ };
557
+ els.avatarBox.onclick = open;
558
+ els.nameBox.onclick = open;
559
+ }
560
+ function paintPanel(els, payload, tab, emit) {
561
+ const isForYou = tab === "forYou";
562
+ const loading = payload.loading === true;
563
+ setHidden(els.panel, false);
564
+ els.tabs.forYou.classList.toggle("castle-lb-tab-active", isForYou);
565
+ els.tabs.global.classList.toggle("castle-lb-tab-active", !isForYou);
566
+ setHidden(els.tabs.forYouIndicator, !isForYou);
567
+ setHidden(els.tabs.globalIndicator, isForYou);
568
+ els.nameHeader.textContent = isForYou ? "RELEVANT PLAYERS" : "NAME";
569
+ els.labelHeader.textContent = payload.label.toUpperCase();
570
+ // Column headers title a list, so they wait for one — same as the engine's
571
+ // loading branch (LeaderboardCoreViews onLoad).
572
+ setHidden(els.nameHeader, loading);
573
+ setHidden(els.labelHeader, loading);
574
+ setHidden(els.spinner, !loading);
575
+ setHidden(els.share, false);
576
+ els.share.textContent = payload.isAnonymous ? "Share Deck" : "Share Leaderboard";
577
+ els.share.classList.toggle("castle-lb-share-narrow", payload.isAnonymous);
578
+ const parties = isForYou && payload.showParties && !loading
579
+ ? payload.parties.slice(0, PARTY_COUNT)
580
+ : [];
581
+ const rows = loading
582
+ ? []
583
+ : visibleRows(isForYou ? payload.followList : payload.list, parties.length);
584
+ els.rows.forEach((rowEls, i) => {
585
+ const row = rows[i];
586
+ if (!row) {
587
+ setHidden(rowEls.root, true);
588
+ return;
589
+ }
590
+ fillRow(rowEls, row, !isForYou);
591
+ bindRowTaps(rowEls, row, emit);
592
+ });
593
+ setHidden(els.partiesHeader, parties.length === 0);
594
+ els.parties.forEach((partyEls, i) => {
595
+ const party = parties[i];
596
+ if (party)
597
+ fillParty(partyEls, party);
598
+ else
599
+ setHidden(partyEls.root, true);
600
+ });
601
+ }
602
+ function ensureStyle(doc) {
603
+ if (doc.getElementById(STYLE_ELEMENT_ID))
604
+ return;
605
+ const style = doc.createElement("style");
606
+ style.id = STYLE_ELEMENT_ID;
607
+ style.textContent = embeddedFontCss() + CASTLE_LEADERBOARD_PANEL_CSS;
608
+ (doc.head ?? doc.documentElement).append(style);
609
+ }
610
+ // The font travels with the panel rather than being fetched or read from the
611
+ // app bundle. A mobile WebView can reach neither: on iOS the face is registered
612
+ // with the app process (UIAppFonts), not the WKWebView content process, so
613
+ // local() cannot see it; on Android the page has an https origin and fonts are
614
+ // CORS-restricted, so file:///android_asset is unreachable. Embedding is also
615
+ // what makes the panel render identically offline and on first paint.
616
+ function embeddedFontCss() {
617
+ return ("@font-face{font-family:'Castle Overlay';font-weight:500;font-display:block;" +
618
+ `src:url(data:font/woff2;base64,${DM_SANS_MEDIUM_WOFF2_BASE64}) format('woff2')}`);
619
+ }
620
+ // `root` must be sized to the card rect — every fraction in the panel is
621
+ // relative to it. It also has to establish a containing block, so a statically
622
+ // positioned root is promoted to relative.
623
+ export function mountCastleLeaderboardPanel(root, onEvent) {
624
+ const doc = root.ownerDocument;
625
+ ensureStyle(doc);
626
+ if (doc.defaultView?.getComputedStyle(root).position === "static") {
627
+ root.style.position = "relative";
628
+ }
629
+ const els = buildPanel(doc);
630
+ root.append(els.root);
631
+ let payload = null;
632
+ let tab = "forYou";
633
+ const emit = (event) => {
634
+ try {
635
+ onEvent(event);
636
+ }
637
+ catch {
638
+ /* a host handler's failure must not wedge the panel */
639
+ }
640
+ };
641
+ const paint = () => {
642
+ if (payload)
643
+ paintPanel(els, payload, tab, emit);
644
+ };
645
+ const setTab = (next) => {
646
+ // A tab tap before the data lands would switch to a list that isn't there
647
+ // yet and never repaint; the engine ignores it too.
648
+ if (!payload || payload.loading || tab === next)
649
+ return;
650
+ tab = next;
651
+ emit({ type: "switchTab", tab: next });
652
+ paint();
653
+ };
654
+ const resize = () => {
655
+ const width = root.clientWidth;
656
+ if (width > 0)
657
+ els.root.style.setProperty("--castle-lb-u", `${width / 800}px`);
658
+ };
659
+ els.root.addEventListener("click", (event) => {
660
+ if (event.target === els.root)
661
+ emit({ type: "close" });
662
+ });
663
+ els.tabs.close.addEventListener("click", () => emit({ type: "close" }));
664
+ els.tabs.forYou.addEventListener("click", () => setTab("forYou"));
665
+ els.tabs.global.addEventListener("click", () => setTab("global"));
666
+ els.share.addEventListener("click", () => emit({ type: "share" }));
667
+ resize();
668
+ const observer = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(resize);
669
+ observer?.observe(root);
670
+ const clear = () => {
671
+ payload = null;
672
+ tab = "forYou";
673
+ clearPanel(els);
674
+ };
675
+ clear();
676
+ return {
677
+ render(next) {
678
+ payload = next;
679
+ tab = "forYou";
680
+ resize();
681
+ paint();
682
+ },
683
+ clear,
684
+ destroy() {
685
+ observer?.disconnect();
686
+ els.root.remove();
687
+ },
688
+ };
689
+ }
690
+ const PAGE_RESET_CSS = "html,body{margin:0;padding:0;width:100%;height:100%;position:relative;" +
691
+ "overflow:hidden;background:transparent;-webkit-user-select:none;user-select:none;" +
692
+ "touch-action:manipulation;overscroll-behavior:none}";
693
+ // Entry point of the standalone document served to the mobile overlay WebView.
694
+ // The host drives the panel through window.__castleLeaderboardPanel and reads
695
+ // its events off the React Native message channel.
696
+ export function castleLeaderboardPanelPageBootstrap() {
697
+ const page = window;
698
+ const post = (body) => {
699
+ page.ReactNativeWebView?.postMessage(JSON.stringify({ castleLeaderboard: CASTLE_LEADERBOARD_PAYLOAD_VERSION, ...body }));
700
+ };
701
+ const reset = document.createElement("style");
702
+ reset.textContent = PAGE_RESET_CSS;
703
+ document.head.append(reset);
704
+ const panel = mountCastleLeaderboardPanel(document.body, (event) => post({ ...event }));
705
+ page.__castleLeaderboardPanel = {
706
+ render: (payload) => panel.render(payload),
707
+ clear: () => panel.clear(),
708
+ };
709
+ post({ type: "ready" });
710
+ }
711
+ // DM Sans Medium (Google Fonts, OFL), the face the engine loads as "Overlay", as woff2.
712
+ // Regenerate from castle-client/mobile/assets/fonts/DMSans-Medium.ttf with fontTools:
713
+ // font = TTFont(src); font.flavor = "woff2"; font.save(out) -> base64 the bytes
714
+ const DM_SANS_MEDIUM_WOFF2_BASE64 = "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";