agentbox-app 0.1.7 → 0.1.12
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 +220 -58
- package/bin/agentbox.mjs +18 -3
- package/briefs/message-rules.md +24 -3
- package/briefs/worker.md +63 -49
- package/briefs/writing-rules.md +90 -131
- package/main/account-discovery.mjs +21 -20
- package/main/account-tooling.mjs +11 -11
- package/main/agent-activity.mjs +45 -5
- package/main/agent-schedule.mjs +14 -14
- package/main/agent-sessions.mjs +94 -10
- package/main/agent-updates.mjs +116 -0
- package/main/agents.mjs +52 -46
- package/main/analytics.mjs +27 -0
- package/main/approval-prompt-server.mjs +2 -2
- package/main/approvals.mjs +14 -5
- package/main/artifact-path.mjs +11 -0
- package/main/claude-bin.mjs +32 -5
- package/main/claude-input.mjs +45 -3
- package/main/claude-plan.mjs +25 -13
- package/main/code-change.mjs +3 -3
- package/main/codex-account.mjs +1 -1
- package/main/codex-bin.mjs +18 -0
- package/main/codex-launch-env.mjs +31 -0
- package/main/codex-memory-gate.mjs +260 -0
- package/main/codex-models.mjs +12 -7
- package/main/codex-threads.mjs +46 -23
- package/main/codex-usage-file.mjs +7 -7
- package/main/codex-usage.mjs +4 -4
- package/main/codex-watch.mjs +12 -12
- package/main/config.mjs +82 -17
- package/main/demo.mjs +17 -14
- package/main/dev-window.mjs +9 -9
- package/main/doc-scheme.mjs +2 -0
- package/main/engine-setup.mjs +204 -0
- package/main/feedback.mjs +55 -0
- package/main/folder-pictures.mjs +48 -0
- package/main/frame-scrollbars.mjs +90 -0
- package/main/fresh-user.mjs +7 -4
- package/main/git-change-offthread.mjs +70 -0
- package/main/git-change-thread.mjs +11 -0
- package/main/git-change.mjs +9 -3
- package/main/img-scheme.mjs +70 -1
- package/main/instruction-settings.mjs +134 -60
- package/main/ipc.mjs +335 -42
- package/main/leftovers.mjs +518 -0
- package/main/live-replies.mjs +43 -5
- package/main/machine.mjs +48 -1
- package/main/main.mjs +138 -15
- package/main/memory-gate-history.mjs +254 -0
- package/main/memory-gate-server.mjs +461 -0
- package/main/memory-gate.mjs +206 -0
- package/main/message-priority.mjs +87 -0
- package/main/notify.mjs +1 -1
- package/main/rail-note.mjs +2 -2
- package/main/refresh-agent-models.mjs +21 -0
- package/main/repeats.mjs +4 -4
- package/main/row-label.mjs +115 -51
- package/main/runs-on.mjs +93 -0
- package/main/serve.mjs +77 -5
- package/main/settings.mjs +245 -26
- package/main/ship-queue.mjs +279 -0
- package/main/sign-in-files.mjs +39 -0
- package/main/source-updater.mjs +298 -0
- package/main/store/home.mjs +84 -7
- package/main/store/project.mjs +15 -19
- package/main/store/work-items.mjs +150 -6
- package/main/store.mjs +245 -13
- package/main/supervisor.mjs +1634 -417
- package/main/task-commands.mjs +8 -10
- package/main/task-folders.mjs +94 -16
- package/main/task-remote-control.mjs +3 -3
- package/main/task-terminals.mjs +14 -2
- package/main/team/index.mjs +440 -0
- package/main/team/memory-cloud.mjs +247 -0
- package/main/team/projects.mjs +162 -0
- package/main/team/session.mjs +225 -0
- package/main/team/sign-in.mjs +106 -0
- package/main/team/supabase-backend.mjs +231 -0
- package/main/team/sync.mjs +163 -0
- package/main/updater.mjs +15 -5
- package/main/write-before-reload.mjs +50 -0
- package/mcp/core/page.mjs +10 -12
- package/mcp/core/work.mjs +123 -26
- package/mcp/tools.mjs +13 -6
- package/package.json +21 -9
- package/renderer/dist/assets/agentbox-icon-F1oN9nj_.svg +15 -0
- package/renderer/dist/assets/index-ChKsQkRw.js +1169 -0
- package/renderer/dist/assets/index-ClBXnq3B.css +32 -0
- package/renderer/dist/index.html +2 -2
- package/scripts/after-install.mjs +14 -0
- package/scripts/approval-server.sh +7 -2
- package/scripts/memory-gate-hook.sh +59 -0
- package/shared/agent-import.mjs +39 -16
- package/shared/agents.d.mts +26 -8
- package/shared/agents.mjs +100 -108
- package/shared/analytics-events.mjs +19 -2
- package/shared/answers.mjs +12 -0
- package/shared/bridge-map.d.mts +12 -0
- package/shared/bridge-map.mjs +38 -1
- package/shared/claude-commands.generated.mjs +2 -2
- package/shared/claude-models.generated.mjs +6 -6
- package/shared/claude-usage.mjs +6 -6
- package/shared/codex-import.mjs +7 -7
- package/shared/codex-modes.d.mts +50 -0
- package/shared/codex-modes.mjs +1 -1
- package/shared/codex-usage.mjs +7 -8
- package/shared/demo-world.mjs +6 -6
- package/shared/engines.mjs +27 -10
- package/shared/feedback.d.mts +14 -0
- package/shared/feedback.mjs +44 -0
- package/shared/first-run-examples.mjs +4 -4
- package/shared/first-run-practice.d.mts +16 -0
- package/shared/first-run-practice.mjs +176 -70
- package/shared/fresh-user-home.mjs +34 -4
- package/shared/instruction-defaults.json +2 -2
- package/shared/product-name.mjs +4 -2
- package/shared/project-folder-check.mjs +9 -3
- package/shared/rank.d.mts +1 -0
- package/shared/rank.mjs +22 -0
- package/shared/referenced-files.mjs +1 -1
- package/shared/runs-on.d.mts +20 -0
- package/shared/runs-on.mjs +79 -0
- package/shared/schemes.d.mts +11 -0
- package/shared/schemes.mjs +1 -1
- package/shared/shortcuts.d.mts +41 -0
- package/shared/shortcuts.mjs +236 -0
- package/shared/spawn-trouble.d.mts +2 -0
- package/shared/spawn-trouble.mjs +40 -19
- package/shared/team-rules.d.mts +17 -0
- package/shared/team-rules.mjs +230 -0
- package/shared/team-status.d.mts +11 -0
- package/shared/team-status.mjs +90 -0
- package/shared/terminal-links.d.mts +2 -0
- package/shared/terminal-links.mjs +55 -0
- package/shared/terminal-state.d.mts +1 -0
- package/shared/terminal-state.mjs +16 -0
- package/shared/thread-cards.d.mts +19 -0
- package/shared/thread-cards.mjs +254 -0
- package/shared/usage.d.mts +1 -1
- package/shared/usage.mjs +6 -7
- package/shared/work-items.mjs +258 -28
- package/shared/work-lines.mjs +393 -16
- package/worker-permissions.json +1 -1
- package/renderer/dist/assets/cel-dusk-CS5I7kJS.webp +0 -0
- package/renderer/dist/assets/cel-dusk-DUslqS6B.webp +0 -0
- package/renderer/dist/assets/cel-dusk-Jt_xVGxp.webp +0 -0
- package/renderer/dist/assets/cel-dusk-sm-BBkV-tWT.webp +0 -0
- package/renderer/dist/assets/frost-haze-CxPSOBEg.webp +0 -0
- package/renderer/dist/assets/frost-haze-sm-C_w21qgd.webp +0 -0
- package/renderer/dist/assets/ice-BC8luINc.webp +0 -0
- package/renderer/dist/assets/ice-CP9PrKHo.webp +0 -0
- package/renderer/dist/assets/ice-river-D6ziOhLY.webp +0 -0
- package/renderer/dist/assets/ice-river-UVM2-JY_.webp +0 -0
- package/renderer/dist/assets/ice-river-bErJwYWW.webp +0 -0
- package/renderer/dist/assets/ice-river-sm-Bg1U-SIj.webp +0 -0
- package/renderer/dist/assets/ice-sm-CbVcg3_D.webp +0 -0
- package/renderer/dist/assets/index-B7hhfHrT.js +0 -684
- package/renderer/dist/assets/index-CwiDv5bL.css +0 -32
- package/renderer/dist/assets/lake-C0WaW-6E.webp +0 -0
- package/renderer/dist/assets/lake-CSKjLC5K.webp +0 -0
- package/renderer/dist/assets/lake-ETGcOb25.webp +0 -0
- package/renderer/dist/assets/lake-harbour-BCQRbrHb.webp +0 -0
- package/renderer/dist/assets/lake-harbour-B_wfXTmE.webp +0 -0
- package/renderer/dist/assets/lake-harbour-Te1pEvBh.webp +0 -0
- package/renderer/dist/assets/lake-harbour-sm-Cme_ShEg.webp +0 -0
- package/renderer/dist/assets/lake-sm-CbG72Hbv.webp +0 -0
- package/renderer/dist/assets/lino-coast-CUZHcucI.webp +0 -0
- package/renderer/dist/assets/lino-coast-DP4J7cgd.webp +0 -0
- package/renderer/dist/assets/lino-coast-kOIAffr_.webp +0 -0
- package/renderer/dist/assets/lino-coast-sm-C1Mdbgit.webp +0 -0
- package/renderer/dist/assets/moon-pines-BskgnnXR.webp +0 -0
- package/renderer/dist/assets/moon-pines-CFSIIwt0.webp +0 -0
- package/renderer/dist/assets/moon-pines-PNhdOYww.webp +0 -0
- package/renderer/dist/assets/moon-pines-sm-C6K1NomK.webp +0 -0
- package/renderer/dist/assets/orbit-rings-2XV36Ch3.webp +0 -0
- package/renderer/dist/assets/orbit-rings-C4NrcYGQ.webp +0 -0
- package/renderer/dist/assets/orbit-rings-DGLk07dT.webp +0 -0
- package/renderer/dist/assets/orbit-rings-sm-Dky3YdvL.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-C6f7xnWw.webp +0 -0
- package/renderer/dist/assets/peach-haze-2-sm-Dj_Ez_Sb.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-DQjqMROg.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-Dw71H_bc.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-kOZfm-GM.webp +0 -0
- package/renderer/dist/assets/pixel-harbour-sm-Dturjuky.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C296JVMO.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-C4oMRDSx.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-CqVmQ4eh.webp +0 -0
- package/renderer/dist/assets/pixel-orbit-sm-CHagC_nO.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-C6LYu6uE.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-CIUCEESs.webp +0 -0
- package/renderer/dist/assets/pixel-ridge-sm-BnE0F_w-.webp +0 -0
- package/renderer/dist/assets/riso-hills-7heKVtry.webp +0 -0
- package/renderer/dist/assets/riso-hills-CIjAL3J6.webp +0 -0
- package/renderer/dist/assets/riso-hills-sm-DHsnbCfP.webp +0 -0
- package/renderer/dist/assets/slate-haze-BPWdkNsw.webp +0 -0
- package/renderer/dist/assets/slate-haze-sm-B0Cb5a2W.webp +0 -0
- package/renderer/dist/assets/valley-haze-BDHPqoJy.webp +0 -0
- package/renderer/dist/assets/valley-haze-sm-CTyjmPAG.webp +0 -0
- package/renderer/dist/assets/vector-dunes-DzzWLdKo.webp +0 -0
- package/renderer/dist/assets/vector-dunes-Yr9NBQUy.webp +0 -0
- package/renderer/dist/assets/vector-dunes-sm-D8MYY6ms.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BCGKN4u4.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-BF-jk5MC.webp +0 -0
- package/renderer/dist/assets/watercolour-mist-sm-Ds1xzTw9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-B1um67Z9.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-DKQdYs32.webp +0 -0
- package/renderer/dist/assets/woodblock-sea-sm-BJzNq8xh.webp +0 -0
- package/renderer/dist/emulator/audio-rules.mjs +0 -74
- package/renderer/dist/emulator/data/compression/README.md +0 -11
- package/renderer/dist/emulator/data/compression/extract7z.js +0 -1
- package/renderer/dist/emulator/data/compression/extractzip.js +0 -1
- package/renderer/dist/emulator/data/compression/libunrar.js +0 -519
- package/renderer/dist/emulator/data/compression/libunrar.wasm +0 -0
- package/renderer/dist/emulator/data/cores/README.md +0 -22
- package/renderer/dist/emulator/data/cores/mgba-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-legacy-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-thread-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/mgba-wasm.data +0 -0
- package/renderer/dist/emulator/data/cores/package.json +0 -65
- package/renderer/dist/emulator/data/cores/reports/mgba.json +0 -1
- package/renderer/dist/emulator/data/emulator.css +0 -1614
- package/renderer/dist/emulator/data/loader.js +0 -170
- package/renderer/dist/emulator/data/localization/README.md +0 -63
- package/renderer/dist/emulator/data/localization/af-FR.json +0 -339
- package/renderer/dist/emulator/data/localization/ar-AR.json +0 -301
- package/renderer/dist/emulator/data/localization/ben-BEN.json +0 -301
- package/renderer/dist/emulator/data/localization/de-GER.json +0 -301
- package/renderer/dist/emulator/data/localization/el-GR.json +0 -301
- package/renderer/dist/emulator/data/localization/en-US.json +0 -339
- package/renderer/dist/emulator/data/localization/es-ES.json +0 -310
- package/renderer/dist/emulator/data/localization/fa-AF.json +0 -310
- package/renderer/dist/emulator/data/localization/hi-HI.json +0 -301
- package/renderer/dist/emulator/data/localization/it-IT.json +0 -302
- package/renderer/dist/emulator/data/localization/ja-JA.json +0 -301
- package/renderer/dist/emulator/data/localization/jv-JV.json +0 -301
- package/renderer/dist/emulator/data/localization/ko-KO.json +0 -336
- package/renderer/dist/emulator/data/localization/pt-BR.json +0 -361
- package/renderer/dist/emulator/data/localization/retroarch.json +0 -617
- package/renderer/dist/emulator/data/localization/ro-RO.json +0 -310
- package/renderer/dist/emulator/data/localization/ru-RU.json +0 -301
- package/renderer/dist/emulator/data/localization/tr-TR.json +0 -310
- package/renderer/dist/emulator/data/localization/vi-VN.json +0 -302
- package/renderer/dist/emulator/data/localization/zh-CN.json +0 -351
- package/renderer/dist/emulator/data/src/GameManager.js +0 -464
- package/renderer/dist/emulator/data/src/compression.js +0 -142
- package/renderer/dist/emulator/data/src/emulator.js +0 -6158
- package/renderer/dist/emulator/data/src/gamepad.js +0 -167
- package/renderer/dist/emulator/data/src/nipplejs.js +0 -1
- package/renderer/dist/emulator/data/src/shaders.js +0 -236
- package/renderer/dist/emulator/data/src/socket.io.min.js +0 -7
- package/renderer/dist/emulator/data/src/storage.js +0 -125
- package/renderer/dist/emulator/data/version.json +0 -5
- package/renderer/dist/emulator/host.js +0 -299
- package/renderer/dist/emulator/index.html +0 -28
- package/renderer/dist/emulator/provenance.json +0 -6
package/mcp/core/work.mjs
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
} from '../../main/store/work-items.mjs';
|
|
26
26
|
import { matchesFilter } from '../../shared/work-items.mjs';
|
|
27
27
|
import { unleaked } from '../../shared/agents.mjs';
|
|
28
|
+
import { CONTEXT_WORDS, DONE_STEPS, DONE_STEP_WORDS, SUMMARY_WORDS, doneSteps, wordsIn } from '../../shared/thread-cards.mjs';
|
|
28
29
|
import {
|
|
29
30
|
parkPendingWrite, readPendingWrites, collectPendingWrites,
|
|
30
31
|
} from '../../main/store/pending-writes.mjs';
|
|
@@ -77,9 +78,9 @@ function locate(id, { product = null } = {}) {
|
|
|
77
78
|
//
|
|
78
79
|
// `unleaked` holds what leaks and the row it cost. It is applied here, at the
|
|
79
80
|
// boundary where an agent's text arrives, and NOT in the store: the store also
|
|
80
|
-
// holds what
|
|
81
|
-
// cuts it again on the way out, because the rows that
|
|
82
|
-
// still on
|
|
81
|
+
// holds what the user typed, and the user's words are theirs whatever they
|
|
82
|
+
// contain. The pane cuts it again on the way out, because the rows that
|
|
83
|
+
// already carry it are still on screen.
|
|
83
84
|
const WORDS = ['result', 'note', 'body', 'title', 'label'];
|
|
84
85
|
|
|
85
86
|
function saidPlainly(fields, source) {
|
|
@@ -91,12 +92,35 @@ function saidPlainly(fields, source) {
|
|
|
91
92
|
return out;
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
export function createItem(product, fields = {}, { source = 'agent' } = {}) {
|
|
95
|
+
export function createItem(product, fields = {}, { source = 'agent', from = [] } = {}) {
|
|
95
96
|
const p = resolveProduct(product);
|
|
96
|
-
const
|
|
97
|
+
const sources = [...from, fields.parent].filter(Boolean).map((id) => { try { return locate(id).item; } catch { return null; } });
|
|
98
|
+
const kept = fields.visibility ? {} : privacyFrom(sources);
|
|
99
|
+
const item = createWorkItem(p.dir, saidPlainly({ ...fields, ...kept }, source), { source });
|
|
97
100
|
return { ...item, product: p.id, productName: p.name };
|
|
98
101
|
}
|
|
99
102
|
|
|
103
|
+
/*
|
|
104
|
+
* A TASK AN AGENT FILES IS SEEN BY NO MORE PEOPLE THAN THE TASKS IT CAME FROM
|
|
105
|
+
* (w-e053ed3581). The agent asked into a private chat holds a task seen only
|
|
106
|
+
* by the chat, and what it files from there is written out of that chat; with
|
|
107
|
+
* no word of its own, a filed task in a project that reads as the whole team
|
|
108
|
+
* went on every teammate's board. So it takes the narrowest of its sources:
|
|
109
|
+
* Private if any is, else only the people every one of them names. A source
|
|
110
|
+
* with no word of its own leaves the project to decide, as before.
|
|
111
|
+
*/
|
|
112
|
+
export function privacyFrom(items) {
|
|
113
|
+
let people = null;
|
|
114
|
+
for (const item of items) {
|
|
115
|
+
if (item?.visibility === 'private') return { visibility: 'private' };
|
|
116
|
+
if (item?.visibility !== 'people') continue;
|
|
117
|
+
const named = Array.isArray(item.visibleTo) ? item.visibleTo.filter(Boolean) : [];
|
|
118
|
+
people = people ? people.filter((id) => named.includes(id)) : [...new Set(named)];
|
|
119
|
+
}
|
|
120
|
+
if (!people) return {};
|
|
121
|
+
return people.length ? { visibility: 'people', visibleTo: people } : { visibility: 'private' };
|
|
122
|
+
}
|
|
123
|
+
|
|
100
124
|
export function updateItem(id, patch, { product = null, epoch = null, source = 'agent' } = {}) {
|
|
101
125
|
const { project } = locate(id, { product });
|
|
102
126
|
const item = updateWorkItem(project.dir, id, saidPlainly(patch, source), { epoch, source });
|
|
@@ -104,28 +128,26 @@ export function updateItem(id, patch, { product = null, epoch = null, source = '
|
|
|
104
128
|
}
|
|
105
129
|
|
|
106
130
|
/*
|
|
107
|
-
* ONLY
|
|
131
|
+
* ONLY THE USER CLOSES A ROW THEY WROTE, UNLESS THEY SAID TO (w-e372d22a99).
|
|
108
132
|
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* or something like that, should it close it."
|
|
133
|
+
* A worker's job on a row the user wrote is to return what was asked for. The
|
|
134
|
+
* row closes only when the user asks for it to be closed.
|
|
112
135
|
*
|
|
113
|
-
* Until then a worker answered
|
|
114
|
-
* the row wore "Closed" from then on
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
* been closed by an agent against 361 closed by her.
|
|
136
|
+
* Until then a worker answered the ask and set it done in the same call, and
|
|
137
|
+
* the row wore "Closed" from then on: on w-3384aa9e5c a worker claimed and
|
|
138
|
+
* closed the row inside a minute, and the answer could only be found by
|
|
139
|
+
* looking in Closed.
|
|
118
140
|
*
|
|
119
|
-
* So a `done` on a row labelled `founder` needs
|
|
120
|
-
* in `closeBecause` and found in what
|
|
121
|
-
* rest of the write lands and the row stays open: the answer reaches
|
|
122
|
-
* as an answer (`answeredHerAsk`, list-rules.ts), and `awaitingHer`
|
|
123
|
-
* (supervisor.mjs) keeps a second worker off it until
|
|
124
|
-
* checked for being
|
|
125
|
-
* worker's, and the quote is what makes it one it has to make on purpose.
|
|
141
|
+
* So a `done` on a row labelled `founder` needs THE USER'S WORDS asking for it,
|
|
142
|
+
* quoted in `closeBecause` and found in what they wrote on the row. Without
|
|
143
|
+
* them the rest of the write lands and the row stays open: the answer reaches
|
|
144
|
+
* the inbox as an answer (`answeredHerAsk`, list-rules.ts), and `awaitingHer`
|
|
145
|
+
* (supervisor.mjs) keeps a second worker off it until the user speaks. The
|
|
146
|
+
* quote is checked for being the user's, not for meaning close; that judgement
|
|
147
|
+
* is the worker's, and the quote is what makes it one it has to make on purpose.
|
|
126
148
|
*
|
|
127
|
-
* A run of a repeating task is not
|
|
128
|
-
* and close quietly when there is nothing to say, so `repeat:` rows keep that.
|
|
149
|
+
* A run of a repeating task is not a user's ask. The task was set up to run
|
|
150
|
+
* daily and close quietly when there is nothing to say, so `repeat:` rows keep that.
|
|
129
151
|
*/
|
|
130
152
|
const plainly = (s) => String(s ?? '')
|
|
131
153
|
.toLowerCase()
|
|
@@ -145,6 +167,53 @@ export function saidToClose(item, words) {
|
|
|
145
167
|
return [item?.answer, item?.body, item?.title].some((t) => plainly(t).includes(quote));
|
|
146
168
|
}
|
|
147
169
|
|
|
170
|
+
/*
|
|
171
|
+
* A PUT-OFF THE USER ASKED FOR IS THEIRS (w-d6ea290028).
|
|
172
|
+
*
|
|
173
|
+
* A runAt an agent writes brakes workers and never hides the row
|
|
174
|
+
* (`parkedByAgent`, list-rules.ts), so an agent cannot take its own question
|
|
175
|
+
* out of the inbox. But "remind me in 4 days" asks for exactly that, and the
|
|
176
|
+
* row sat in Needs you wearing Scheduled until Sunday, with the user unsure
|
|
177
|
+
* whether closing it would lose the reminder.
|
|
178
|
+
*
|
|
179
|
+
* So a worker that quotes the user's own words asking for the put-off, in
|
|
180
|
+
* `deferBecause`, checked exactly as `closeBecause` is, has the moment written
|
|
181
|
+
* as the user's. That is what hides a row until it comes due, puts it in
|
|
182
|
+
* Scheduled, and lets the user's L move it again.
|
|
183
|
+
*/
|
|
184
|
+
const DEFERRED_AS_AGENT = 'The put-off was saved as YOURS, not theirs, so the row stays in their inbox until then: the words in deferBecause are not ones they wrote on this row. If they did ask for it to be put off, send runAt again with deferBecause set to their exact words.';
|
|
185
|
+
|
|
186
|
+
/*
|
|
187
|
+
* A SUMMARY LINE IS SHORT ENOUGH TO READ (w-b51b2e1c86). An agent's problem,
|
|
188
|
+
* progress or solution over SUMMARY_WORDS words is taken out of the write and
|
|
189
|
+
* the rest lands; the agent is told which line, how long, and to send it again.
|
|
190
|
+
* Refused rather than cut, because a cut sentence says less than a short one.
|
|
191
|
+
*/
|
|
192
|
+
//
|
|
193
|
+
// Since w-54e9c7243f the summary is Context (`problem`, CONTEXT_WORDS) and Done
|
|
194
|
+
// (`progress`, at most DONE_STEPS lines of DONE_STEP_WORDS each); `solution`
|
|
195
|
+
// keeps the old one-sentence limit for any writer still sending it.
|
|
196
|
+
function takeOverLong(patch) {
|
|
197
|
+
const said = [];
|
|
198
|
+
if (typeof patch.problem === 'string' && wordsIn(patch.problem) > CONTEXT_WORDS) {
|
|
199
|
+
said.push(`context, the problem field (${wordsIn(patch.problem)} words; ${CONTEXT_WORDS} at most)`);
|
|
200
|
+
delete patch.problem;
|
|
201
|
+
}
|
|
202
|
+
if (typeof patch.progress === 'string') {
|
|
203
|
+
const steps = doneSteps(patch.progress);
|
|
204
|
+
const longest = Math.max(0, ...steps.map(wordsIn));
|
|
205
|
+
if (steps.length > DONE_STEPS) said.push(`done, the progress field (${steps.length} steps; ${DONE_STEPS} at most, so keep the ones that matter)`);
|
|
206
|
+
else if (longest > DONE_STEP_WORDS) said.push(`done, the progress field (a step of ${longest} words; ${DONE_STEP_WORDS} at most each)`);
|
|
207
|
+
if (steps.length > DONE_STEPS || longest > DONE_STEP_WORDS) delete patch.progress;
|
|
208
|
+
}
|
|
209
|
+
if (typeof patch.solution === 'string' && wordsIn(patch.solution) > SUMMARY_WORDS) {
|
|
210
|
+
said.push(`solution (${wordsIn(patch.solution)} words; ${SUMMARY_WORDS} at most)`);
|
|
211
|
+
delete patch.solution;
|
|
212
|
+
}
|
|
213
|
+
if (!said.length) return {};
|
|
214
|
+
return { summaryTooLong: `Not saved: ${said.join(', ')}. The summary has to fit the panel without scrolling; everything else you sent was written, and ${said.length === 1 ? 'that part keeps' : 'those parts keep'} what ${said.length === 1 ? 'it' : 'they'} said before. Send ${said.length === 1 ? 'it' : 'them'} again shorter.` };
|
|
215
|
+
}
|
|
216
|
+
|
|
148
217
|
const LEFT_OPEN = 'The row was left OPEN. The founder wrote it, and only she closes her own rows unless she asked you to: everything else you sent was written, and your answer reaches her inbox as an answer. If she did ask you to close it, send status done again with closeBecause set to her exact words asking for it.';
|
|
149
218
|
|
|
150
219
|
/**
|
|
@@ -182,6 +251,11 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
182
251
|
for (const [id, { dir, epoch, live }] of held) {
|
|
183
252
|
if (!live) continue;
|
|
184
253
|
try {
|
|
254
|
+
const current = readWorkItem(dir, id);
|
|
255
|
+
if (!current?.claim || current.epoch !== epoch || current.claim.holder !== holder) {
|
|
256
|
+
held.get(id).live = false;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
185
259
|
heartbeatWorkItem(dir, id, { epoch, holder });
|
|
186
260
|
} catch (err) {
|
|
187
261
|
// A failed beat is not fatal: the lease still has two beats of margin,
|
|
@@ -190,6 +264,7 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
190
264
|
console.error(`${LOG} heartbeat failed for ${id}: ${err?.message ?? err}`);
|
|
191
265
|
}
|
|
192
266
|
}
|
|
267
|
+
stopTimer();
|
|
193
268
|
};
|
|
194
269
|
|
|
195
270
|
const ensureTimer = () => {
|
|
@@ -297,7 +372,7 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
297
372
|
// fence below still catches the case where somebody else took over.
|
|
298
373
|
}
|
|
299
374
|
|
|
300
|
-
const { closeBecause, ...asked } = patch;
|
|
375
|
+
const { closeBecause, deferBecause, ...asked } = patch;
|
|
301
376
|
let leftOpen = false;
|
|
302
377
|
if (asked.status === 'done') {
|
|
303
378
|
const before = readWorkItem(holding.dir, id);
|
|
@@ -306,6 +381,18 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
306
381
|
leftOpen = true;
|
|
307
382
|
}
|
|
308
383
|
}
|
|
384
|
+
let theirMoment = 0;
|
|
385
|
+
let deferredAsAgent = null;
|
|
386
|
+
if (deferBecause !== undefined && Number.isFinite(asked.runAt) && asked.runAt > 0) {
|
|
387
|
+
const before = readWorkItem(holding.dir, id);
|
|
388
|
+
if (herRow(before) && saidToClose(before, deferBecause)) {
|
|
389
|
+
theirMoment = asked.runAt;
|
|
390
|
+
delete asked.runAt;
|
|
391
|
+
} else {
|
|
392
|
+
deferredAsAgent = { deferredAsAgent: DEFERRED_AS_AGENT };
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const summaryTooLong = takeOverLong(asked);
|
|
309
396
|
patch = asked;
|
|
310
397
|
let item = Object.keys(patch).length
|
|
311
398
|
? updateWorkItem(holding.dir, id, patch, { epoch: holding.epoch })
|
|
@@ -329,6 +416,10 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
329
416
|
holding.pending = false;
|
|
330
417
|
}
|
|
331
418
|
|
|
419
|
+
// Only now, past the fence, so a session that lost the row cannot still
|
|
420
|
+
// put it away in the user's name.
|
|
421
|
+
if (theirMoment) item = updateWorkItem(holding.dir, id, { runAt: theirMoment }, { source: 'founder' });
|
|
422
|
+
|
|
332
423
|
// FINISHING A ROW GIVES THE CLAIM BACK NOW, not in five minutes. It used
|
|
333
424
|
// to drop the row from this map and leave the claim line standing, so the
|
|
334
425
|
// ledger went on reading "held by <this session>" for a full lease after
|
|
@@ -351,9 +442,9 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
351
442
|
holding.live = false;
|
|
352
443
|
stopTimer();
|
|
353
444
|
}
|
|
354
|
-
return { ...item, leftOpen: LEFT_OPEN };
|
|
445
|
+
return { ...item, leftOpen: LEFT_OPEN, ...deferredAsAgent, ...summaryTooLong };
|
|
355
446
|
}
|
|
356
|
-
return item;
|
|
447
|
+
return { ...item, ...deferredAsAgent, ...summaryTooLong };
|
|
357
448
|
},
|
|
358
449
|
|
|
359
450
|
release(id) {
|
|
@@ -365,6 +456,12 @@ export function createClaimRegistry({ heartbeatMs = HEARTBEAT_MS, holder } = {})
|
|
|
365
456
|
return item;
|
|
366
457
|
},
|
|
367
458
|
|
|
459
|
+
// Filing from this session: what it files is kept as private as every row
|
|
460
|
+
// it has held, finished ones too, since it may still be answering on them.
|
|
461
|
+
file(product, fields) {
|
|
462
|
+
return createItem(product, fields, { from: [...held.keys()] });
|
|
463
|
+
},
|
|
464
|
+
|
|
368
465
|
holding: () => [...held.entries()].filter(([, h]) => h.live).map(([id]) => id),
|
|
369
466
|
// Test seams; not part of normal use.
|
|
370
467
|
_beat: beat,
|
package/mcp/tools.mjs
CHANGED
|
@@ -16,10 +16,11 @@ import { resolveAccount } from './core/account.mjs';
|
|
|
16
16
|
import { listProducts, getProduct, createProduct, updateProduct } from './core/products.mjs';
|
|
17
17
|
import { listDocuments, readDocument, writeDocument } from './core/documents.mjs';
|
|
18
18
|
import { listSkills, fetchSkill, fetchReference } from './core/skills.mjs';
|
|
19
|
-
import { listWorkItems,
|
|
19
|
+
import { listWorkItems, updateItem, createClaimRegistry } from './core/work.mjs';
|
|
20
20
|
import { listProductChats, readProductChat } from './core/chat.mjs';
|
|
21
21
|
import { lookAtPage } from './core/page.mjs';
|
|
22
22
|
import { WORK_ITEM_STATUSES } from '../shared/work-items.mjs';
|
|
23
|
+
import { CONTEXT_WORDS, DONE_STEPS, DONE_STEP_WORDS, SUMMARY_WORDS } from '../shared/thread-cards.mjs';
|
|
23
24
|
import { AGENT_CREATION_KINDS } from '../shared/contracts.mjs';
|
|
24
25
|
// The descriptions below are read by every agent on every run, so the app is
|
|
25
26
|
// named in them from the one place it is named. They said "the app" while this
|
|
@@ -36,7 +37,7 @@ const CAPABILITIES = [
|
|
|
36
37
|
];
|
|
37
38
|
const MISSING = [
|
|
38
39
|
'create_database', 'deploy_app', 'connect_github', 'set_up_analytics',
|
|
39
|
-
'run_creation', 'browsing the web or anything
|
|
40
|
+
'run_creation', 'browsing the web or anything they are signed into', 'ask_user',
|
|
40
41
|
];
|
|
41
42
|
|
|
42
43
|
const json = (value) => ({ content: [{ type: 'text', text: JSON.stringify(value, null, 2) }] });
|
|
@@ -172,7 +173,7 @@ export function buildTools({ holder } = {}) {
|
|
|
172
173
|
parent: z.string().optional().describe('another work item id, for a subtask'),
|
|
173
174
|
runAt: z.number().int().optional().describe('epoch ms before which nothing happens with this item: it cannot be claimed and will not start. Use it when the work genuinely belongs to a later moment. A missed moment is not lost; the item simply becomes available once it passes.'),
|
|
174
175
|
},
|
|
175
|
-
run: ({ product, ...fields }) => json(
|
|
176
|
+
run: ({ product, ...fields }) => json(claims.file(product, fields)),
|
|
176
177
|
},
|
|
177
178
|
{
|
|
178
179
|
name: 'claim_work_item',
|
|
@@ -190,7 +191,7 @@ export function buildTools({ holder } = {}) {
|
|
|
190
191
|
},
|
|
191
192
|
{
|
|
192
193
|
name: 'update_work_item',
|
|
193
|
-
description: 'Report progress on an item: set status to done when it is finished, blocked when it cannot proceed until something outside it changes, and leave a note saying where things stand. A worker the app started for a row ends with its answer as its last message, and the app writes that message onto the row as the result, so such a worker does not pass result for its own row: the same answer written twice is what
|
|
194
|
+
description: 'Report progress on an item: set status to done when it is finished, blocked when it cannot proceed until something outside it changes, and leave a note saying where things stand. Keep the summary current with problem (shown as Context) and progress (shown as the Done list), which is all a teammate sees of the thread. A worker the app started for a row ends with its answer as its last message, and the app writes that message onto the row as the result, so such a worker does not pass result for its own row: the same answer written twice is what they then read twice. A row the founder wrote (labelled founder) is closed only when they asked for it: answering them is not finishing it, so the row stays open for them. To close one, pass closeBecause with their exact words asking you to; without them the rest of the write lands and the row is left open. A runAt you set holds workers off but keeps the row in their inbox; when they asked for it to be put off ("remind me Friday"), pass deferBecause with their exact words and it leaves their inbox until then. Writing to a row this session is not holding takes the row first, so there is no need to claim before you speak; the write is only refused when another session is genuinely on it, and that refusal is kept rather than thrown away, parked where the error says and handed to whoever takes the row next. Finishing a row hands the claim straight back, and you can still answer on it afterwards.',
|
|
194
195
|
schema: {
|
|
195
196
|
id: z.string(),
|
|
196
197
|
status: z.enum(WORK_ITEM_STATUSES).optional(),
|
|
@@ -199,7 +200,13 @@ export function buildTools({ holder } = {}) {
|
|
|
199
200
|
priority: z.number().int().optional(),
|
|
200
201
|
labels: z.array(z.string()).optional(),
|
|
201
202
|
runAt: z.number().int().optional().describe('epoch ms to defer this item until; 0 clears a schedule and makes it available now'),
|
|
202
|
-
closeBecause: z.string().optional().describe('only with status done on a row the founder wrote:
|
|
203
|
+
closeBecause: z.string().optional().describe('only with status done on a row the founder wrote: their own words, quoted exactly from the row, asking you to close it'),
|
|
204
|
+
deferBecause: z.string().optional().describe('only with runAt on a row the founder wrote: their own words, quoted exactly from the row, asking for it to be put off or to be reminded later. Without them the row stays in their inbox'),
|
|
205
|
+
problem: z.string().optional().describe(`the summary's CONTEXT: a few plain sentences, ${CONTEXT_WORDS} words at most, that bring the thread back to someone who has forgotten it: what was asked, what was found, the facts needed to decide`),
|
|
206
|
+
progress: z.string().optional().describe(`the summary's DONE list: the steps taken so far, one per line, oldest first and newest last, ${DONE_STEPS} lines at most of ${DONE_STEP_WORDS} words each. Send the whole list each time; it replaces the last one`),
|
|
207
|
+
solution: z.string().optional().describe(`no longer shown; leave it out (older threads may still carry one, ${SUMMARY_WORDS} words at most)`),
|
|
208
|
+
blockedBy: z.array(z.string()).optional().describe('ids of threads this one waits on'),
|
|
209
|
+
blocks: z.array(z.string()).optional().describe('ids of threads that wait on this one'),
|
|
203
210
|
},
|
|
204
211
|
run: async ({ id, ...patch }) => json(await claims.update(id, patch)),
|
|
205
212
|
},
|
|
@@ -238,7 +245,7 @@ export function buildTools({ holder } = {}) {
|
|
|
238
245
|
// address can post anything it has read to any address.
|
|
239
246
|
{
|
|
240
247
|
name: 'look_at_page',
|
|
241
|
-
description: `Open a page running on this machine, photograph it, and read its words back. For looking at what you just built: start the app, look at it, then name the picture in your message so
|
|
248
|
+
description: `Open a page running on this machine, photograph it, and read its words back. For looking at what you just built: start the app, look at it, then name the picture in your message so they see what you saw. Local addresses only, so it cannot reach the web or anything they are signed into. Returns the picture's path inside the product, plus the page's title and visible text.`,
|
|
242
249
|
schema: {
|
|
243
250
|
product: z.string(),
|
|
244
251
|
url: z.string().describe('a local address, as in http://localhost:3000/'),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentbox-app",
|
|
3
|
-
"productName": "
|
|
4
|
-
"version": "0.1.
|
|
3
|
+
"productName": "Agentbox",
|
|
4
|
+
"version": "0.1.12",
|
|
5
5
|
"description": "An inbox for managing dozens of Claude Code and Codex agents.",
|
|
6
6
|
"author": "Savannah Feder",
|
|
7
7
|
"repository": {
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"scripts/before-publish.mjs",
|
|
43
43
|
"scripts/after-install.mjs",
|
|
44
44
|
"scripts/approval-server.sh",
|
|
45
|
+
"scripts/memory-gate-hook.sh",
|
|
45
46
|
"worker-permissions.json",
|
|
46
47
|
"LICENSE",
|
|
47
48
|
"README.md"
|
|
@@ -49,21 +50,28 @@
|
|
|
49
50
|
"scripts": {
|
|
50
51
|
"dev": "node scripts/dev.mjs",
|
|
51
52
|
"build": "node scripts/prepare-terminal.mjs && node scripts/read-claude-commands.mjs && node scripts/read-claude-models.mjs && vite build renderer",
|
|
52
|
-
"start": "npm run build && electron .",
|
|
53
|
+
"start": "npm run build && node scripts/brand-electron.mjs && electron .",
|
|
53
54
|
"test": "vitest run",
|
|
55
|
+
"typecheck": "node node_modules/typescript/bin/tsc --noEmit -p renderer/tsconfig.json",
|
|
56
|
+
"test:changed": "node scripts/test-what-changed.mjs",
|
|
54
57
|
"icon": "electron scripts/make-icon.mjs",
|
|
55
58
|
"pack": "node scripts/release.mjs --no-sign",
|
|
56
59
|
"pack:side": "node scripts/pack-side.mjs",
|
|
57
60
|
"release": "node scripts/release.mjs",
|
|
61
|
+
"setup:feedback": "node scripts/set-up-feedback.mjs",
|
|
58
62
|
"fresh": "node scripts/fresh-user.mjs",
|
|
59
63
|
"hooks:install": "node scripts/install-hooks.mjs",
|
|
64
|
+
"check:public": "node scripts/check-before-public.mjs --all",
|
|
65
|
+
"ship": "node scripts/ship.mjs",
|
|
60
66
|
"prepare": "node scripts/install-hooks.mjs",
|
|
61
67
|
"serve": "node bin/agentbox.mjs",
|
|
62
68
|
"prepack": "npm run build",
|
|
63
69
|
"postinstall": "node scripts/after-install.mjs",
|
|
64
|
-
"prepublishOnly": "node scripts/before-publish.mjs"
|
|
70
|
+
"prepublishOnly": "node scripts/before-publish.mjs",
|
|
71
|
+
"app": "vite build renderer --logLevel warn && node scripts/prepare-terminal.mjs && node scripts/brand-electron.mjs && electron ."
|
|
65
72
|
},
|
|
66
73
|
"devDependencies": {
|
|
74
|
+
"@electric-sql/pglite": "^0.5.8",
|
|
67
75
|
"@fontsource-variable/source-sans-3": "^5.3.0",
|
|
68
76
|
"@tiptap/core": "^2.27.2",
|
|
69
77
|
"@tiptap/extension-link": "^2.27.2",
|
|
@@ -96,6 +104,7 @@
|
|
|
96
104
|
},
|
|
97
105
|
"dependencies": {
|
|
98
106
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
107
|
+
"@supabase/supabase-js": "^2.117.2",
|
|
99
108
|
"electron-updater": "^6.8.9",
|
|
100
109
|
"node-pty": "^1.1.0",
|
|
101
110
|
"posthog-node": "^5.21.2",
|
|
@@ -103,7 +112,7 @@
|
|
|
103
112
|
},
|
|
104
113
|
"build": {
|
|
105
114
|
"appId": "ac.astral.app",
|
|
106
|
-
"productName": "
|
|
115
|
+
"productName": "Agentbox",
|
|
107
116
|
"copyright": "Copyright © 2026 Agentbox",
|
|
108
117
|
"directories": {
|
|
109
118
|
"output": "release",
|
|
@@ -118,12 +127,14 @@
|
|
|
118
127
|
"!briefs/writing-rules.md",
|
|
119
128
|
"worker-permissions.json",
|
|
120
129
|
"scripts/approval-server.sh",
|
|
130
|
+
"scripts/memory-gate-hook.sh",
|
|
121
131
|
"renderer/dist/**/*",
|
|
122
132
|
"package.json"
|
|
123
133
|
],
|
|
124
134
|
"asarUnpack": [
|
|
125
135
|
"worker-permissions.json",
|
|
126
136
|
"scripts/approval-server.sh",
|
|
137
|
+
"scripts/memory-gate-hook.sh",
|
|
127
138
|
"node_modules/node-pty/**"
|
|
128
139
|
],
|
|
129
140
|
"mac": {
|
|
@@ -132,10 +143,11 @@
|
|
|
132
143
|
"NSDocumentsFolderUsageDescription": "Agentbox needs this to let your agents work in a project you keep in Documents.",
|
|
133
144
|
"NSDownloadsFolderUsageDescription": "Agentbox needs this to let your agents work in a project you keep in Downloads.",
|
|
134
145
|
"NSRemovableVolumesUsageDescription": "Agentbox needs this to let your agents work in a project you keep on an external disk.",
|
|
135
|
-
"NSAppleEventsUsageDescription": "Agentbox needs this
|
|
146
|
+
"NSAppleEventsUsageDescription": "Agentbox needs this when an agent you started asks another app to do something."
|
|
136
147
|
},
|
|
137
148
|
"category": "public.app-category.productivity",
|
|
138
149
|
"icon": "build/icon.icns",
|
|
150
|
+
"x64ArchFiles": "Contents/Resources/app.asar.unpacked/node_modules/node-pty/prebuilds/darwin-*/*",
|
|
139
151
|
"target": [
|
|
140
152
|
{
|
|
141
153
|
"target": "dmg",
|
|
@@ -157,7 +169,7 @@
|
|
|
157
169
|
"notarize": false
|
|
158
170
|
},
|
|
159
171
|
"dmg": {
|
|
160
|
-
"title": "
|
|
172
|
+
"title": "Agentbox",
|
|
161
173
|
"contents": [
|
|
162
174
|
{
|
|
163
175
|
"x": 140,
|
|
@@ -175,8 +187,8 @@
|
|
|
175
187
|
"publish": [
|
|
176
188
|
{
|
|
177
189
|
"provider": "github",
|
|
178
|
-
"owner": "
|
|
179
|
-
"repo": "
|
|
190
|
+
"owner": "agentboxhq",
|
|
191
|
+
"repo": "agentbox-releases"
|
|
180
192
|
}
|
|
181
193
|
]
|
|
182
194
|
},
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1024" height="1024" viewBox="0 0 1024 1024"><defs><clipPath id="tile-clip"><path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z"/></clipPath>
|
|
2
|
+
<linearGradient id="t-black" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#1b1a1a"/><stop offset="1" stop-color="#080808"/></linearGradient>
|
|
3
|
+
<linearGradient id="sheen-d" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".07"/><stop offset=".5" stop-color="#fff" stop-opacity="0"/></linearGradient>
|
|
4
|
+
<linearGradient id="edge-d" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".22"/><stop offset=".35" stop-color="#fff" stop-opacity=".05"/><stop offset="1" stop-color="#fff" stop-opacity=".03"/></linearGradient>
|
|
5
|
+
<linearGradient id="or" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#F47632"/><stop offset="1" stop-color="#E0530C"/></linearGradient>
|
|
6
|
+
<linearGradient id="sheen-or" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".22"/><stop offset=".5" stop-color="#fff" stop-opacity="0"/><stop offset="1" stop-color="#7a2400" stop-opacity=".12"/></linearGradient>
|
|
7
|
+
<linearGradient id="row-film" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#f4f1ec"/><stop offset="1" stop-color="#dcd5cd"/></linearGradient>
|
|
8
|
+
<linearGradient id="sheen-row" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".5"/><stop offset=".45" stop-color="#fff" stop-opacity="0"/></linearGradient>
|
|
9
|
+
<linearGradient id="or-edge" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#fff" stop-opacity=".3"/><stop offset=".4" stop-color="#fff" stop-opacity=".04"/><stop offset="1" stop-color="#fff" stop-opacity=".08"/></linearGradient>
|
|
10
|
+
<filter id="b3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="3"/></filter>
|
|
11
|
+
<filter id="b16" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="16"/></filter><filter id="b16" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="16"/></filter><filter id="b3" x="-50%" y="-50%" width="200%" height="200%"><feGaussianBlur stdDeviation="3"/></filter></defs><path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z" transform="translate(0 12)" fill="#000" opacity="0.42" filter="url(#b16)" /><path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z" transform="translate(0 2)" fill="#000" opacity="0.18" filter="url(#b3)" />
|
|
12
|
+
<path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z" fill="url(#t-black)"/>
|
|
13
|
+
<path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z" fill="url(#sheen-d)"/>
|
|
14
|
+
<path d="M260 284H652A28 28 0 0 1 680 312V368A28 28 0 0 1 652 396H260A28 28 0 0 1 232 368V312A28 28 0 0 1 260 284Z" fill="url(#row-film)"/><path d="M260 284H652A28 28 0 0 1 680 312V368A28 28 0 0 1 652 396H260A28 28 0 0 1 232 368V312A28 28 0 0 1 260 284Z" fill="url(#sheen-row)"/><path d="M260 620H652A28 28 0 0 1 680 648V704A28 28 0 0 1 652 732H260A28 28 0 0 1 232 704V648A28 28 0 0 1 260 620Z" fill="url(#row-film)"/><path d="M260 620H652A28 28 0 0 1 680 648V704A28 28 0 0 1 652 732H260A28 28 0 0 1 232 704V648A28 28 0 0 1 260 620Z" fill="url(#sheen-row)"/><path d="M372 452H764A28 28 0 0 1 792 480V536A28 28 0 0 1 764 564H372A28 28 0 0 1 344 536V480A28 28 0 0 1 372 452Z" transform="translate(0 14)" fill="#000" opacity="0.6" filter="url(#b16)" /><path d="M372 452H764A28 28 0 0 1 792 480V536A28 28 0 0 1 764 564H372A28 28 0 0 1 344 536V480A28 28 0 0 1 372 452Z" fill="url(#or)" /><path d="M372 452H764A28 28 0 0 1 792 480V536A28 28 0 0 1 764 564H372A28 28 0 0 1 344 536V480A28 28 0 0 1 372 452Z" fill="url(#sheen-or)" /><path d="M372 453H764A27 27 0 0 1 791 480V536A27 27 0 0 1 764 563H372A27 27 0 0 1 345 536V480A27 27 0 0 1 372 453Z" fill="none" stroke="url(#or-edge)" stroke-width="2" />
|
|
15
|
+
<path d="M924.0 512.0 L923.9 608.0 L923.8 638.6 L923.5 660.9 L923.1 679.0 L922.6 694.5 L922.0 708.2 L921.2 720.5 L920.4 731.8 L919.4 742.2 L918.3 751.9 L917.1 761.0 L915.8 769.6 L914.4 777.6 L912.8 785.3 L911.2 792.6 L909.4 799.5 L907.5 806.1 L905.4 812.4 L903.3 818.5 L901.0 824.2 L898.5 829.8 L896.0 835.1 L893.3 840.2 L890.5 845.1 L887.6 849.8 L884.5 854.3 L881.2 858.7 L877.9 862.8 L874.3 866.8 L870.7 870.7 L866.8 874.3 L862.8 877.9 L858.7 881.2 L854.3 884.5 L849.8 887.6 L845.1 890.5 L840.2 893.3 L835.1 896.0 L829.8 898.5 L824.2 901.0 L818.5 903.3 L812.4 905.4 L806.1 907.5 L799.5 909.4 L792.6 911.2 L785.3 912.8 L777.6 914.4 L769.6 915.8 L761.0 917.1 L751.9 918.3 L742.2 919.4 L731.8 920.4 L720.5 921.2 L708.2 922.0 L694.5 922.6 L679.0 923.1 L660.9 923.5 L638.6 923.8 L608.0 923.9 L512.0 924.0 L416.0 923.9 L385.4 923.8 L363.1 923.5 L345.0 923.1 L329.5 922.6 L315.8 922.0 L303.5 921.2 L292.2 920.4 L281.8 919.4 L272.1 918.3 L263.0 917.1 L254.4 915.8 L246.4 914.4 L238.7 912.8 L231.4 911.2 L224.5 909.4 L217.9 907.5 L211.6 905.4 L205.5 903.3 L199.8 901.0 L194.2 898.5 L188.9 896.0 L183.8 893.3 L178.9 890.5 L174.2 887.6 L169.7 884.5 L165.3 881.2 L161.2 877.9 L157.2 874.3 L153.3 870.7 L149.7 866.8 L146.1 862.8 L142.8 858.7 L139.5 854.3 L136.4 849.8 L133.5 845.1 L130.7 840.2 L128.0 835.1 L125.5 829.8 L123.0 824.2 L120.7 818.5 L118.6 812.4 L116.5 806.1 L114.6 799.5 L112.8 792.6 L111.2 785.3 L109.6 777.6 L108.2 769.6 L106.9 761.0 L105.7 751.9 L104.6 742.2 L103.6 731.8 L102.8 720.5 L102.0 708.2 L101.4 694.5 L100.9 679.0 L100.5 660.9 L100.2 638.6 L100.1 608.0 L100.0 512.0 L100.1 416.0 L100.2 385.4 L100.5 363.1 L100.9 345.0 L101.4 329.5 L102.0 315.8 L102.8 303.5 L103.6 292.2 L104.6 281.8 L105.7 272.1 L106.9 263.0 L108.2 254.4 L109.6 246.4 L111.2 238.7 L112.8 231.4 L114.6 224.5 L116.5 217.9 L118.6 211.6 L120.7 205.5 L123.0 199.8 L125.5 194.2 L128.0 188.9 L130.7 183.8 L133.5 178.9 L136.4 174.2 L139.5 169.7 L142.8 165.3 L146.1 161.2 L149.7 157.2 L153.3 153.3 L157.2 149.7 L161.2 146.1 L165.3 142.8 L169.7 139.5 L174.2 136.4 L178.9 133.5 L183.8 130.7 L188.9 128.0 L194.2 125.5 L199.8 123.0 L205.5 120.7 L211.6 118.6 L217.9 116.5 L224.5 114.6 L231.4 112.8 L238.7 111.2 L246.4 109.6 L254.4 108.2 L263.0 106.9 L272.1 105.7 L281.8 104.6 L292.2 103.6 L303.5 102.8 L315.8 102.0 L329.5 101.4 L345.0 100.9 L363.1 100.5 L385.4 100.2 L416.0 100.1 L512.0 100.0 L608.0 100.1 L638.6 100.2 L660.9 100.5 L679.0 100.9 L694.5 101.4 L708.2 102.0 L720.5 102.8 L731.8 103.6 L742.2 104.6 L751.9 105.7 L761.0 106.9 L769.6 108.2 L777.6 109.6 L785.3 111.2 L792.6 112.8 L799.5 114.6 L806.1 116.5 L812.4 118.6 L818.5 120.7 L824.2 123.0 L829.8 125.5 L835.1 128.0 L840.2 130.7 L845.1 133.5 L849.8 136.4 L854.3 139.5 L858.7 142.8 L862.8 146.1 L866.8 149.7 L870.7 153.3 L874.3 157.2 L877.9 161.2 L881.2 165.3 L884.5 169.7 L887.6 174.2 L890.5 178.9 L893.3 183.8 L896.0 188.9 L898.5 194.2 L901.0 199.8 L903.3 205.5 L905.4 211.6 L907.5 217.9 L909.4 224.5 L911.2 231.4 L912.8 238.7 L914.4 246.4 L915.8 254.4 L917.1 263.0 L918.3 272.1 L919.4 281.8 L920.4 292.2 L921.2 303.5 L922.0 315.8 L922.6 329.5 L923.1 345.0 L923.5 363.1 L923.8 385.4 L923.9 416.0Z" fill="none" stroke="url(#edge-d)" stroke-width="6" clip-path="url(#tile-clip)"/></svg>
|