@songsid/agend 2.3.2-beta.9 → 2.3.3-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/README.zh-TW.md +6 -0
- package/dist/agent-cli-instructions.md +2 -2
- package/dist/agent-cli.js +48 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +6 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-whats-new.d.ts +21 -0
- package/dist/agent-whats-new.js +53 -21
- package/dist/agent-whats-new.js.map +1 -1
- package/dist/auth-api.js +2 -0
- package/dist/auth-api.js.map +1 -1
- package/dist/backend/claude-code.d.ts +13 -1
- package/dist/backend/claude-code.js +43 -2
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +15 -0
- package/dist/backend/codex-session-lookup.js +58 -0
- package/dist/backend/codex-session-lookup.js.map +1 -1
- package/dist/backend/codex.js +15 -4
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/kiro-classic-archive.d.ts +57 -0
- package/dist/backend/kiro-classic-archive.js +622 -0
- package/dist/backend/kiro-classic-archive.js.map +1 -0
- package/dist/backend/kiro-classic-links.d.ts +24 -0
- package/dist/backend/kiro-classic-links.js +135 -0
- package/dist/backend/kiro-classic-links.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +100 -1
- package/dist/backend/kiro-identity.js +262 -31
- package/dist/backend/kiro-identity.js.map +1 -1
- package/dist/backend/kiro-migration-verify.d.ts +10 -0
- package/dist/backend/kiro-migration-verify.js +52 -0
- package/dist/backend/kiro-migration-verify.js.map +1 -0
- package/dist/backend/kiro-reconcile-store.d.ts +27 -0
- package/dist/backend/kiro-reconcile-store.js +351 -0
- package/dist/backend/kiro-reconcile-store.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.js +35 -1
- package/dist/backend/kiro-v2-store-worker.js.map +1 -1
- package/dist/backend/kiro-v2-store.d.ts +31 -1
- package/dist/backend/kiro-v2-store.js +22 -12
- package/dist/backend/kiro-v2-store.js.map +1 -1
- package/dist/backend/kiro.d.ts +124 -6
- package/dist/backend/kiro.js +553 -39
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/types.d.ts +109 -4
- package/dist/backend/types.js +9 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-service.d.ts +13 -1
- package/dist/cache-service.js +45 -2
- package/dist/cache-service.js.map +1 -1
- package/dist/channel/ipc-timeouts.js +3 -0
- package/dist/channel/ipc-timeouts.js.map +1 -1
- package/dist/channel/mcp-tools.js +40 -5
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/channel/tool-router.js +2 -1
- package/dist/channel/tool-router.js.map +1 -1
- package/dist/classic-channel-manager.d.ts +6 -0
- package/dist/classic-channel-manager.js +25 -0
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli.js +52 -6
- package/dist/cli.js.map +1 -1
- package/dist/config-validator.d.ts +7 -1
- package/dist/config-validator.js +20 -9
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +2 -0
- package/dist/config.js.map +1 -1
- package/dist/cross-instance-envelope.d.ts +10 -5
- package/dist/cross-instance-envelope.js +20 -17
- package/dist/cross-instance-envelope.js.map +1 -1
- package/dist/daemon.d.ts +125 -63
- package/dist/daemon.js +694 -330
- package/dist/daemon.js.map +1 -1
- package/dist/dashboard-permissions.d.ts +15 -4
- package/dist/dashboard-permissions.js +49 -23
- package/dist/dashboard-permissions.js.map +1 -1
- package/dist/delivery-outbox.d.ts +27 -22
- package/dist/delivery-outbox.js +109 -161
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +10 -25
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/doctor.js +2 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fleet-control-audit.d.ts +1 -1
- package/dist/fleet-control-audit.js +3 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-manager.d.ts +94 -15
- package/dist/fleet-manager.js +597 -133
- package/dist/fleet-manager.js.map +1 -1
- package/dist/forged-envelope-scan.d.ts +9 -0
- package/dist/forged-envelope-scan.js +30 -5
- package/dist/forged-envelope-scan.js.map +1 -1
- package/dist/general-instance.d.ts +24 -0
- package/dist/general-instance.js +53 -0
- package/dist/general-instance.js.map +1 -1
- package/dist/general-knowledge/skills/delegation-playbook/SKILL.md +1 -1
- package/dist/general-knowledge/skills/docker-install/SKILL.md +25 -0
- package/dist/general-knowledge/skills/fleet-config/SKILL.md +5 -3
- package/dist/general-knowledge/skills/fleet-restart/SKILL.md +1 -1
- package/dist/general-knowledge/skills/kiro-engine-migration/SKILL.md +34 -0
- package/dist/general-knowledge/skills/session-management/SKILL.md +2 -2
- package/dist/general-knowledge/skills/tui-effort/SKILL.md +1 -1
- package/dist/general-knowledge/skills/web-appearance/SKILL.canvas-worker-off.md +32 -0
- package/dist/general-knowledge/skills/web-appearance/SKILL.md +32 -0
- package/dist/general-knowledge/skills/web-dashboard/SKILL.canvas-worker-off.md +57 -17
- package/dist/general-knowledge/skills/web-dashboard/SKILL.md +57 -17
- package/dist/instance-config-impact.js +3 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +4 -0
- package/dist/instance-lifecycle.js +28 -5
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.js +6 -7
- package/dist/instructions.js.map +1 -1
- package/dist/kiro-migrate.d.ts +19 -2
- package/dist/kiro-migrate.js +133 -35
- package/dist/kiro-migrate.js.map +1 -1
- package/dist/kiro-reconcile.d.ts +21 -0
- package/dist/kiro-reconcile.js +88 -0
- package/dist/kiro-reconcile.js.map +1 -0
- package/dist/kiro-session-proof.d.ts +41 -0
- package/dist/kiro-session-proof.js +89 -0
- package/dist/kiro-session-proof.js.map +1 -0
- package/dist/kiro-tui-forensic.d.ts +19 -0
- package/dist/kiro-tui-forensic.js +124 -0
- package/dist/kiro-tui-forensic.js.map +1 -0
- package/dist/locale.js +202 -16
- package/dist/locale.js.map +1 -1
- package/dist/log-service.js +3 -3
- package/dist/log-service.js.map +1 -1
- package/dist/needs-you.d.ts +3 -1
- package/dist/needs-you.js +4 -2
- package/dist/needs-you.js.map +1 -1
- package/dist/office-levels.d.ts +64 -0
- package/dist/office-levels.js +66 -0
- package/dist/office-levels.js.map +1 -0
- package/dist/office-share-page.d.ts +3 -1
- package/dist/office-share-page.js +8 -3
- package/dist/office-share-page.js.map +1 -1
- package/dist/office-share-service.d.ts +6 -3
- package/dist/office-share-service.js +12 -8
- package/dist/office-share-service.js.map +1 -1
- package/dist/office-share.d.ts +45 -8
- package/dist/office-share.js +75 -15
- package/dist/office-share.js.map +1 -1
- package/dist/outbound-handlers.js +21 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +47 -2
- package/dist/outbound-schemas.js +42 -3
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/public-web-gateway.js +1 -1
- package/dist/public-web-gateway.js.map +1 -1
- package/dist/quickstart-api.d.ts +39 -1
- package/dist/quickstart-api.js +115 -17
- package/dist/quickstart-api.js.map +1 -1
- package/dist/remote-card-answer.d.ts +83 -0
- package/dist/remote-card-answer.js +208 -0
- package/dist/remote-card-answer.js.map +1 -0
- package/dist/remote-card-prompt.d.ts +38 -0
- package/dist/remote-card-prompt.js +86 -0
- package/dist/remote-card-prompt.js.map +1 -0
- package/dist/scheduler/task-board.d.ts +44 -17
- package/dist/scheduler/task-board.js +95 -36
- package/dist/scheduler/task-board.js.map +1 -1
- package/dist/sd-notify.d.ts +13 -14
- package/dist/sd-notify.js +62 -28
- package/dist/sd-notify.js.map +1 -1
- package/dist/service-installer.d.ts +13 -0
- package/dist/service-installer.js +15 -0
- package/dist/service-installer.js.map +1 -1
- package/dist/service-owner.d.ts +25 -0
- package/dist/service-owner.js +43 -2
- package/dist/service-owner.js.map +1 -1
- package/dist/settings-api.d.ts +2 -1
- package/dist/settings-api.js +19 -26
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-change.js +10 -5
- package/dist/settings-change.js.map +1 -1
- package/dist/settings-effect.js +7 -6
- package/dist/settings-effect.js.map +1 -1
- package/dist/settings-instance-patch.js +1 -1
- package/dist/settings-instance-patch.js.map +1 -1
- package/dist/setup-form.d.ts +2 -2
- package/dist/setup-form.js +139 -93
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-i18n.d.ts +25 -0
- package/dist/setup-i18n.js +226 -0
- package/dist/setup-i18n.js.map +1 -0
- package/dist/task-board-waker.d.ts +40 -1
- package/dist/task-board-waker.js +115 -9
- package/dist/task-board-waker.js.map +1 -1
- package/dist/tmux-control.d.ts +1 -1
- package/dist/tmux-control.js +3 -2
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.js +18 -16
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +2 -0
- package/dist/tmux-read.js +7 -1
- package/dist/tmux-read.js.map +1 -1
- package/dist/tool-permissions.js +18 -0
- package/dist/tool-permissions.js.map +1 -1
- package/dist/topic-commands.d.ts +2 -0
- package/dist/topic-commands.js +2 -1
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-sources.d.ts +1 -0
- package/dist/transcript-sources.js +20 -3
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +11 -5
- package/dist/ui/backend-signin.js +4 -3
- package/dist/ui/chat-store.js +3 -2
- package/dist/ui/chat-strings.js +2 -2
- package/dist/ui/fleet-office-card.js +114 -0
- package/dist/ui/fleet-office-editor.js +81 -9
- package/dist/ui/fleet-office-layout.js +56 -11
- package/dist/ui/fleet-office-levels.js +105 -0
- package/dist/ui/fleet-office-model.js +9 -1
- package/dist/ui/fleet-office-pack.d.ts +15 -3
- package/dist/ui/fleet-office-pack.js +177 -23
- package/dist/ui/fleet-office-skin.js +39 -3
- package/dist/ui/fleet-office-store.js +74 -3
- package/dist/ui/fleet-office-view.js +8 -0
- package/dist/ui/fleet-office-zones.js +102 -19
- package/dist/ui/fleet-office.js +308 -44
- package/dist/ui/fleet-org.js +2 -0
- package/dist/ui/fleet-task-card.js +2 -2
- package/dist/ui/fleet-task-common.js +30 -7
- package/dist/ui/fleet-task-work.js +2 -2
- package/dist/ui/fleet-tasks.js +10 -11
- package/dist/ui/office-share-dialog.js +31 -7
- package/dist/ui/office-share-page.js +1 -0
- package/dist/ui/panel-chat.js +14 -2
- package/dist/ui/panel-log.js +6 -6
- package/dist/ui/panel-needs.js +1 -1
- package/dist/ui/panel-settings.js +16 -8
- package/dist/ui/settings-appearance.js +3 -35
- package/dist/ui/settings-discord.js +3 -2
- package/dist/ui/settings-guests.js +17 -7
- package/dist/ui/settings-model.js +17 -9
- package/dist/ui/settings-registry.js +1 -1
- package/dist/ui/settings-strings.js +18 -6
- package/dist/ui/settings-token.js +3 -2
- package/dist/ui/settings-wizard.js +25 -9
- package/dist/ui/shared/app-i18n.js +2 -2
- package/dist/ui/shared/app-stream.js +1 -1
- package/dist/ui/shared/app.css +70 -2
- package/dist/ui/shared/setup-host-text.js +107 -0
- package/dist/ui/structured-signin.js +89 -38
- package/dist/update-check.d.ts +13 -4
- package/dist/update-check.js +17 -4
- package/dist/update-check.js.map +1 -1
- package/dist/usage-rollup.d.ts +34 -3
- package/dist/usage-rollup.js +56 -3
- package/dist/usage-rollup.js.map +1 -1
- package/dist/web-api.d.ts +10 -1
- package/dist/web-api.js +207 -17
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.js +1 -1
- package/dist/web-auth.js.map +1 -1
- package/dist/web-experimental.d.ts +6 -2
- package/dist/web-experimental.js +8 -4
- package/dist/web-experimental.js.map +1 -1
- package/dist/web-office-acts.d.ts +5 -2
- package/dist/web-office-acts.js +9 -4
- package/dist/web-office-acts.js.map +1 -1
- package/dist/web-office-pack-read.d.ts +35 -0
- package/dist/web-office-pack-read.js +252 -0
- package/dist/web-office-pack-read.js.map +1 -0
- package/dist/web-office-pack-tools.d.ts +241 -0
- package/dist/web-office-pack-tools.js +785 -0
- package/dist/web-office-pack-tools.js.map +1 -0
- package/dist/web-office-skins.d.ts +68 -4
- package/dist/web-office-skins.js +324 -33
- package/dist/web-office-skins.js.map +1 -1
- package/dist/web-office-store.d.ts +47 -4
- package/dist/web-office-store.js +124 -23
- package/dist/web-office-store.js.map +1 -1
- package/dist/web-settings-patch.d.ts +3 -2
- package/dist/web-settings-patch.js +7 -5
- package/dist/web-settings-patch.js.map +1 -1
- package/dist/workflow-templates/default.md +3 -3
- package/dist/working-recovery.d.ts +0 -2
- package/dist/working-recovery.js +2 -23
- package/dist/working-recovery.js.map +1 -1
- package/package.json +2 -2
- package/templates/windows-shortcuts.ps1 +18 -17
- package/dist/upgrade-notices.d.ts +0 -17
- package/dist/upgrade-notices.js +0 -93
- package/dist/upgrade-notices.js.map +0 -1
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
// seats' figures, #2558), a moon, and a thin line to its day place. One that sleeps in place shows it on its day place
|
|
9
9
|
// (and it follows the item); dragged away, the item has its own night place; its Reset puts back the pack's.
|
|
10
10
|
//
|
|
11
|
+
// #2736: the mail drop — where letters from other offices land — is a handle too (an envelope). On a pack without
|
|
12
|
+
// one it stands, dashed, where letters land today (fleet-office-zones.js dropPoint); dragged, the office has its own.
|
|
13
|
+
//
|
|
14
|
+
// #2691: a selected seat lists the office's members under "Reserved for" (several may be picked) and "Lend when
|
|
15
|
+
// away": whoever it is for takes it first, and nobody else does unless it is lent while they are all elsewhere
|
|
16
|
+
// (fleet-office-zones.js assignSeats). Saved as the overrides' `seatFor` by area and slot; a reserved seat's handle
|
|
17
|
+
// is ringed.
|
|
18
|
+
//
|
|
11
19
|
// Every handle is a button for the keyboard too: Tab to it, the arrow keys move it (Shift: by 10), Delete removes a
|
|
12
20
|
// waypoint; the selected waypoint's corridors are listed with a way to join or unjoin each. Never offered to a guest,
|
|
13
21
|
// the public link or a read-only session (the host refuses their saves too).
|
|
@@ -17,24 +25,27 @@ import { html, useEffect, useLayoutEffect, useMemo, useRef, useState } from "/as
|
|
|
17
25
|
import { t, register } from "/assets/app-i18n.js";
|
|
18
26
|
import { SidePanel } from "/assets/side-panel.js";
|
|
19
27
|
import { LOGICAL, overridesBetween, own } from "./fleet-office-pack.js";
|
|
28
|
+
import { dropPoint } from "./fleet-office-zones.js";
|
|
20
29
|
|
|
21
30
|
register("orgl", {
|
|
22
31
|
en: {
|
|
23
32
|
edit: "Edit layout", title: "Edit layout", coords: "Show coordinates", addWaypoint: "Add waypoint", removeWaypoint: "Remove waypoint",
|
|
24
|
-
joinTo: "Join to", join: "Join", unjoin: "Unjoin {0}", corridors: "Corridors", none: "Nothing selected: pick a seat, an item, the door or a waypoint.",
|
|
33
|
+
joinTo: "Join to", join: "Join", unjoin: "Unjoin {0}", corridors: "Corridors", none: "Nothing selected: pick a seat, an item, the door, the mail drop or a waypoint.",
|
|
25
34
|
reset: "Reset to the pack's layout", save: "Save layout", cancel: "Cancel", saved: "Layout saved.", hint: "Drag, or use the arrow keys (Shift: by 10).",
|
|
26
|
-
seat: "Seat {0} in {1}", furniture: "Item {0}", night: "Item {0} (night)", door: "Door", waypoint: "Waypoint {0}", at: "{0} at {1}, {2}",
|
|
35
|
+
seat: "Seat {0} in {1}", furniture: "Item {0}", night: "Item {0} (night)", door: "Door", mail: "Mail drop", mailAuto: "Mail drop (where letters land now; drag to place it)", waypoint: "Waypoint {0}", at: "{0} at {1}, {2}",
|
|
27
36
|
nightReset: "Back to the pack's night place",
|
|
37
|
+
seatFor: "Seat {0} in {1}, reserved for {2}", reservedFor: "Reserved for", lend: "Lend when away", nobody: "No members to pick.",
|
|
28
38
|
changed: "Someone changed the offices meanwhile. Your layout is kept: Save again puts it on the current list.",
|
|
29
39
|
failed: "The layout was not saved ({0}).", rateLimited: "Too many saves. Try again in a minute.",
|
|
30
40
|
stale: "This office was removed or its style changed meanwhile: this layout can no longer be saved. Cancel closes it.",
|
|
31
41
|
},
|
|
32
42
|
"zh-TW": {
|
|
33
43
|
edit: "編輯配置", title: "編輯配置", coords: "顯示座標", addWaypoint: "新增路徑點", removeWaypoint: "移除路徑點",
|
|
34
|
-
joinTo: "連到", join: "連接", unjoin: "取消連接 {0}", corridors: "走道", none: "
|
|
44
|
+
joinTo: "連到", join: "連接", unjoin: "取消連接 {0}", corridors: "走道", none: "尚未選取:請選座位、家具、門、信件落點或路徑點。",
|
|
35
45
|
reset: "還原成 pack 的配置", save: "儲存配置", cancel: "取消", saved: "配置已儲存。", hint: "拖曳,或用方向鍵移動(Shift:一次 10)。",
|
|
36
|
-
seat: "{1} 的座位 {0}", furniture: "家具 {0}", night: "家具 {0}(夜間)", door: "門", waypoint: "路徑點 {0}", at: "{0},位置 {1}, {2}",
|
|
46
|
+
seat: "{1} 的座位 {0}", furniture: "家具 {0}", night: "家具 {0}(夜間)", door: "門", mail: "信件落點", mailAuto: "信件落點(目前信件落下的位置;拖曳即可指定)", waypoint: "路徑點 {0}", at: "{0},位置 {1}, {2}",
|
|
37
47
|
nightReset: "回到 pack 的夜間位置",
|
|
48
|
+
seatFor: "{1} 的座位 {0},保留給 {2}", reservedFor: "保留給", lend: "不在時借給別人", nobody: "沒有可選的成員。",
|
|
38
49
|
changed: "有人在這期間修改了辦公室。你的配置已保留:再按一次儲存,會套用到目前的清單。",
|
|
39
50
|
failed: "配置沒有儲存({0})。", rateLimited: "儲存太頻繁,請一分鐘後再試。",
|
|
40
51
|
stale: "這個辦公室在這期間被移除,或它的風格已改變:這份配置無法再儲存。按取消關閉。",
|
|
@@ -48,12 +59,15 @@ const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, Math.round(v)));
|
|
|
48
59
|
/** An item's night place (#2665): its own, or (in place) its day place; `own` whether it has one. */
|
|
49
60
|
const nightAt = (f) => (f.night.x !== null && f.night.x !== undefined && f.night.y !== null && f.night.y !== undefined ? { x: f.night.x, y: f.night.y, own: true } : { x: f.x, y: f.y, own: false });
|
|
50
61
|
/**
|
|
51
|
-
* Every handle on a pack: { key, kind, label, x, y } — seats by area
|
|
52
|
-
* item with a `night`; `day` its day place, `inPlace` while it sleeps
|
|
62
|
+
* Every handle on a pack: { key, kind, label, x, y } — seats by area (#2691: `for` and `lend` when reserved),
|
|
63
|
+
* furniture, each item's night place (#2665: an item with a `night`; `day` its day place, `inPlace` while it sleeps
|
|
64
|
+
* there), the door, the mail drop (#2736: `auto` where the pack has none — where letters land now), the waypoints.
|
|
53
65
|
*/
|
|
54
66
|
export function handlesOf(pack) {
|
|
55
67
|
const out = [];
|
|
56
|
-
for (const [name, a] of Object.entries(pack.areas)) a.seats.forEach((s, i) => out.push({ key: `seat:${name}:${i}`, kind: "seat",
|
|
68
|
+
for (const [name, a] of Object.entries(pack.areas)) a.seats.forEach((s, i) => out.push({ key: `seat:${name}:${i}`, kind: "seat",
|
|
69
|
+
label: s.for && s.for.length ? tl("seatFor", i + 1, name, s.for.join(", ")) : tl("seat", i + 1, name), x: s.x, y: s.y,
|
|
70
|
+
...(s.for && s.for.length ? { for: [...s.for], lend: s.lend === true } : {}) }));
|
|
57
71
|
for (const f of pack.furniture) out.push({ key: `furn:${f.id}`, kind: "furniture", label: tl("furniture", f.id), x: f.x, y: f.y });
|
|
58
72
|
for (const f of pack.furniture) {
|
|
59
73
|
if (!f.night) continue;
|
|
@@ -61,6 +75,8 @@ export function handlesOf(pack) {
|
|
|
61
75
|
out.push({ key: `night:${f.id}`, kind: "night", label: tl("night", f.id), x: n.x, y: n.y, day: { x: f.x, y: f.y }, inPlace: !n.own });
|
|
62
76
|
}
|
|
63
77
|
out.push({ key: "door", kind: "door", label: tl("door"), x: pack.door.x, y: pack.door.y });
|
|
78
|
+
const md = pack.mailDrop || dropPoint({ areas: pack.areas, waypoints: pack.waypoints, width: LOGICAL.w, height: LOGICAL.h });
|
|
79
|
+
if (md) out.push({ key: "mail", kind: "mail", label: tl(pack.mailDrop ? "mail" : "mailAuto"), x: md.x, y: md.y, ...(pack.mailDrop ? {} : { auto: true }) });
|
|
64
80
|
for (const w of pack.waypoints) out.push({ key: `wp:${w.id}`, kind: "waypoint", label: tl("waypoint", w.id), x: w.x, y: w.y });
|
|
65
81
|
return out;
|
|
66
82
|
}
|
|
@@ -72,11 +88,12 @@ export function moveHandle(pack, key, x, y) {
|
|
|
72
88
|
const area = own(pack.areas, a), i = Number(b);
|
|
73
89
|
if (!area || !area.seats[i]) return pack;
|
|
74
90
|
const r = area.rect, p = { x: clamp(x, Math.ceil(r.x), Math.floor(r.x + r.w)), y: clamp(y, Math.ceil(r.y), Math.floor(r.y + r.h)) };
|
|
75
|
-
return { ...pack, areas: { ...pack.areas, [a]: { ...area, seats: area.seats.map((s, j) => (j === i ? p : s)) } } };
|
|
91
|
+
return { ...pack, areas: { ...pack.areas, [a]: { ...area, seats: area.seats.map((s, j) => (j === i ? { ...s, ...p } : s)) } } };
|
|
76
92
|
}
|
|
77
93
|
if (kind === "furn") return { ...pack, furniture: pack.furniture.map((f) => (f.id === a ? { ...f, ...inCanvas() } : f)) };
|
|
78
94
|
if (kind === "night") return { ...pack, furniture: pack.furniture.map((f) => (f.id === a && f.night ? { ...f, night: { ...f.night, ...inCanvas() } } : f)) };
|
|
79
95
|
if (kind === "door") return { ...pack, door: inCanvas() };
|
|
96
|
+
if (kind === "mail") return { ...pack, mailDrop: inCanvas() };
|
|
80
97
|
if (kind === "wp") return { ...pack, waypoints: pack.waypoints.map((w) => (w.id === a ? { ...w, ...inCanvas() } : w)) };
|
|
81
98
|
return pack;
|
|
82
99
|
}
|
|
@@ -104,6 +121,18 @@ export function resetNight(pack, base, id) {
|
|
|
104
121
|
if (!o || !o.night) return pack;
|
|
105
122
|
return { ...pack, furniture: pack.furniture.map((f) => (f.id === id && f.night ? { ...f, night: { ...f.night, x: o.night.x, y: o.night.y } } : f)) };
|
|
106
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* #2691: seat `key` ("seat:<area>:<i>") reserved for `names` (in that order, none twice), lent while they are all
|
|
126
|
+
* elsewhere when `lend`; no names: a plain seat again.
|
|
127
|
+
*/
|
|
128
|
+
export function reserveSeat(pack, key, names, lend = false) {
|
|
129
|
+
const [kind, a, b] = key.split(":");
|
|
130
|
+
const area = kind === "seat" ? own(pack.areas, a) : null, i = Number(b);
|
|
131
|
+
if (!area || !area.seats[i]) return pack;
|
|
132
|
+
const list = [...new Set(names)];
|
|
133
|
+
const seat = (s) => { const { for: _f, lend: _l, ...p } = s; return list.length ? { ...p, for: list, lend: lend === true } : p; };
|
|
134
|
+
return { ...pack, areas: { ...pack.areas, [a]: { ...area, seats: area.seats.map((s, j) => (j === i ? seat(s) : s)) } } };
|
|
135
|
+
}
|
|
107
136
|
/** What Save keeps: the overrides between the pack and the edited layout (null: the pack's own). */
|
|
108
137
|
export const layoutOverrides = (base, edited) => overridesBetween(base, edited);
|
|
109
138
|
|
|
@@ -123,9 +152,10 @@ const KEY_STEP = { ArrowLeft: [-1, 0], ArrowRight: [1, 0], ArrowUp: [0, -1], Arr
|
|
|
123
152
|
* zoomed; the page sets its box through the CSSOM, never a style attribute: #1300) — a pointer is read back through
|
|
124
153
|
* the overlay's own box, so a drag lands on the logical point under it at any zoom; `onChange(edited)` as anything
|
|
125
154
|
* moves (the canvas redraws it); `onSave(overrides | null)` → { ok } or { ok: false, message }; `onClose()`. `stale` (a message): the
|
|
126
|
-
* office or its style changed underneath the session — no handles, nothing to save, only Cancel.
|
|
155
|
+
* office or its style changed underneath the session — no handles, nothing to save, only Cancel. `members` (#2691):
|
|
156
|
+
* the office's instances' names, offered under a selected seat's "Reserved for".
|
|
127
157
|
*/
|
|
128
|
-
export function LayoutEditor({ base, start, place = null, stale = "", dock = true, onChange, onSave, onClose }) {
|
|
158
|
+
export function LayoutEditor({ base, start, place = null, stale = "", dock = true, members = [], onChange, onSave, onClose }) {
|
|
129
159
|
const [edited, setEdited] = useState(start);
|
|
130
160
|
const [sel, setSel] = useState(null);
|
|
131
161
|
const [coords, setCoords] = useState(true);
|
|
@@ -160,6 +190,13 @@ export function LayoutEditor({ base, start, place = null, stale = "", dock = tru
|
|
|
160
190
|
const add = () => { const at = selected ? { x: selected.x + 40, y: selected.y } : { x: LOGICAL.w / 2, y: LOGICAL.h / 2 }; const r = addWaypoint(edited, at.x, at.y); change(r.pack); setSel(`wp:${r.id}`); };
|
|
161
191
|
const wpSel = selected && selected.kind === "waypoint" ? selected.key.slice(3) : null;
|
|
162
192
|
const nightSel = selected && selected.kind === "night" ? selected.key.slice(6) : null;
|
|
193
|
+
const seatSel = selected && selected.kind === "seat" ? selected : null;
|
|
194
|
+
// #2691: the members to pick from, and anyone the seat is already for who is not one now (so they can be unpicked).
|
|
195
|
+
const pickable = seatSel ? [...new Set([...members, ...(seatSel.for || [])])] : [];
|
|
196
|
+
const pickFor = (name) => {
|
|
197
|
+
const now = seatSel.for || [], next = now.includes(name) ? now.filter((n) => n !== name) : [...now, name];
|
|
198
|
+
change(reserveSeat(edited, seatSel.key, next, next.length ? seatSel.lend === true : false));
|
|
199
|
+
};
|
|
163
200
|
const save = async () => {
|
|
164
201
|
if (busy) return;
|
|
165
202
|
setBusy(true); setMsg("");
|
|
@@ -196,6 +233,12 @@ export function LayoutEditor({ base, start, place = null, stale = "", dock = tru
|
|
|
196
233
|
const controls = html`<label class="check"><input type="checkbox" class="ol-coords" checked=${coords} onChange=${() => setCoords((v) => !v)} /><span>${tl("coords")}</span></label>
|
|
197
234
|
<button type="button" class="btn btn-sm ol-add" onClick=${add} disabled=${busy}>${tl("addWaypoint")}</button>
|
|
198
235
|
<span class="muted ol-sel" aria-live="polite">${selected ? tl("at", selected.label, selected.x, selected.y) : tl("none")}</span>
|
|
236
|
+
${seatSel ? html`<fieldset class="ol-for"><legend class="oo-pick-label">${tl("reservedFor")}</legend>
|
|
237
|
+
${pickable.length ? pickable.map((n) => html`<label key=${n} class="check"><input type="checkbox" class="ol-for-pick" value=${n} checked=${(seatSel.for || []).includes(n)}
|
|
238
|
+
disabled=${busy} onChange=${() => pickFor(n)} /><span>${n}</span></label>`) : html`<span class="muted">${tl("nobody")}</span>`}
|
|
239
|
+
</fieldset>
|
|
240
|
+
<label class="check"><input type="checkbox" class="ol-lend" checked=${seatSel.lend === true} disabled=${busy || !(seatSel.for || []).length}
|
|
241
|
+
onChange=${() => change(reserveSeat(edited, seatSel.key, seatSel.for || [], !(seatSel.lend === true)))} /><span>${tl("lend")}</span></label>` : null}
|
|
199
242
|
${nightSel ? html`<button type="button" class="btn btn-sm ol-night-reset" onClick=${() => change(resetNight(edited, base, nightSel))} disabled=${busy}>${tl("nightReset")}</button>` : null}
|
|
200
243
|
${wpSel ? html`<button type="button" class="btn btn-sm btn-danger ol-remove" onClick=${() => { change(removeWaypoint(edited, wpSel)); setSel(null); }} disabled=${busy}>${tl("removeWaypoint")}</button>
|
|
201
244
|
<label class="oo-pick"><span class="oo-pick-label">${tl("joinTo")}</span>
|
|
@@ -219,12 +262,14 @@ export function LayoutEditor({ base, start, place = null, stale = "", dock = tru
|
|
|
219
262
|
${Object.values(edited.areas).map((a) => html`<rect key=${`a:${a.name}`} class="ol-area" x=${a.rect.x} y=${a.rect.y} width=${a.rect.w} height=${a.rect.h} />`)}
|
|
220
263
|
${edited.edges.map((e) => { const p = at.get(e[0]), q = at.get(e[1]); return p && q ? html`<line key=${`e:${edgeKey(e)}`} class="ol-edge" x1=${p.x} y1=${p.y} x2=${q.x} y2=${q.y} />` : null; })}
|
|
221
264
|
${handles.filter((h) => h.kind === "night" && !h.inPlace).map((h) => html`<line key=${`nl:${h.key}`} class="ol-night-line" x1=${h.day.x} y1=${h.day.y} x2=${h.x} y2=${h.y} />`)}
|
|
222
|
-
${[...handles.filter((h) => h.kind === "night"), ...handles.filter((h) => h.kind !== "night")].map((h) => html`<g key=${h.key} class=${`ol-handle ol-${h.kind}${sel === h.key ? " on" : ""}`} data-handle=${h.key} tabindex="0" role="button"
|
|
265
|
+
${[...handles.filter((h) => h.kind === "night"), ...handles.filter((h) => h.kind !== "night")].map((h) => html`<g key=${h.key} class=${`ol-handle ol-${h.kind}${h.for ? " reserved" : ""}${h.auto ? " auto" : ""}${sel === h.key ? " on" : ""}`} data-handle=${h.key} tabindex="0" role="button"
|
|
223
266
|
aria-label=${tl("at", h.label, h.x, h.y)} aria-pressed=${sel === h.key ? "true" : "false"}
|
|
224
267
|
onPointerDown=${down(h.key)} onKeyDown=${keyOn(h)} onFocus=${() => setSel(h.key)}>
|
|
225
268
|
${h.kind === "door" ? html`<rect x=${h.x - 9} y=${h.y - 9} width="18" height="18" transform=${`rotate(45 ${h.x} ${h.y})`} />`
|
|
269
|
+
: h.kind === "mail" ? html`<rect x=${h.x - 10} y=${h.y - 7} width="20" height="14" /><path class="ol-flap" d=${`M${h.x - 10} ${h.y - 7}L${h.x} ${h.y + 1}L${h.x + 10} ${h.y - 7}`} />`
|
|
226
270
|
: h.kind === "furniture" ? html`<rect x=${h.x - 8} y=${h.y - 8} width="16" height="16" />`
|
|
227
271
|
: h.kind === "night" ? html`<circle cx=${h.x} cy=${h.y} r=${h.inPlace ? 15 : 8} /><path class="ol-moon" d=${h.inPlace ? moonPath(h.x + 10, h.y - 10) : moonPath(h.x, h.y)} />`
|
|
272
|
+
: h.kind === "seat" && h.for ? html`<circle class="ol-for-ring" cx=${h.x} cy=${h.y} r="13" /><circle cx=${h.x} cy=${h.y} r="9" />`
|
|
228
273
|
: html`<circle cx=${h.x} cy=${h.y} r=${h.kind === "seat" ? 9 : 7} />`}
|
|
229
274
|
${coords && sel === h.key ? html`<text class="ol-coord" x=${h.x + 12} y=${h.y - 10}>${h.x}, ${h.y}</text>` : null}
|
|
230
275
|
</g>`)}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// #2661: the Office levels on the page — what the host serves (GET /ui/office-levels, src/office-levels.ts: the level from
|
|
2
|
+
// each instance's lifetime work, and where the viewer may see them, the numbers behind it) put into words and colours:
|
|
3
|
+
// the tier a level is in, its title (the page's generic ones, or a skin pack's `levels.titles`), a title a pack pins on
|
|
4
|
+
// someone (`levels.fixed`, which may hide the number), the badge's text and the XP bar. Pure: no DOM, no fetch.
|
|
5
|
+
import { t, register } from "/assets/app-i18n.js";
|
|
6
|
+
|
|
7
|
+
register("olv", {
|
|
8
|
+
en: { t0: "Novice", t1: "Apprentice", t2: "Adept", t3: "Expert", t4: "Master", t5: "Legend" },
|
|
9
|
+
"zh-TW": { t0: "新手", t1: "學徒", t2: "熟手", t3: "專家", t4: "大師", t5: "傳奇" },
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
/** The tiers by the level each starts at: grey, green, blue, the filled blue, gold, red (#2661). */
|
|
13
|
+
export const TIER_FROM = [0, 10, 20, 35, 50, 100];
|
|
14
|
+
/** The tier (0–5) a level is in. */
|
|
15
|
+
export const tierOf = (level) => { let i = 0; while (i + 1 < TIER_FROM.length && level >= TIER_FROM[i + 1]) i++; return i; };
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A tier's badge colours from the dashboard's tokens (no palette of its own: the status tokens and their tints, as the
|
|
19
|
+
* renderer reads them, readPal). { bg, fg, line }.
|
|
20
|
+
*/
|
|
21
|
+
export function tierColours(tier, pal) {
|
|
22
|
+
switch (tier) {
|
|
23
|
+
case 1: return { bg: pal.okBg, fg: pal.ok, line: pal.ok };
|
|
24
|
+
case 2: return { bg: pal.accentDim, fg: pal.accent, line: pal.accent };
|
|
25
|
+
case 3: return { bg: pal.accent, fg: pal.surface, line: pal.accent };
|
|
26
|
+
case 4: return { bg: pal.warnBg, fg: pal.warn, line: pal.warn };
|
|
27
|
+
case 5: return { bg: pal.dangerBg, fg: pal.danger, line: pal.danger };
|
|
28
|
+
default: return { bg: pal.surface2, fg: pal.text2, line: pal.border };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** A level as the badge writes it: up to 999 whole, then 1.1k, 12k (never wider than four characters). */
|
|
33
|
+
export function badgeText(level) {
|
|
34
|
+
if (level < 1000) return String(level);
|
|
35
|
+
const k = level / 1000;
|
|
36
|
+
return k < 10 ? `${Math.floor(k * 10) / 10}k` : `${Math.floor(k)}k`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The title for a level: the pack's table (the last entry it has reached), else the page's tier name. */
|
|
40
|
+
export function titleOf(level, titles) {
|
|
41
|
+
if (Array.isArray(titles) && titles.length) {
|
|
42
|
+
let name = null;
|
|
43
|
+
for (const e of titles) if (level >= e.from) name = e.name;
|
|
44
|
+
if (name) return name;
|
|
45
|
+
}
|
|
46
|
+
return t(`olv.t${tierOf(level)}`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** What a pack pins on `name` (an instance or an NPC's id): { title, hideLevel } or null. */
|
|
50
|
+
export function fixedOf(name, levels) {
|
|
51
|
+
const f = levels && levels.fixed;
|
|
52
|
+
return f && Object.prototype.hasOwnProperty.call(f, name) ? f[name] : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Work tokens to reach a level (the host's curve: level = floor(√(work ÷ unit))). */
|
|
56
|
+
export const workFor = (level, unit) => level * level * unit;
|
|
57
|
+
|
|
58
|
+
/** The XP bar: { next, toNext, pct (0–1) } — the next level, the work it still needs, how far along this level is. */
|
|
59
|
+
export function xpOf(level, work, unit) {
|
|
60
|
+
const from = workFor(level, unit), to = workFor(level + 1, unit);
|
|
61
|
+
return { next: level + 1, toNext: Math.max(0, to - work), pct: to > from ? Math.min(1, Math.max(0, (work - from) / (to - from))) : 0 };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Tokens in short words: 950, 12.3K, 260M, 1.2B. */
|
|
65
|
+
export function tokens(n) {
|
|
66
|
+
const v = Math.max(0, n);
|
|
67
|
+
if (v < 1000) return String(Math.round(v));
|
|
68
|
+
const [d, s] = v >= 1e9 ? [1e9, "B"] : v >= 1e6 ? [1e6, "M"] : [1e3, "K"];
|
|
69
|
+
const x = v / d;
|
|
70
|
+
return `${x < 100 ? Math.floor(x * 10) / 10 : Math.floor(x)}${s}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* What the host answered (GET /ui/office-levels), checked: { enabled, unit, detail, levels: name → entry } with every
|
|
75
|
+
* entry's numbers sane (anything odd: no levels at all).
|
|
76
|
+
*/
|
|
77
|
+
export function levelsOk(v) {
|
|
78
|
+
const none = { enabled: false, unit: 100000, detail: false, levels: new Map() };
|
|
79
|
+
if (!v || typeof v !== "object" || v.enabled !== true || typeof v.levels !== "object" || !v.levels) return none;
|
|
80
|
+
const unit = Number.isFinite(v.unit) && v.unit > 0 ? v.unit : 100000;
|
|
81
|
+
const n = (x) => Number.isFinite(x) && x >= 0;
|
|
82
|
+
const out = new Map();
|
|
83
|
+
for (const [name, e] of Object.entries(v.levels)) {
|
|
84
|
+
if (!e || !Number.isInteger(e.level) || e.level < 0) continue;
|
|
85
|
+
const detail = v.detail === true && n(e.workTokens) && e.today && n(e.today.workTokens) && n(e.today.requests);
|
|
86
|
+
out.set(name, detail
|
|
87
|
+
? { level: e.level, workTokens: e.workTokens, estimated: e.estimated === true, today: { workTokens: e.today.workTokens, requests: e.today.requests },
|
|
88
|
+
firstSeen: typeof e.firstSeen === "string" && /^\d{4}-\d{2}-\d{2}$/.test(e.firstSeen) ? e.firstSeen : null }
|
|
89
|
+
: { level: e.level });
|
|
90
|
+
}
|
|
91
|
+
return { enabled: true, unit, detail: v.detail === true, levels: out };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* The badge a person's name tag carries: { text, tier } — or { mark: true } for a pinned title that hides the level —
|
|
96
|
+
* or null (levels off, or none for them).
|
|
97
|
+
*/
|
|
98
|
+
export function badgeOf(name, lv, levels) {
|
|
99
|
+
if (!lv || !lv.enabled) return null;
|
|
100
|
+
const fx = fixedOf(name, levels);
|
|
101
|
+
if (fx && fx.hideLevel) return { mark: true, tier: 0 };
|
|
102
|
+
const e = lv && lv.levels.get(name);
|
|
103
|
+
if (!e) return null;
|
|
104
|
+
return { text: badgeText(e.level), tier: tierOf(e.level) };
|
|
105
|
+
}
|
|
@@ -74,13 +74,21 @@ export function officeRooms(view, filter) {
|
|
|
74
74
|
return picked.map((r) => ({ ...r, nodes: r.nodes.filter((n) => pinned.has(n.name)) })).filter((r) => r.nodes.length);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* #2752: an office kept for nobody (its style's NPCs only) stores this one member: a team with no name, which no team
|
|
79
|
+
* has, so a version before it finds nobody too. `[]` still means everyone.
|
|
80
|
+
*/
|
|
81
|
+
export const NOBODY = "team:";
|
|
82
|
+
/** Who an office's members pick: "everyone" ([]), "nobody" (only NOBODY), or "picked". */
|
|
83
|
+
export const membersMode = (members) => (!members.length ? "everyone" : members.every((m) => m === NOBODY) ? "nobody" : "picked");
|
|
84
|
+
/** A stored office's members: instance names, or `team:<name>` for a team's; none means everyone, NOBODY nobody. */
|
|
78
85
|
export function membersOf(office, view) {
|
|
79
86
|
const every = [...view.top, ...view.teams.flatMap((tm) => tm.nodes), ...view.rest.nodes];
|
|
80
87
|
const byName = new Map(every.map((n) => [n.name, n]));
|
|
81
88
|
if (!office.members.length) return [...byName.values()];
|
|
82
89
|
const out = new Map();
|
|
83
90
|
for (const m of office.members) {
|
|
91
|
+
if (m === NOBODY) continue;
|
|
84
92
|
const team = m.startsWith("team:") ? view.teams.find((tm) => tm.name === m.slice(5)) : null;
|
|
85
93
|
for (const n of team ? team.nodes : byName.has(m) ? [byName.get(m)] : []) if (!out.has(n.name)) out.set(n.name, n);
|
|
86
94
|
}
|
|
@@ -3,16 +3,23 @@
|
|
|
3
3
|
/** `dw` × `dh`: its displayed size in logical units (w·scale × h·scale unless the manifest says otherwise). */
|
|
4
4
|
export interface PackStrip { src: string; frames: number; w: number; h: number; fps: number; ax: number; ay: number; dw: number; dh: number }
|
|
5
5
|
export interface PackPoint { x: number; y: number }
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export interface
|
|
6
|
+
/** #2691: a seat reserved for `for` (lent while they are all elsewhere when `lend`); a plain seat has neither. */
|
|
7
|
+
export interface PackSeat extends PackPoint { for?: string[]; lend?: boolean }
|
|
8
|
+
export interface PackArea { name: string; rect: { x: number; y: number; w: number; h: number }; seats: PackSeat[] }
|
|
9
|
+
/** `label` (#2574): its name tag, or null. `activeOn`/`hides` (#2698): when it turns active, and whether it hides its people then. */
|
|
10
|
+
export interface PackFurniture { id: string; sprite: PackStrip; x: number; y: number; depth: number | "y"; activeWhen: string[] | null; activeSprite: PackStrip | null;
|
|
11
|
+
activeFor?: string[] | null; loop?: boolean; activeOn?: "state" | "seated"; hides?: boolean; label: string | null }
|
|
9
12
|
export interface CheckedPack {
|
|
10
13
|
format: 1; id: string; scale: number; background?: string; foreground?: string; matte?: string;
|
|
11
14
|
areas: Record<string, PackArea>; stateZones: Record<string, string> | null; door: PackPoint;
|
|
15
|
+
/** #2736: where a letter from another office lands, or null (the waypoint nearest the middle). */
|
|
16
|
+
mailDrop: PackPoint | null;
|
|
12
17
|
waypoints: Array<{ id: string; x: number; y: number }>; edges: Array<[string, string]>;
|
|
13
18
|
furniture: PackFurniture[]; characters: Record<string, Record<string, PackStrip>>; byInstance: Record<string, string>;
|
|
14
19
|
props: Record<string, PackStrip>; bubbles: Record<string, Record<string, string[]>>;
|
|
15
20
|
room: { floor?: string; wall?: string }; desk: { back?: string; front?: string; lit?: string };
|
|
21
|
+
/** #2661: the Office levels' words — titles from each level up, and titles pinned on instances or NPCs. */
|
|
22
|
+
levels?: { titles?: Array<{ from: number; name: string }>; fixed?: Record<string, { title: string; hideLevel: boolean }> };
|
|
16
23
|
}
|
|
17
24
|
export interface LayoutOverrides {
|
|
18
25
|
pack: string;
|
|
@@ -20,7 +27,11 @@ export interface LayoutOverrides {
|
|
|
20
27
|
furniture?: Record<string, [number, number]>;
|
|
21
28
|
/** #2665: an item's night place (an item with a `night` only). */
|
|
22
29
|
furnitureNight?: Record<string, [number, number]>;
|
|
30
|
+
/** #2691: a seat's reservation by area and slot ("0", "1", …), in place of the pack's; `for: []` is none. */
|
|
31
|
+
seatFor?: Record<string, Record<string, { for: string[]; lend: boolean }>>;
|
|
23
32
|
door?: [number, number];
|
|
33
|
+
/** #2736: where a letter from another office lands. */
|
|
34
|
+
mailDrop?: [number, number];
|
|
24
35
|
waypoints?: Array<{ id: string; x: number; y: number }>;
|
|
25
36
|
edges?: Array<[string, string]>;
|
|
26
37
|
}
|
|
@@ -38,6 +49,7 @@ export function packStrips(pack: CheckedPack): Array<{ at: string; strip: PackSt
|
|
|
38
49
|
export function checkLayoutOverrides(x: unknown): { ok: true; overrides: LayoutOverrides } | { ok: false; error: string };
|
|
39
50
|
export function applyOverrides(pack: CheckedPack, ov: LayoutOverrides | null | undefined): { ok: true; pack: CheckedPack } | { ok: false; error: string };
|
|
40
51
|
export function fitNight<T extends LayoutOverrides | null | undefined>(pack: CheckedPack, ov: T): T;
|
|
52
|
+
export function fitSeatFor<T extends LayoutOverrides | null | undefined>(pack: CheckedPack, ov: T): T;
|
|
41
53
|
export function overridesBetween(pack: CheckedPack, edited: CheckedPack): LayoutOverrides | null;
|
|
42
54
|
export function poseStrip(set: Record<string, PackStrip> | null | undefined, pose: string, heading?: { dx: number; dy: number } | null): { strip: PackStrip; mirror: boolean } | null;
|
|
43
55
|
export function walkStrip(f: { walk?: Record<string, PackStrip> | null; walking?: boolean; heading?: { dx: number; dy: number } | null } | null | undefined): { strip: PackStrip; mirror: boolean } | null;
|