nothumanallowed 13.5.19 → 13.5.21
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/package.json +1 -1
- package/src/constants.mjs +1 -1
- package/src/services/web-ui.mjs +295 -118
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "13.5.
|
|
3
|
+
"version": "13.5.21",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '13.5.
|
|
8
|
+
export const VERSION = '13.5.21';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
package/src/services/web-ui.mjs
CHANGED
|
@@ -2620,8 +2620,11 @@ function renderSettings(el) {
|
|
|
2620
2620
|
]) +
|
|
2621
2621
|
'<div class="card" style="margin-top:16px"><div class="card__title">Google Account</div>' +
|
|
2622
2622
|
'<div style="font-size:11px;color:var(--dim);margin-bottom:8px">Connect Gmail, Calendar, Drive, Contacts, and Tasks. Opens a browser window for Google sign-in.</div>' +
|
|
2623
|
-
(settingsData.hasGoogle ? '<div style="color:var(--green);font-size:12px;margin-bottom:8px"
|
|
2623
|
+
(settingsData.hasGoogle ? '<div style="color:var(--green);font-size:12px;margin-bottom:8px">✅ Connected</div>' : '') +
|
|
2624
|
+
'<div style="display:flex;gap:8px;flex-wrap:wrap">' +
|
|
2624
2625
|
'<button onclick="connectGoogle()" style="background:var(--green3);color:var(--bg);padding:8px 20px;border-radius:var(--r);font-weight:700;font-size:12px;cursor:pointer;border:none">' + (settingsData.hasGoogle ? 'Reconnect Google' : 'Connect Google') + '</button>' +
|
|
2626
|
+
(settingsData.hasGoogle ? '<button onclick="disconnectGoogle()" style="background:var(--red3,#7f1d1d);color:#fca5a5;padding:8px 16px;border-radius:var(--r);font-weight:700;font-size:12px;cursor:pointer;border:1px solid var(--red,#ef4444)">Disconnect Google</button>' : '') +
|
|
2627
|
+
'</div>' +
|
|
2625
2628
|
'<div id="googleStatus" style="margin-top:8px;font-size:10px;color:var(--dim)"></div>' +
|
|
2626
2629
|
'</div>' +
|
|
2627
2630
|
'</div>';
|
|
@@ -2637,6 +2640,17 @@ function connectGoogle() {
|
|
|
2637
2640
|
if (s) { s.textContent = 'Error: ' + e.message; s.style.color = 'var(--red)'; }
|
|
2638
2641
|
});
|
|
2639
2642
|
}
|
|
2643
|
+
function disconnectGoogle() {
|
|
2644
|
+
var s = document.getElementById('googleStatus');
|
|
2645
|
+
if (s) s.textContent = 'Disconnecting...';
|
|
2646
|
+
apiPost('/api/google/revoke', {}).then(function() {
|
|
2647
|
+
if (s) { s.textContent = 'Google account disconnected.'; s.style.color = 'var(--dim)'; }
|
|
2648
|
+
setTimeout(function(){ location.reload(); }, 1200);
|
|
2649
|
+
}).catch(function() {
|
|
2650
|
+
// Fallback: delete token file via CLI hint
|
|
2651
|
+
if (s) { s.textContent = 'Run: nha google revoke'; s.style.color = 'var(--amber)'; }
|
|
2652
|
+
});
|
|
2653
|
+
}
|
|
2640
2654
|
|
|
2641
2655
|
function settingsSection(id, title, desc, fields) {
|
|
2642
2656
|
var h = '<form class="card" style="margin-bottom:16px" id="settings-' + id + '" onsubmit="event.preventDefault();saveSettingsSection(\\x27' + id + '\\x27)">' +
|
|
@@ -3238,7 +3252,7 @@ function renderSidebar() {
|
|
|
3238
3252
|
\x27<div class="sidebar__brand">\x27+
|
|
3239
3253
|
\x27<button class="sidebar__close" onclick="closeSidebar()" title="Close menu">×</button>\x27+
|
|
3240
3254
|
\x27<div style="display:flex;align-items:center;gap:8px">\x27+
|
|
3241
|
-
\x27<div class="sidebar__brand-name">NHA</div>\x27+
|
|
3255
|
+
\x27<div class="sidebar__brand-name">NHA <span style="font-size:11px;font-weight:500;opacity:.7;letter-spacing:.5px">3rdArm</span></div>\x27+
|
|
3242
3256
|
\x27<span id="wsIndicator" style="color:var(--dim);font-size:8px" title="Daemon WebSocket">●</span>\x27+
|
|
3243
3257
|
\x27</div>\x27+
|
|
3244
3258
|
\x27<div id="sidebarPageTitle" style="font-size:11px;color:var(--bright);margin-top:4px;font-weight:600">\x27+t(\x27nav_dashboard\x27)+\x27</div>\x27+
|
|
@@ -3311,6 +3325,7 @@ var studioAbortController = null;
|
|
|
3311
3325
|
var parlActiveAgent = null; // active agent label during parliament streaming
|
|
3312
3326
|
var parlDoneAgents = {}; // set of completed agent labels during parliament
|
|
3313
3327
|
var _parlPersistHtml = null; // persists parliament block HTML across tab navigations
|
|
3328
|
+
var _PARL_STAMP = '<!--nha-parl-v13.5.21-->';
|
|
3314
3329
|
|
|
3315
3330
|
function stopStudio() {
|
|
3316
3331
|
if (!studioState.running) return;
|
|
@@ -3931,10 +3946,14 @@ function renderStudioNodes() {
|
|
|
3931
3946
|
: (isActive ? \x27\u2022\u2022\u2022 lavora\x27 : (isDone ? \x27\u2714 fatto\x27 : (isErr ? \x27\u2715 errore\x27 : \x27\x27)));
|
|
3932
3947
|
var bubbleBg = isOrch ? \x27rgba(99,102,241,.15)\x27 : (isActive ? \x27rgba(99,102,241,.12)\x27 : (isDone ? \x27rgba(0,0,0,.08)\x27 : \x27rgba(239,68,68,.12)\x27));
|
|
3933
3948
|
var glowBox = isActive ? (\x270 0 0 3px \x27+accentColor+\x2744,0 8px 24px \x27+accentColor+\x2733\x27) : (isDone ? (\x270 0 0 2px rgba(0,0,0,.25)\x27) : \x27none\x27);
|
|
3949
|
+
// orchWalkClass goes on the CHAR only, not the whole station card
|
|
3934
3950
|
var orchWalkClass = (isOrch && hasActive) ? \x27 iso-orch-walking\x27 : (isOrch && doneCount===totalCount&&totalCount>0 ? \x27 iso-orch-done\x27 : \x27\x27);
|
|
3935
|
-
var charHtml = isoCharSvg({emojiIdx: isOrch ? 99 : emojiIdx, isActive: isActive, isDone: isDone, scale: 1.1, accentColor: accentColor});
|
|
3951
|
+
var charHtml = \x27<div class="iso-char-mover\x27+orchWalkClass+\x27">\x27+isoCharSvg({emojiIdx: isOrch ? 99 : emojiIdx, isActive: isActive, isDone: isDone, scale: 1.1, accentColor: accentColor})+\x27</div>\x27;
|
|
3936
3952
|
var clickAttr = isOrch ? \x27\x27 : (\x27data-agent-label="\x27+esc(label)+\x27" onclick="studioScrollToAgent(this.getAttribute(String.fromCharCode(100,97,116,97,45,97,103,101,110,116,45,108,97,98,101,108)))"\x27);
|
|
3937
|
-
|
|
3953
|
+
// Flying doc emoji when active
|
|
3954
|
+
var flyDoc = isActive ? \x27<div class="iso-fly-doc" style="color:\x27+accentColor+\x27">\x27+String.fromCodePoint(0x1F4C4)+\x27</div>\x27 : \x27\x27;
|
|
3955
|
+
return \x27<div class="iso-station" \x27+clickAttr+\x27 style="box-shadow:\x27+glowBox+\x27;border-color:\x27+accentColor+\x27;transition:box-shadow .4s">\x27+
|
|
3956
|
+
flyDoc+
|
|
3938
3957
|
\x27<div class="iso-bubble\x27+(isActive?\x27 iso-bubble--active\x27:\x27\x27)+\x27" style="border-color:\x27+accentColor+\x27;color:\x27+accentColor+\x27;background:\x27+bubbleBg+\x27;visibility:\x27+(bubbleText||isOrch?\x27visible\x27:\x27hidden\x27)+\x27">\x27+esc(bubbleText)+\x27</div>\x27+
|
|
3939
3958
|
\x27<div class="iso-tool-badge">\x27+toolEmoji+\x27</div>\x27+
|
|
3940
3959
|
charHtml+
|
|
@@ -4654,7 +4673,7 @@ async function runStudio() {
|
|
|
4654
4673
|
if (!parlBlockBuilt || !pb.innerHTML.trim()) {
|
|
4655
4674
|
parlBlockBuilt = true;
|
|
4656
4675
|
|
|
4657
|
-
// ──
|
|
4676
|
+
// ── FREE agent builder — no box, just floating emoji+name ─────────
|
|
4658
4677
|
function buildSeat(prop, seatIdx) {
|
|
4659
4678
|
var lbl = prop.label || prop.agent;
|
|
4660
4679
|
var safeLbl = lbl.replace(new RegExp('[^a-zA-Z0-9_-]','g'),\x27_\x27);
|
|
@@ -4663,12 +4682,11 @@ async function runStudio() {
|
|
|
4663
4682
|
void seatIdx;
|
|
4664
4683
|
return \x27<div class="br-seat" id="brseat_\x27+safeLbl+\x27" data-lbl="\x27+esc(lbl)+\x27">\x27+
|
|
4665
4684
|
\x27<div class="br-bubble" id="brbubble_\x27+safeLbl+\x27" style="display:none"></div>\x27+
|
|
4666
|
-
\x27<div class="br-char">\x27+agentEmoji+\x27</div>\x27+
|
|
4685
|
+
\x27<div class="br-char" id="brchar_\x27+safeLbl+\x27">\x27+agentEmoji+\x27</div>\x27+
|
|
4667
4686
|
\x27<div class="br-seat-name" id="brname_\x27+safeLbl+\x27">\x27+esc(lbl)+\x27</div>\x27+
|
|
4668
4687
|
\x27</div>\x27;
|
|
4669
4688
|
}
|
|
4670
4689
|
|
|
4671
|
-
// Split agents: even indices top, odd indices bottom
|
|
4672
4690
|
var topSeats = [];
|
|
4673
4691
|
var botSeats = [];
|
|
4674
4692
|
proposals.forEach(function(prop, si) {
|
|
@@ -4677,72 +4695,150 @@ async function runStudio() {
|
|
|
4677
4695
|
var topHtml = topSeats.map(buildSeat).join(\x27\x27);
|
|
4678
4696
|
var botHtml = botSeats.map(buildSeat).join(\x27\x27);
|
|
4679
4697
|
|
|
4680
|
-
// Orchestrator
|
|
4698
|
+
// Orchestrator head — free floating, no box
|
|
4681
4699
|
var orchEmoji2 = String.fromCodePoint(0x1F9D1,0x200D,0x1F4BC);
|
|
4682
4700
|
var crownEm = String.fromCodePoint(0x1F451);
|
|
4683
|
-
var orchHeadHtml = \x27<div class="br-orch" id="brOrch"
|
|
4701
|
+
var orchHeadHtml = \x27<div class="br-orch" id="brOrch">\x27+
|
|
4684
4702
|
\x27<div class="br-orch-speech" id="brOrchSpeech" style="display:none"></div>\x27+
|
|
4685
|
-
\x27<
|
|
4686
|
-
\x27<span
|
|
4703
|
+
\x27<div class="br-orch-inner">\x27+
|
|
4704
|
+
\x27<span class="br-orch-crown">\x27+crownEm+\x27</span>\x27+
|
|
4705
|
+
\x27<span class="br-orch-emoji" id="brOrchEmoji">\x27+orchEmoji2+\x27</span>\x27+
|
|
4706
|
+
\x27</div>\x27+
|
|
4687
4707
|
\x27<div class="br-orch-label">Orchestratore</div>\x27+
|
|
4688
4708
|
\x27</div>\x27;
|
|
4689
4709
|
|
|
4690
|
-
// Conference table SVG —
|
|
4710
|
+
// ── Conference table SVG — rich walnut with real objects ────────────
|
|
4691
4711
|
var tblSvg = \x27<svg viewBox="0 0 1000 200" preserveAspectRatio="none" xmlns="http://www.w3.org/2000/svg" style="position:absolute;top:50%;left:0;width:100%;height:140px;transform:translateY(-50%);z-index:1;pointer-events:none">\x27+
|
|
4692
|
-
\x27<defs
|
|
4693
|
-
\x27<
|
|
4694
|
-
\x27<
|
|
4695
|
-
\x27
|
|
4696
|
-
|
|
4697
|
-
\x27<
|
|
4698
|
-
|
|
4699
|
-
\x27<
|
|
4700
|
-
|
|
4701
|
-
\x27<
|
|
4702
|
-
\x27<
|
|
4703
|
-
\x27<
|
|
4704
|
-
|
|
4712
|
+
\x27<defs>\x27+
|
|
4713
|
+
\x27<linearGradient id="tblGrad" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#6b4423"/><stop offset="0.4" stop-color="#4a2e12"/><stop offset="1" stop-color="#2e1a08"/></linearGradient>\x27+
|
|
4714
|
+
\x27<linearGradient id="tblSheen" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="rgba(255,255,255,0)"/><stop offset="0.3" stop-color="rgba(255,255,255,.04)"/><stop offset="0.7" stop-color="rgba(255,255,255,.06)"/><stop offset="1" stop-color="rgba(255,255,255,0)"/></linearGradient>\x27+
|
|
4715
|
+
\x27</defs>\x27+
|
|
4716
|
+
// Shadow
|
|
4717
|
+
\x27<rect x="6" y="10" width="988" height="178" rx="22" fill="rgba(0,0,0,.28)"/>\x27+
|
|
4718
|
+
// Table body
|
|
4719
|
+
\x27<rect x="0" y="2" width="1000" height="178" rx="20" fill="url(#tblGrad)"/>\x27+
|
|
4720
|
+
// Wood grain lines
|
|
4721
|
+
\x27<line x1="0" y1="48" x2="1000" y2="48" stroke="rgba(0,0,0,.07)" stroke-width="2"/>\x27+
|
|
4722
|
+
\x27<line x1="0" y1="96" x2="1000" y2="96" stroke="rgba(0,0,0,.09)" stroke-width="2.5"/>\x27+
|
|
4723
|
+
\x27<line x1="0" y1="144" x2="1000" y2="144" stroke="rgba(0,0,0,.07)" stroke-width="2"/>\x27+
|
|
4724
|
+
// Sheen
|
|
4725
|
+
\x27<rect x="0" y="2" width="1000" height="178" rx="20" fill="url(#tblSheen)"/>\x27+
|
|
4726
|
+
// Top edge highlight
|
|
4727
|
+
\x27<rect x="0" y="2" width="1000" height="6" rx="4" fill="rgba(255,255,255,.1)"/>\x27+
|
|
4728
|
+
// NHA monogram
|
|
4729
|
+
\x27<text x="500" y="118" text-anchor="middle" font-family="system-ui" font-size="58" font-weight="900" fill="rgba(160,140,255,.09)" letter-spacing="10">NHA</text>\x27+
|
|
4730
|
+
// Laptop 1
|
|
4731
|
+
\x27<rect x="155" y="55" width="68" height="46" rx="5" fill="#1a1a2e" stroke="#4a4a8a" stroke-width="2"/>\x27+
|
|
4732
|
+
\x27<rect x="160" y="59" width="58" height="34" rx="3" fill="#0d0d1a"/>\x27+
|
|
4733
|
+
\x27<rect x="162" y="61" width="54" height="30" rx="2" fill="#1e3a5f"/>\x27+
|
|
4734
|
+
\x27<rect x="148" y="101" width="82" height="5" rx="2" fill="#333"/>\x27+
|
|
4735
|
+
// Laptop 2
|
|
4736
|
+
\x27<rect x="770" y="55" width="68" height="46" rx="5" fill="#1a1a2e" stroke="#4a4a8a" stroke-width="2"/>\x27+
|
|
4737
|
+
\x27<rect x="775" y="59" width="58" height="34" rx="3" fill="#0d0d1a"/>\x27+
|
|
4738
|
+
\x27<rect x="777" y="61" width="54" height="30" rx="2" fill="#1e3a5f"/>\x27+
|
|
4739
|
+
\x27<rect x="763" y="101" width="82" height="5" rx="2" fill="#333"/>\x27+
|
|
4740
|
+
// Telephone with handset (center-left)
|
|
4741
|
+
\x27<rect x="360" y="62" width="52" height="38" rx="4" fill="#2a2a2a" stroke="#555" stroke-width="1.5"/>\x27+
|
|
4742
|
+
\x27<ellipse cx="366" cy="72" rx="6" ry="8" fill="#1a1a1a" stroke="#888" stroke-width="1"/>\x27+
|
|
4743
|
+
\x27<ellipse cx="406" cy="72" rx="6" ry="8" fill="#1a1a1a" stroke="#888" stroke-width="1"/>\x27+
|
|
4744
|
+
\x27<line x1="366" y1="72" x2="406" y2="72" stroke="#666" stroke-width="3" stroke-linecap="round"/>\x27+
|
|
4745
|
+
\x27<rect x="372" y="76" width="40" height="18" rx="2" fill="#333"/>\x27+
|
|
4746
|
+
// Coffee cup 1
|
|
4747
|
+
\x27<rect x="570" y="68" width="28" height="28" rx="4" fill="#f5f0e8" stroke="#c8b08a" stroke-width="1.5"/>\x27+
|
|
4748
|
+
\x27<rect x="575" y="73" width="18" height="15" rx="2" fill="#6b3a1f" opacity=".8"/>\x27+
|
|
4749
|
+
\x27<path d="M598 78 Q608 83 598 88" stroke="#c8b08a" stroke-width="2" fill="none"/>\x27+
|
|
4750
|
+
// Mini plant on table
|
|
4751
|
+
\x27<rect x="470" y="72" width="14" height="16" rx="2" fill="#8B6914"/>\x27+
|
|
4752
|
+
\x27<ellipse cx="477" cy="68" rx="10" ry="12" fill="#2d6a2d"/>\x27+
|
|
4753
|
+
\x27<ellipse cx="470" cy="65" rx="7" ry="9" fill="#3a8a3a"/>\x27+
|
|
4754
|
+
\x27<ellipse cx="484" cy="65" rx="7" ry="9" fill="#2d7a2d"/>\x27+
|
|
4705
4755
|
\x27</svg>\x27;
|
|
4706
4756
|
|
|
4707
|
-
// Background
|
|
4757
|
+
// ── Background SVG — enhanced room with art, detailed door, windows ─
|
|
4708
4758
|
var bgSvg = \x27<svg viewBox="0 0 1000 600" preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg" style="position:absolute;top:0;left:0;width:100%;height:100%;z-index:0;pointer-events:none">\x27+
|
|
4709
4759
|
\x27<defs>\x27+
|
|
4710
4760
|
\x27<filter id="brGlow" x="-100%" y="-100%" width="300%" height="300%"><feGaussianBlur stdDeviation="5" result="b"/><feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge></filter>\x27+
|
|
4711
|
-
\x27<
|
|
4761
|
+
\x27<filter id="brShadow" x="-20%" y="-20%" width="140%" height="140%"><feDropShadow dx="2" dy="2" stdDeviation="3" flood-color="rgba(0,0,0,.2)"/></filter>\x27+
|
|
4762
|
+
\x27<linearGradient id="brWall" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#f5f0e8"/><stop offset="1" stop-color="#e8e0d0"/></linearGradient>\x27+
|
|
4763
|
+
\x27<linearGradient id="winGrad" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#b8dff8"/><stop offset="1" stop-color="#d8f0ff"/></linearGradient>\x27+
|
|
4764
|
+
\x27<linearGradient id="doorGrad" x1="0" y1="0" x2="1" y2="0"><stop offset="0" stop-color="#a0724a"/><stop offset="0.5" stop-color="#c8905c"/><stop offset="1" stop-color="#a0724a"/></linearGradient>\x27+
|
|
4712
4765
|
\x27</defs>\x27+
|
|
4713
|
-
|
|
4714
|
-
\x27<rect x="0" y="
|
|
4766
|
+
// Wall
|
|
4767
|
+
\x27<rect x="0" y="0" width="1000" height="215" fill="url(#brWall)"/>\x27+
|
|
4768
|
+
// Crown molding
|
|
4769
|
+
\x27<rect x="0" y="0" width="1000" height="8" fill="#d8cfc0"/>\x27+
|
|
4770
|
+
\x27<rect x="0" y="8" width="1000" height="4" fill="#e8e0d0"/>\x27+
|
|
4771
|
+
// Baseboard
|
|
4772
|
+
\x27<rect x="0" y="206" width="1000" height="9" fill="#c8b898" rx="1"/>\x27+
|
|
4773
|
+
\x27<rect x="0" y="210" width="1000" height="3" fill="#b0a080"/>\x27+
|
|
4774
|
+
// Parquet floor
|
|
4715
4775
|
function() {
|
|
4716
|
-
var
|
|
4717
|
-
var
|
|
4718
|
-
var
|
|
4719
|
-
for (var
|
|
4720
|
-
var
|
|
4721
|
-
for (var
|
|
4722
|
-
var
|
|
4723
|
-
|
|
4724
|
-
|
|
4776
|
+
var s3 = \x27\x27;
|
|
4777
|
+
var pC = [\x27#c8a06a\x27,\x27#bf9860\x27,\x27#d4aa72\x27,\x27#ba9458\x27,\x27#caa86e\x27];
|
|
4778
|
+
var pH3 = 32; var pW3 = 120;
|
|
4779
|
+
for (var fy3 = 215; fy3 < 600+pH3; fy3 += pH3) {
|
|
4780
|
+
var ro4 = (Math.floor((fy3-215)/pH3) % 2) * (pW3/2);
|
|
4781
|
+
for (var fx3 = -pW3+ro4; fx3 < 1000+pW3; fx3 += pW3) {
|
|
4782
|
+
var pc4 = pC[Math.abs(Math.round(fx3/pW3+fy3/pH3*1.3)) % pC.length];
|
|
4783
|
+
s3 += \x27<rect x="\x27+Math.round(fx3)+\x27" y="\x27+fy3+\x27" width="\x27+(pW3-2)+\x27" height="\x27+(pH3-2)+\x27" fill="\x27+pc4+\x27" rx="2"/>\x27;
|
|
4784
|
+
s3 += \x27<line x1="\x27+Math.round(fx3+pW3*.4)+\x27" y1="\x27+fy3+\x27" x2="\x27+Math.round(fx3+pW3*.4)+\x27" y2="\x27+(fy3+pH3-2)+\x27" stroke="rgba(0,0,0,.04)" stroke-width="1.5"/>\x27;
|
|
4725
4785
|
}
|
|
4726
4786
|
}
|
|
4727
|
-
return
|
|
4787
|
+
return s3;
|
|
4728
4788
|
}()+
|
|
4729
|
-
|
|
4730
|
-
\x27<
|
|
4731
|
-
\x27<
|
|
4732
|
-
\x27<rect x="
|
|
4733
|
-
\x27<
|
|
4734
|
-
\x27<line x1="
|
|
4735
|
-
|
|
4736
|
-
\x27<rect x="
|
|
4737
|
-
|
|
4738
|
-
\x27<rect x="
|
|
4739
|
-
\x27<
|
|
4740
|
-
\x27<
|
|
4741
|
-
\x27<
|
|
4742
|
-
\x27<
|
|
4743
|
-
\x27<
|
|
4744
|
-
|
|
4745
|
-
\x27<
|
|
4789
|
+
// Window LEFT — thick frame, venetian blinds effect
|
|
4790
|
+
\x27<rect x="28" y="18" width="126" height="96" rx="3" fill="#4a6080" stroke="#2a3a50" stroke-width="4"/>\x27+
|
|
4791
|
+
\x27<rect x="34" y="24" width="114" height="84" rx="2" fill="url(#winGrad)"/>\x27+
|
|
4792
|
+
\x27<rect x="34" y="24" width="114" height="84" rx="2" fill="rgba(255,255,255,.12)"/>\x27+
|
|
4793
|
+
\x27<line x1="91" y1="24" x2="91" y2="108" stroke="#3a5070" stroke-width="3"/>\x27+
|
|
4794
|
+
\x27<line x1="34" y1="66" x2="148" y2="66" stroke="#3a5070" stroke-width="3"/>\x27+
|
|
4795
|
+
// window sill
|
|
4796
|
+
\x27<rect x="22" y="114" width="138" height="8" rx="2" fill="#c8b898"/>\x27+
|
|
4797
|
+
// Window RIGHT
|
|
4798
|
+
\x27<rect x="846" y="18" width="126" height="96" rx="3" fill="#4a6080" stroke="#2a3a50" stroke-width="4"/>\x27+
|
|
4799
|
+
\x27<rect x="852" y="24" width="114" height="84" rx="2" fill="url(#winGrad)"/>\x27+
|
|
4800
|
+
\x27<rect x="852" y="24" width="114" height="84" rx="2" fill="rgba(255,255,255,.12)"/>\x27+
|
|
4801
|
+
\x27<line x1="909" y1="24" x2="909" y2="108" stroke="#3a5070" stroke-width="3"/>\x27+
|
|
4802
|
+
\x27<line x1="852" y1="66" x2="966" y2="66" stroke="#3a5070" stroke-width="3"/>\x27+
|
|
4803
|
+
\x27<rect x="840" y="114" width="138" height="8" rx="2" fill="#c8b898"/>\x27+
|
|
4804
|
+
// Door CENTER — detailed with panels and handle
|
|
4805
|
+
\x27<rect x="455" y="0" width="90" height="215" fill="url(#doorGrad)" stroke="#7a5030" stroke-width="3"/>\x27+
|
|
4806
|
+
// Door panels
|
|
4807
|
+
\x27<rect x="463" y="10" width="74" height="55" rx="3" fill="rgba(0,0,0,.08)" stroke="rgba(0,0,0,.15)" stroke-width="1.5"/>\x27+
|
|
4808
|
+
\x27<rect x="463" y="72" width="74" height="55" rx="3" fill="rgba(0,0,0,.08)" stroke="rgba(0,0,0,.15)" stroke-width="1.5"/>\x27+
|
|
4809
|
+
\x27<rect x="463" y="134" width="74" height="55" rx="3" fill="rgba(0,0,0,.06)" stroke="rgba(0,0,0,.12)" stroke-width="1.5"/>\x27+
|
|
4810
|
+
// Door handle
|
|
4811
|
+
\x27<circle cx="533" cy="118" r="7" fill="#c8a040" stroke="#a07828" stroke-width="2"/>\x27+
|
|
4812
|
+
\x27<rect x="530" y="118" width="14" height="4" rx="2" fill="#c8a040" stroke="#a07828" stroke-width="1"/>\x27+
|
|
4813
|
+
// Door frame
|
|
4814
|
+
\x27<rect x="451" y="0" width="5" height="215" fill="#7a5030"/>\x27+
|
|
4815
|
+
\x27<rect x="544" y="0" width="5" height="215" fill="#7a5030"/>\x27+
|
|
4816
|
+
// Painting LEFT — abstract NHA art
|
|
4817
|
+
\x27<rect x="190" y="18" width="100" height="76" rx="3" fill="#f8f4ee" stroke="#8a7050" stroke-width="4" filter="url(#brShadow)"/>\x27+
|
|
4818
|
+
\x27<rect x="196" y="24" width="88" height="64" rx="1" fill="#1a1060"/>\x27+
|
|
4819
|
+
\x27<circle cx="240" cy="56" r="22" fill="#6366f1" opacity=".7"/>\x27+
|
|
4820
|
+
\x27<circle cx="240" cy="56" r="14" fill="#818cf8" opacity=".8"/>\x27+
|
|
4821
|
+
\x27<circle cx="240" cy="56" r="6" fill="#c7d2fe"/>\x27+
|
|
4822
|
+
\x27<text x="240" y="60" text-anchor="middle" font-size="10" font-weight="900" fill="white" font-family="system-ui">NHA</text>\x27+
|
|
4823
|
+
// Painting RIGHT — landscape
|
|
4824
|
+
\x27<rect x="710" y="18" width="110" height="76" rx="3" fill="#f8f4ee" stroke="#8a7050" stroke-width="4" filter="url(#brShadow)"/>\x27+
|
|
4825
|
+
\x27<rect x="716" y="24" width="98" height="64" rx="1" fill="#87CEEB"/>\x27+
|
|
4826
|
+
\x27<ellipse cx="765" cy="65" rx="48" ry="20" fill="#228B22"/>\x27+
|
|
4827
|
+
\x27<circle cx="748" cy="52" rx="14" ry="14" fill="#ffed4a" opacity=".9"/>\x27+
|
|
4828
|
+
\x27<ellipse cx="730" cy="62" rx="12" ry="16" fill="#1a5c1a"/>\x27+
|
|
4829
|
+
\x27<ellipse cx="780" cy="60" rx="10" ry="14" fill="#2a7a2a"/>\x27+
|
|
4830
|
+
// Chandelier
|
|
4831
|
+
\x27<line x1="500" y1="0" x2="500" y2="28" stroke="#aaa" stroke-width="4"/>\x27+
|
|
4832
|
+
\x27<ellipse cx="500" cy="36" rx="52" ry="14" fill="#f0d830" stroke="#c8a820" stroke-width="3"/>\x27+
|
|
4833
|
+
\x27<ellipse cx="500" cy="36" rx="45" ry="10" fill="#ffe850" opacity=".5"/>\x27+
|
|
4834
|
+
\x27<circle cx="470" cy="47" r="9" fill="#fffce0" filter="url(#brGlow)"/>\x27+
|
|
4835
|
+
\x27<circle cx="500" cy="50" r="9" fill="#fffce0" filter="url(#brGlow)"/>\x27+
|
|
4836
|
+
\x27<circle cx="530" cy="47" r="9" fill="#fffce0" filter="url(#brGlow)"/>\x27+
|
|
4837
|
+
\x27<circle cx="455" cy="40" r="6" fill="#ffe060" filter="url(#brGlow)"/>\x27+
|
|
4838
|
+
\x27<circle cx="545" cy="40" r="6" fill="#ffe060" filter="url(#brGlow)"/>\x27+
|
|
4839
|
+
\x27<polygon points="448,62 552,62 680,600 320,600" fill="rgba(255,252,180,.07)"/>\x27+
|
|
4840
|
+
// Cross-agent conversation lines overlay placeholder (updated dynamically)
|
|
4841
|
+
\x27<g id="brConvLines"></g>\x27+
|
|
4746
4842
|
\x27</svg>\x27;
|
|
4747
4843
|
|
|
4748
4844
|
var headerHtml = \x27<div class="br-header">\x27+
|
|
@@ -4757,8 +4853,14 @@ async function runStudio() {
|
|
|
4757
4853
|
headerHtml+
|
|
4758
4854
|
\x27<div class="br-room">\x27+
|
|
4759
4855
|
bgSvg+
|
|
4760
|
-
|
|
4761
|
-
\x27<div style="position:absolute;bottom:
|
|
4856
|
+
// Decorative plants at corners
|
|
4857
|
+
\x27<div style="position:absolute;bottom:8px;left:10px;font-size:44px;z-index:5;filter:drop-shadow(0 3px 8px rgba(0,0,0,.3))">\x27+String.fromCodePoint(0x1FAB4)+\x27</div>\x27+
|
|
4858
|
+
\x27<div style="position:absolute;bottom:8px;right:10px;font-size:44px;z-index:5;filter:drop-shadow(0 3px 8px rgba(0,0,0,.3))">\x27+String.fromCodePoint(0x1FAB4)+\x27</div>\x27+
|
|
4859
|
+
// Small plants on window sills
|
|
4860
|
+
\x27<div style="position:absolute;top:112px;left:58px;font-size:20px;z-index:5">\x27+String.fromCodePoint(0x1F331)+\x27</div>\x27+
|
|
4861
|
+
\x27<div style="position:absolute;top:112px;right:58px;font-size:20px;z-index:5">\x27+String.fromCodePoint(0x1F331)+\x27</div>\x27+
|
|
4862
|
+
// Cross-agent communication SVG overlay (dynamic, updated per call)
|
|
4863
|
+
\x27<svg id="brCommSvg" style="position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:8;overflow:visible"></svg>\x27+
|
|
4762
4864
|
\x27<div style="position:relative;z-index:10;display:flex;flex-direction:column;justify-content:center;min-height:480px;padding:20px 16px;gap:0;box-sizing:border-box">\x27+
|
|
4763
4865
|
\x27<div class="br-seats-row">\x27+topHtml+\x27</div>\x27+
|
|
4764
4866
|
\x27<div style="position:relative;display:flex;align-items:center;width:100%;min-height:160px">\x27+
|
|
@@ -4820,49 +4922,14 @@ async function runStudio() {
|
|
|
4820
4922
|
orchEl.style.setProperty(\x27--oc\x27, phaseColor);
|
|
4821
4923
|
}
|
|
4822
4924
|
|
|
4823
|
-
//
|
|
4824
|
-
var orchEl2 = document.getElementById(\x27brOrch\x27);
|
|
4825
|
-
var brRoom2 = orchEl2 ? orchEl2.closest(\x27.br-room\x27) : null;
|
|
4826
|
-
if (brRoom2) {
|
|
4827
|
-
var existLine = brRoom2.querySelector(\x27.br-attention-line\x27);
|
|
4828
|
-
if (existLine) existLine.parentNode.removeChild(existLine);
|
|
4829
|
-
if (activeLabel && phase !== \x27done\x27) {
|
|
4830
|
-
var aLblSafe = activeLabel.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27);
|
|
4831
|
-
var activeSeatEl = document.getElementById(\x27brseat_\x27+aLblSafe);
|
|
4832
|
-
if (activeSeatEl && orchEl2) {
|
|
4833
|
-
var roomRect = brRoom2.getBoundingClientRect();
|
|
4834
|
-
var orchRect = orchEl2.getBoundingClientRect();
|
|
4835
|
-
var seatRect = activeSeatEl.getBoundingClientRect();
|
|
4836
|
-
var x1 = orchRect.left + orchRect.width/2 - roomRect.left;
|
|
4837
|
-
var y1 = orchRect.top + orchRect.height/2 - roomRect.top;
|
|
4838
|
-
var x2 = seatRect.left + seatRect.width/2 - roomRect.left;
|
|
4839
|
-
var y2 = seatRect.top + seatRect.height/2 - roomRect.top;
|
|
4840
|
-
var lineSvg = document.createElementNS(\x27http://www.w3.org/2000/svg\x27, \x27svg\x27);
|
|
4841
|
-
lineSvg.setAttribute(\x27class\x27, \x27br-attention-line\x27);
|
|
4842
|
-
lineSvg.style.cssText = \x27position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:10;overflow:visible\x27;
|
|
4843
|
-
var lineEl = document.createElementNS(\x27http://www.w3.org/2000/svg\x27, \x27line\x27);
|
|
4844
|
-
lineEl.setAttribute(\x27x1\x27, String(Math.round(x1)));
|
|
4845
|
-
lineEl.setAttribute(\x27y1\x27, String(Math.round(y1)));
|
|
4846
|
-
lineEl.setAttribute(\x27x2\x27, String(Math.round(x2)));
|
|
4847
|
-
lineEl.setAttribute(\x27y2\x27, String(Math.round(y2)));
|
|
4848
|
-
lineEl.setAttribute(\x27stroke\x27, \x27#6366f1\x27);
|
|
4849
|
-
lineEl.setAttribute(\x27stroke-width\x27, \x272\x27);
|
|
4850
|
-
lineEl.setAttribute(\x27stroke-dasharray\x27, \x276 4\x27);
|
|
4851
|
-
lineEl.setAttribute(\x27opacity\x27, \x27.6\x27);
|
|
4852
|
-
lineEl.style.animation = \x27brDashFlow 1s linear infinite\x27;
|
|
4853
|
-
lineSvg.appendChild(lineEl);
|
|
4854
|
-
brRoom2.appendChild(lineSvg);
|
|
4855
|
-
}
|
|
4856
|
-
}
|
|
4857
|
-
}
|
|
4858
|
-
|
|
4859
|
-
// Update each agent seat state
|
|
4925
|
+
// ── Update each agent seat state ────────────────────────────────────
|
|
4860
4926
|
proposals.forEach(function(prop) {
|
|
4861
4927
|
var lbl = prop.label || prop.agent;
|
|
4862
4928
|
var safeLbl = lbl.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27);
|
|
4863
4929
|
var seatEl = document.getElementById(\x27brseat_\x27+safeLbl);
|
|
4864
4930
|
var bubbleEl = document.getElementById(\x27brbubble_\x27+safeLbl);
|
|
4865
4931
|
var nameEl = document.getElementById(\x27brname_\x27+safeLbl);
|
|
4932
|
+
var charEl = document.getElementById(\x27brchar_\x27+safeLbl);
|
|
4866
4933
|
var isDone = !!parlDoneAgents[lbl];
|
|
4867
4934
|
var isActive = lbl === activeLabel;
|
|
4868
4935
|
|
|
@@ -4872,27 +4939,122 @@ async function runStudio() {
|
|
|
4872
4939
|
(isDone ? \x27 br-seat--done\x27 : \x27\x27);
|
|
4873
4940
|
seatEl.style.setProperty(\x27--sc\x27, phaseColor);
|
|
4874
4941
|
}
|
|
4942
|
+
// Character animation: bob when active
|
|
4943
|
+
if (charEl) {
|
|
4944
|
+
charEl.style.animation = isActive ? \x27brCharBob .8s ease-in-out infinite\x27 : \x27\x27;
|
|
4945
|
+
charEl.style.filter = isActive
|
|
4946
|
+
? (\x27drop-shadow(0 0 12px \x27+phaseColor+\x27)\x27)
|
|
4947
|
+
: (isDone ? \x27none\x27 : \x27grayscale(.4)\x27);
|
|
4948
|
+
}
|
|
4875
4949
|
if (bubbleEl) {
|
|
4876
4950
|
var actionStr2 = \x27\x27;
|
|
4877
4951
|
if (phase===\x27r1\x27 && isActive) actionStr2 = \x27...analizza\x27;
|
|
4878
4952
|
else if (phase===\x27r1\x27 && isDone) actionStr2 = \x27\u2714 bozza pronta\x27;
|
|
4879
|
-
else if (phase===\x27r2\x27 && isActive) actionStr2 = \x27...legge
|
|
4953
|
+
else if (phase===\x27r2\x27 && isActive) actionStr2 = \x27...legge proposte\x27;
|
|
4880
4954
|
else if (phase===\x27r2\x27 && isDone) actionStr2 = \x27\u2714 raffinato\x27;
|
|
4881
4955
|
else if (phase===\x27r3\x27 && isActive) actionStr2 = \x27...media\x27;
|
|
4882
4956
|
else if (phase===\x27done\x27) actionStr2 = \x27\u2714 consenso\x27;
|
|
4957
|
+
else if (!isActive && !isDone && phase===\x27r2\x27) actionStr2 = \x27legge...\x27;
|
|
4883
4958
|
else if (!isActive && !isDone) actionStr2 = \x27in attesa\x27;
|
|
4884
4959
|
bubbleEl.textContent = actionStr2;
|
|
4885
4960
|
bubbleEl.style.display = actionStr2 ? \x27\x27 : \x27none\x27;
|
|
4886
4961
|
bubbleEl.style.borderColor = isActive ? phaseColor : (isDone ? \x27rgba(0,0,0,.25)\x27 : \x27rgba(0,0,0,.15)\x27);
|
|
4887
4962
|
bubbleEl.style.color = isActive ? phaseColor : (isDone ? \x27#111827\x27 : \x27#6b7280\x27);
|
|
4963
|
+
bubbleEl.style.background = isActive ? \x27rgba(255,255,255,.95)\x27 : \x27rgba(255,255,255,.82)\x27;
|
|
4964
|
+
bubbleEl.style.fontWeight = isActive ? \x27700\x27 : \x27500\x27;
|
|
4888
4965
|
}
|
|
4889
4966
|
if (nameEl) {
|
|
4890
4967
|
nameEl.style.color = isDone ? \x27#111827\x27 : (isActive ? phaseColor : \x27#374151\x27);
|
|
4968
|
+
nameEl.style.fontWeight = isActive ? \x27800\x27 : \x27600\x27;
|
|
4891
4969
|
}
|
|
4892
4970
|
});
|
|
4893
4971
|
|
|
4972
|
+
// ── Cross-agent communication lines (R2/R3 only) ────────────────────
|
|
4973
|
+
// In R2: show lines from active agent to all done agents (cross-reading)
|
|
4974
|
+
// In R1/done: show orch→active line only
|
|
4975
|
+
var commSvg = document.getElementById(\x27brCommSvg\x27);
|
|
4976
|
+
var brRoom2 = commSvg ? commSvg.closest(\x27.br-room\x27) : null;
|
|
4977
|
+
if (commSvg && brRoom2) {
|
|
4978
|
+
commSvg.innerHTML = \x27\x27;
|
|
4979
|
+
var roomRect2 = brRoom2.getBoundingClientRect();
|
|
4980
|
+
var ns = \x27http://www.w3.org/2000/svg\x27;
|
|
4981
|
+
|
|
4982
|
+
function addCommLine(fromEl, toEl, color, dash, width, opacity, anim) {
|
|
4983
|
+
if (!fromEl || !toEl) return;
|
|
4984
|
+
var fr = fromEl.getBoundingClientRect();
|
|
4985
|
+
var tr = toEl.getBoundingClientRect();
|
|
4986
|
+
var lx1 = Math.round(fr.left + fr.width/2 - roomRect2.left);
|
|
4987
|
+
var ly1 = Math.round(fr.top + fr.height/2 - roomRect2.top);
|
|
4988
|
+
var lx2 = Math.round(tr.left + tr.width/2 - roomRect2.left);
|
|
4989
|
+
var ly2 = Math.round(tr.top + tr.height/2 - roomRect2.top);
|
|
4990
|
+
// Bezier curve for elegance
|
|
4991
|
+
var mx = (lx1+lx2)/2; var my = Math.min(ly1,ly2) - 30;
|
|
4992
|
+
var path = document.createElementNS(ns, \x27path\x27);
|
|
4993
|
+
path.setAttribute(\x27d\x27, \x27M\x27+lx1+\x27,\x27+ly1+\x27 Q\x27+mx+\x27,\x27+my+\x27 \x27+lx2+\x27,\x27+ly2);
|
|
4994
|
+
path.setAttribute(\x27stroke\x27, color);
|
|
4995
|
+
path.setAttribute(\x27stroke-width\x27, String(width||2));
|
|
4996
|
+
path.setAttribute(\x27stroke-dasharray\x27, dash||\x27\x27);
|
|
4997
|
+
path.setAttribute(\x27fill\x27, \x27none\x27);
|
|
4998
|
+
path.setAttribute(\x27opacity\x27, String(opacity||.6));
|
|
4999
|
+
if (anim) path.style.animation = anim;
|
|
5000
|
+
// Arrow marker at end
|
|
5001
|
+
var mk = document.createElementNS(ns, \x27marker\x27);
|
|
5002
|
+
var mkId = \x27arr\x27+Math.random().toString(36).slice(2,6);
|
|
5003
|
+
mk.setAttribute(\x27id\x27, mkId);
|
|
5004
|
+
mk.setAttribute(\x27markerWidth\x27,\x278\x27);mk.setAttribute(\x27markerHeight\x27,\x276\x27);
|
|
5005
|
+
mk.setAttribute(\x27refX\x27,\x278\x27);mk.setAttribute(\x27refY\x27,\x273\x27);
|
|
5006
|
+
mk.setAttribute(\x27orient\x27,\x27auto\x27);
|
|
5007
|
+
var poly = document.createElementNS(ns,\x27polygon\x27);
|
|
5008
|
+
poly.setAttribute(\x27points\x27,\x270 0, 8 3, 0 6\x27);
|
|
5009
|
+
poly.setAttribute(\x27fill\x27, color);
|
|
5010
|
+
mk.appendChild(poly);
|
|
5011
|
+
var defs2 = document.createElementNS(ns,\x27defs\x27);
|
|
5012
|
+
defs2.appendChild(mk);
|
|
5013
|
+
commSvg.appendChild(defs2);
|
|
5014
|
+
path.setAttribute(\x27marker-end\x27,\x27url(#\x27+mkId+\x27)\x27);
|
|
5015
|
+
commSvg.appendChild(path);
|
|
5016
|
+
// Floating emoji dot on path midpoint
|
|
5017
|
+
var dot = document.createElementNS(ns, \x27text\x27);
|
|
5018
|
+
dot.setAttribute(\x27x\x27, String(Math.round(mx)));
|
|
5019
|
+
dot.setAttribute(\x27y\x27, String(Math.round(my-8)));
|
|
5020
|
+
dot.setAttribute(\x27text-anchor\x27, \x27middle\x27);
|
|
5021
|
+
dot.setAttribute(\x27font-size\x27, \x2714\x27);
|
|
5022
|
+
dot.textContent = phase===\x27r2\x27 ? String.fromCodePoint(0x1F4AC) : (phase===\x27r3\x27 ? String.fromCodePoint(0x1F91D) : String.fromCodePoint(0x1F4E8));
|
|
5023
|
+
dot.style.animation = \x27brDotFloat 1.5s ease-in-out infinite\x27;
|
|
5024
|
+
commSvg.appendChild(dot);
|
|
5025
|
+
}
|
|
5026
|
+
|
|
5027
|
+
var orchEl2 = document.getElementById(\x27brOrch\x27);
|
|
5028
|
+
if (phase === \x27done\x27) {
|
|
5029
|
+
// All done: show web of connections between all agents
|
|
5030
|
+
proposals.forEach(function(pa, ia) {
|
|
5031
|
+
proposals.forEach(function(pb2, ib2) {
|
|
5032
|
+
if (ib2 <= ia) return;
|
|
5033
|
+
var ea = document.getElementById(\x27brseat_\x27+pa.label.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27));
|
|
5034
|
+
var eb = document.getElementById(\x27brseat_\x27+pb2.label.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27));
|
|
5035
|
+
addCommLine(ea, eb, \x27#22c55e\x27, \x273 3\x27, 1.5, 0.3, \x27\x27);
|
|
5036
|
+
});
|
|
5037
|
+
});
|
|
5038
|
+
} else if (activeLabel) {
|
|
5039
|
+
var aLblSafe2 = activeLabel.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27);
|
|
5040
|
+
var activeSeatEl2 = document.getElementById(\x27brseat_\x27+aLblSafe2);
|
|
5041
|
+
// Orch → active agent (always)
|
|
5042
|
+
addCommLine(orchEl2, activeSeatEl2, phaseColor, \x275 4\x27, 2.5, 0.75, \x27brDashFlow 1.2s linear infinite\x27);
|
|
5043
|
+
// R2/R3: active reads all done agents → show reading lines
|
|
5044
|
+
if (phase === \x27r2\x27 || phase === \x27r3\x27) {
|
|
5045
|
+
proposals.forEach(function(pp2) {
|
|
5046
|
+
var doneL = pp2.label || pp2.agent;
|
|
5047
|
+
if (doneL === activeLabel) return;
|
|
5048
|
+
if (!parlDoneAgents[doneL]) return;
|
|
5049
|
+
var doneSeat = document.getElementById(\x27brseat_\x27+doneL.replace(/[^a-zA-Z0-9_-]/g,\x27_\x27));
|
|
5050
|
+
addCommLine(doneSeat, activeSeatEl2, \x27#f59e0b\x27, \x274 3\x27, 1.5, 0.5, \x27brDashFlow 1.8s linear infinite\x27);
|
|
5051
|
+
});
|
|
5052
|
+
}
|
|
5053
|
+
}
|
|
5054
|
+
}
|
|
5055
|
+
|
|
4894
5056
|
// Persist across tab navigations
|
|
4895
|
-
if (pb.innerHTML && pb.innerHTML.length < 60000) { _parlPersistHtml = pb.innerHTML; }
|
|
5057
|
+
if (pb.innerHTML && pb.innerHTML.length < 60000) { _parlPersistHtml = _PARL_STAMP + pb.innerHTML; }
|
|
4896
5058
|
|
|
4897
5059
|
}
|
|
4898
5060
|
|
|
@@ -5060,7 +5222,7 @@ async function runStudio() {
|
|
|
5060
5222
|
}
|
|
5061
5223
|
}
|
|
5062
5224
|
if (parlFinal && parlFinal.style.display !== 'none' && parlFinal.innerHTML) {
|
|
5063
|
-
_parlPersistHtml = parlFinal.innerHTML; // persist so tab nav doesn't lose it
|
|
5225
|
+
_parlPersistHtml = _PARL_STAMP + parlFinal.innerHTML; // persist so tab nav doesn't lose it
|
|
5064
5226
|
doScroll(parlFinal);
|
|
5065
5227
|
setTimeout(function(){ doScroll(resEl); }, 2200);
|
|
5066
5228
|
} else if (resEl) {
|
|
@@ -5435,7 +5597,7 @@ function renderStudio(el) {
|
|
|
5435
5597
|
// Persist parliament block across tab navigations
|
|
5436
5598
|
var existingParl = document.getElementById('studioParliamentBlock');
|
|
5437
5599
|
if (existingParl && existingParl.innerHTML.trim()) {
|
|
5438
|
-
_parlPersistHtml = existingParl.innerHTML;
|
|
5600
|
+
_parlPersistHtml = _PARL_STAMP + existingParl.innerHTML;
|
|
5439
5601
|
}
|
|
5440
5602
|
|
|
5441
5603
|
var examplesHtml = STUDIO_EXAMPLES.map(function(ex) {
|
|
@@ -5607,12 +5769,15 @@ function renderStudio(el) {
|
|
|
5607
5769
|
// Restore pipeline from state
|
|
5608
5770
|
renderBuilderPipeline();
|
|
5609
5771
|
// Restore parliament block if it was visible before tab navigation
|
|
5610
|
-
|
|
5772
|
+
// Version stamp check: discard stale HTML from older versions
|
|
5773
|
+
if (_parlPersistHtml && _parlPersistHtml.indexOf(_PARL_STAMP) === 0) {
|
|
5611
5774
|
var parlRestoreEl = document.getElementById('studioParliamentBlock');
|
|
5612
5775
|
if (parlRestoreEl) {
|
|
5613
|
-
parlRestoreEl.innerHTML = _parlPersistHtml;
|
|
5776
|
+
parlRestoreEl.innerHTML = _parlPersistHtml.slice(_PARL_STAMP.length);
|
|
5614
5777
|
parlRestoreEl.style.display = 'block';
|
|
5615
5778
|
}
|
|
5779
|
+
} else {
|
|
5780
|
+
_parlPersistHtml = null;
|
|
5616
5781
|
}
|
|
5617
5782
|
}
|
|
5618
5783
|
|
|
@@ -6159,23 +6324,32 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6159
6324
|
.br-room{position:relative;width:100%;min-height:480px;overflow:hidden;border-radius:12px;box-shadow:0 4px 24px rgba(0,0,0,.18)}
|
|
6160
6325
|
/* Seats rows above/below table */
|
|
6161
6326
|
.br-seats-row{display:flex;flex-wrap:wrap;gap:8px;align-items:flex-end;justify-content:space-around}
|
|
6162
|
-
/*
|
|
6163
|
-
.br-seat{display:flex;flex-direction:column;align-items:center;gap:2px;transition:transform .
|
|
6164
|
-
.br-seat--active{transform:scale(1.
|
|
6165
|
-
.br-seat--done{
|
|
6327
|
+
/* Agent seat — FREE (no box, just emoji + name floating) */
|
|
6328
|
+
.br-seat{display:flex;flex-direction:column;align-items:center;gap:2px;transition:transform .35s;padding:4px 6px;border-radius:10px;background:transparent;border:none;box-shadow:none;min-width:56px;cursor:default}
|
|
6329
|
+
.br-seat--active{transform:scale(1.14) translateY(-5px)}
|
|
6330
|
+
.br-seat--done{opacity:.88}
|
|
6166
6331
|
/* Emoji character */
|
|
6167
|
-
.br-char{font-size:
|
|
6168
|
-
|
|
6169
|
-
|
|
6170
|
-
.br-orch
|
|
6171
|
-
|
|
6172
|
-
.br-orch-
|
|
6173
|
-
|
|
6174
|
-
.br-
|
|
6332
|
+
.br-char{font-size:40px;line-height:1;user-select:none;transition:filter .4s}
|
|
6333
|
+
@keyframes brCharBob{0%,100%{transform:translateY(0)}50%{transform:translateY(-6px)}}
|
|
6334
|
+
/* Orchestrator head — large, no box */
|
|
6335
|
+
.br-orch{display:flex;flex-direction:column;align-items:center;gap:2px;padding:6px 10px;flex-shrink:0;position:relative}
|
|
6336
|
+
.br-orch-inner{display:flex;flex-direction:column;align-items:center;gap:0;position:relative}
|
|
6337
|
+
.br-orch-crown{font-size:22px;line-height:1;display:block;text-align:center;animation:brCrownFloat 2s ease-in-out infinite}
|
|
6338
|
+
@keyframes brCrownFloat{0%,100%{transform:translateY(0) rotate(-4deg)}50%{transform:translateY(-3px) rotate(4deg)}}
|
|
6339
|
+
.br-orch-emoji{font-size:54px;line-height:1;display:block;filter:drop-shadow(0 0 16px #818cf8AA);transition:filter .3s}
|
|
6340
|
+
.br-orch--active .br-orch-emoji{animation:brOrchWalk 1.4s ease-in-out infinite alternate;filter:drop-shadow(0 0 20px #6366f1CC)}
|
|
6341
|
+
@keyframes brOrchWalk{0%{transform:translateX(0) scale(1)}100%{transform:translateX(14px) scale(1.07)}}
|
|
6342
|
+
.br-orch--done .br-orch-emoji{animation:orchBounce .7s ease forwards}
|
|
6343
|
+
.br-orch-speech{font-size:10px;font-weight:800;font-family:var(--mono);padding:4px 10px;border:2px solid #6366f1;border-radius:10px;background:rgba(255,255,255,.95);color:#4338ca;white-space:nowrap;animation:brSpeechPop .7s ease-in-out infinite alternate;pointer-events:none;margin-bottom:4px;box-shadow:0 2px 8px rgba(99,102,241,.25)}
|
|
6344
|
+
@keyframes brSpeechPop{0%{transform:scale(1) rotate(-1deg)}100%{transform:scale(1.06) rotate(1deg)}}
|
|
6345
|
+
.br-orch-label{font-size:9px;font-family:var(--mono);font-weight:800;color:#6366f1;background:rgba(99,102,241,.15);border-radius:6px;padding:2px 8px;margin-top:2px}
|
|
6346
|
+
/* Bubble above agent */
|
|
6347
|
+
.br-bubble{font-size:9px;font-family:var(--mono);padding:4px 9px;border-radius:10px 10px 10px 2px;border:1.5px solid rgba(99,102,241,.35);background:rgba(255,255,255,.96);color:#1e1b4b;line-height:1.4;word-break:break-word;max-width:120px;white-space:normal;box-shadow:0 2px 8px rgba(0,0,0,.12);margin-bottom:3px}
|
|
6175
6348
|
/* Agent name pill */
|
|
6176
|
-
.br-seat-name{font-size:9px;font-family:var(--mono);font-weight:
|
|
6177
|
-
.br-seat--active .br-seat-name{color:#4338ca}
|
|
6349
|
+
.br-seat-name{font-size:9px;font-family:var(--mono);font-weight:600;color:#374151;text-align:center;white-space:normal;word-break:break-word;max-width:100px;line-height:1.3;margin-top:1px;background:rgba(255,255,255,.75);border-radius:4px;padding:1px 4px;transition:color .3s,font-weight .2s;backdrop-filter:blur(2px)}
|
|
6350
|
+
.br-seat--active .br-seat-name{color:#4338ca;font-weight:800}
|
|
6178
6351
|
.br-seat--done .br-seat-name{color:#111827}
|
|
6352
|
+
@keyframes brDotFloat{0%,100%{transform:translateY(0)}50%{transform:translateY(-5px)}}
|
|
6179
6353
|
/* Convergence */
|
|
6180
6354
|
.br-convergence{margin-top:10px;padding:8px 12px;background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.2);border-radius:8px}
|
|
6181
6355
|
.br-conv-bar-outer{height:4px;background:rgba(99,102,241,.15);border-radius:4px;overflow:hidden;margin-bottom:6px}
|
|
@@ -6233,10 +6407,13 @@ input:focus,textarea:focus{border-color:var(--green3)}
|
|
|
6233
6407
|
.iso-scene{background:#f0ede6;cursor:default;max-width:100%;overflow-x:auto;box-shadow:0 4px 24px rgba(0,0,0,.18);border-radius:12px;overflow:hidden}
|
|
6234
6408
|
.iso-station{display:flex;flex-direction:column;align-items:center;gap:3px;cursor:pointer;transition:filter .2s,transform .2s;padding:8px 4px;border-radius:12px;border:1.5px solid transparent;position:relative}
|
|
6235
6409
|
.iso-station:hover{filter:brightness(1.06);transform:translateY(-2px)}
|
|
6236
|
-
.iso-
|
|
6237
|
-
|
|
6238
|
-
|
|
6410
|
+
.iso-char-mover{position:relative;transition:transform .3s}
|
|
6411
|
+
.iso-char-mover.iso-orch-walking{animation:orchWalkGrid 1.8s ease-in-out infinite alternate}
|
|
6412
|
+
@keyframes orchWalkGrid{0%{transform:translateX(0) scale(1)}100%{transform:translateX(18px) scale(1.05)}}
|
|
6413
|
+
.iso-char-mover.iso-orch-done{animation:orchBounce .7s ease forwards}
|
|
6239
6414
|
@keyframes orchBounce{0%{transform:scale(1)}40%{transform:scale(1.18) translateY(-6px)}100%{transform:scale(1)}}
|
|
6415
|
+
.iso-fly-doc{position:absolute;top:-8px;right:-4px;font-size:16px;animation:flyDocSpin 1.2s ease-in-out infinite;z-index:20;pointer-events:none}
|
|
6416
|
+
@keyframes flyDocSpin{0%{transform:rotate(-15deg) translateY(0);opacity:.7}50%{transform:rotate(10deg) translateY(-8px);opacity:1}100%{transform:rotate(-15deg) translateY(0);opacity:.7}}
|
|
6240
6417
|
.iso-desk{width:90%;height:16px;background:linear-gradient(180deg,#d4a448 0%,#b8832a 100%);border-radius:4px 4px 2px 2px;box-shadow:0 4px 0 #8a5e18,0 6px 10px rgba(0,0,0,.3);border-top:2px solid #e8c060;position:relative;margin-top:4px}
|
|
6241
6418
|
.iso-desk::after{content:'';position:absolute;bottom:-4px;left:8px;right:8px;height:4px;background:#7a5010;border-radius:0 0 3px 3px}
|
|
6242
6419
|
.iso-monitor{width:56px;height:40px;background:#12101e;border:2px solid #3a3070;border-radius:5px;display:flex;align-items:center;justify-content:center;position:relative;margin-bottom:-2px}
|