@wcstack/devtools 1.33.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.ja.md CHANGED
@@ -31,16 +31,15 @@ auto エントリは `<wcs-devtools>` を定義し、ページに無ければ `<
31
31
  1 つ挿入する。配置や属性を制御したい場合は自分でタグを書く:
32
32
 
33
33
  ```html
34
- <wcs-devtools open dock="right" hotkey="Ctrl+Shift+X" buffer="1000"
35
- hidden-states="analytics"></wcs-devtools>
34
+ <wcs-devtools open dock="right" hotkey="Ctrl+Shift+X" buffer="1000"></wcs-devtools>
36
35
  ```
37
36
 
38
37
  ## ペイン
39
38
 
40
39
  | ペイン | 内容 |
41
40
  |---|---|
42
- | **State** | 各 `<wcs-state>`(ランタイム source 単位)のトップレベルキー、配列/オブジェクトの展開、computed getter。値クリックでインライン編集 — 書き込みは通常のリアクティブパイプライン(set トラップ → 更新バッチ → DOM)を通るため、アプリコードが書いたのと同じようにページが反応する。**パス**クリックで束縛ノードをハイライト。 |
43
- | **Wiring** | ライブ binding 台帳: binding ごとの `property ← path@state` 行と型バッジ(`text` / `prop` / `for` / …)。**⌖ pick** でページ要素をクリックするとその要素の配線だけに絞れる。行クリックで束縛ノードをハイライト。 |
41
+ | **State** | 各ルート state ツリー(root node ごとに 1 本・ラベルはルート由来 — v2 に名前次元は無い)のトップレベルキー、配列/オブジェクトの展開、computed getter。値クリックでインライン編集 — 書き込みは通常のリアクティブパイプライン(set トラップ → 更新バッチ → DOM)を通るため、アプリコードが書いたのと同じようにページが反応する。**パス**クリックで束縛ノードをハイライト。 |
42
+ | **Wiring** | ライブ binding 台帳: binding ごとの `property ← path` 行と型バッジ(`text` / `prop` / `for` / …)。**⌖ pick** でページ要素をクリックするとその要素の配線だけに絞れる。行クリックで束縛ノードをハイライト。 |
44
43
  | **Timeline** | ring buffer(既定 500 件): `write`(旧値が取れた場合は併記)、`batch`(drain ごとの dedup 済み更新アドレス)、`command` / `event` トークン発火(引数要約 + 購読者数 — **購読者ゼロの空撃ちには警告バッジ**。whenDefined 前配線レースの検出に効く)、state 要素の登録/解除。⏸ で一時停止、🗑 でクリア。 |
45
44
 
46
45
  ## 属性
@@ -51,7 +50,6 @@ auto エントリは `<wcs-devtools>` を定義し、ページに無ければ `<
51
50
  | `dock` | `bottom` | `bottom` または `right` |
52
51
  | `hotkey` | `Alt+Shift+D` | 開閉ショートカット。`none` で無効 |
53
52
  | `buffer` | `500` | タイムライン ring buffer 件数(接続時に読む) |
54
- | `hidden-states` | — | 非表示にする state 名(カンマ区切り。`wcs-devtools` 始まりは常に非表示) |
55
53
 
56
54
  ## 遅延アタッチ
57
55
 
package/README.md CHANGED
@@ -33,16 +33,15 @@ does not already contain one. To control placement/attributes, write the tag
33
33
  yourself:
34
34
 
35
35
  ```html
36
- <wcs-devtools open dock="right" hotkey="Ctrl+Shift+X" buffer="1000"
37
- hidden-states="analytics"></wcs-devtools>
36
+ <wcs-devtools open dock="right" hotkey="Ctrl+Shift+X" buffer="1000"></wcs-devtools>
38
37
  ```
39
38
 
40
39
  ## Panes
41
40
 
42
41
  | Pane | What it shows |
43
42
  |---|---|
44
- | **State** | Every `<wcs-state>` (per runtime source): top-level keys, expandable arrays/objects, computed getters. Click a value to edit it inline — the write goes through the normal reactive pipeline (set trap → update batch → DOM), so the page reacts exactly as if application code had written it. Click a **path** to highlight the DOM nodes bound to it. |
45
- | **Wiring** | The live binding ledger: `property ← path@state` rows per binding, with type badges (`text` / `prop` / `for` / …). Use **⌖ pick** to click a page element and see only its bindings. Rows highlight their bound nodes on click. |
43
+ | **State** | Every root state tree (one per root node, labelled by its root — v2 has no name dimension): top-level keys, expandable arrays/objects, computed getters. Click a value to edit it inline — the write goes through the normal reactive pipeline (set trap → update batch → DOM), so the page reacts exactly as if application code had written it. Click a **path** to highlight the DOM nodes bound to it. |
44
+ | **Wiring** | The live binding ledger: `property ← path` rows per binding, with type badges (`text` / `prop` / `for` / …). Use **⌖ pick** to click a page element and see only its bindings. Rows highlight their bound nodes on click. |
46
45
  | **Timeline** | A ring buffer (default 500) of `write` (with old value when available), `batch` (deduplicated update addresses per drain), `command` / `event` token emissions (with argument summaries and subscriber counts — **zero-subscriber emissions get a warning badge**, catching wired-before-`whenDefined` races), and state element registration. ⏸ pauses, 🗑 clears. |
47
46
 
48
47
  ## Attributes
@@ -53,7 +52,6 @@ yourself:
53
52
  | `dock` | `bottom` | `bottom` or `right` |
54
53
  | `hotkey` | `Alt+Shift+D` | Toggle shortcut; `none` disables |
55
54
  | `buffer` | `500` | Timeline ring-buffer capacity (read at connect) |
56
- | `hidden-states` | — | Comma-separated state names to hide (names starting with `wcs-devtools` are always hidden) |
57
55
 
58
56
  ## Late attach
59
57
 
package/dist/auto.min.js CHANGED
@@ -1,2 +1,2 @@
1
- const e="__WCSTACK_DEVTOOLS_HOOK__";function t(){const t=globalThis,n=t[e];if(void 0!==n)return 1!==n.version&&console.warn(`[wcstack/devtools] hook registry version mismatch: found ${n.version}, expected 1. Keeping the existing registry (first-wins).`),n;const i=function(){const e=new Map,t=new Set,n=e=>{if(0===t.size)return void e._setSink(null);const n=e.id;e._setSink(e=>{for(const i of t)i.onEvent?.(n,e)})};return{version:1,sources:e,register(i){if(!e.has(i.id)){e.set(i.id,i),n(i);for(const e of t)e.onSourceRegistered?.(i)}},unregister(n){const i=e.get(n);if(void 0!==i){i._setSink(null),e.delete(n);for(const e of t)e.onSourceUnregistered?.(n)}},addListener(i){t.add(i);for(const t of e.values())n(t),i.onSourceRegistered?.(t);return()=>{if(t.delete(i))for(const t of e.values())n(t)}}}}();return t[e]=i,i}const n=80;function i(e){const t=e.constructor,n=t?.name;return"string"==typeof n&&n.length>0?n:"Object"}function s(e,t=2){switch(typeof e){case"string":return`"${e.length>n?e.slice(0,n)+"…":e}"`;case"number":case"boolean":case"bigint":return String(e);case"symbol":return e.toString();case"undefined":return"undefined";case"function":return"[[Function]]"}if(null===e)return"null";const o=e;if(Array.isArray(o)){if(t<=0)return`[[Array(${o.length})]]`;const e=o.slice(0,3).map(e=>s(e,t-1)),n=o.length>3?`, …(${o.length})`:"";return`[${e.join(", ")}${n}]`}if(function(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(o)){if(t<=0)return"[[Object]]";const e=Object.keys(o),n=e.slice(0,3).map(e=>`${e}: ${s(o[e],t-1)}`),i=e.length>3?`, …(${e.length})`:"";return`{${n.join(", ")}${i}}`}return`[[${i(o)}]]`}function o(e){if(null!==e&&"object"==typeof e){const{name:t,message:s}=e;if("string"==typeof s){const o="string"==typeof t&&t.length>0?t:i(e),r=s.length>n?s.slice(0,n)+"…":s;return r.length>0?`${o}: ${r}`:o}}return s(e,1)}function r(e){if(0===e.length)return"";const t=e.slice(0,3).map(e=>{const t=s(e,1);return t.length>n?t.slice(0,n)+"…":t}),i=e.length>3?`, …(${e.length})`:"";return`${t.join(", ")}${i}`}const a=String.fromCharCode(0);function d(e,t){return e+a+t}function c(e,t,n){return e+a+t+a+n}function l(e,t,n){return d(e,t)+a+n}function h(e,t,n,i){return void 0===i?{stateName:e,kind:t,name:n,status:"never",count:0,note:null}:i.zeroSubscriberCount===i.count?{stateName:e,kind:t,name:n,status:"emitted-unheard",count:i.count,note:`all ${i.count} emit(s) had 0 subscribers`}:{stateName:e,kind:t,name:n,status:"emitted",count:i.count,note:i.zeroSubscriberCount>0?`${i.zeroSubscriberCount}/${i.count} emit(s) had 0 subscribers`:null}}class u{_timelineCapacity;_hiddenStateNames;_removeListener=null;_sources=new Map;_roster=new Map;_wiringByPathKey=new Map;_wiringEntryByBinding=new WeakMap;_timeline=[];_seq=0;_paused=!1;_changeListeners=new Set;_observingSince=null;_watchFiredCounts=new Map;_tokenEmitCounts=new Map;_everAttachedKeys=new Set;constructor(e){this._timelineCapacity=e?.timelineCapacity??500,this._hiddenStateNames=new Set(e?.hiddenStateNames??[])}get connected(){return null!==this._removeListener}get paused(){return this._paused}set paused(e){this._paused=e}isHiddenStateName(e){return null!==e&&(e.startsWith("wcs-devtools")||this._hiddenStateNames.has(e))}connect(){if(null!==this._removeListener)return;this._observingSince=performance.now();const e=t();this._removeListener=e.addListener({onSourceRegistered:e=>{this._sources.set(e.id,e),this._refreshRosterOf(e),this._notify("sources")},onSourceUnregistered:e=>{this._sources.delete(e),this._roster.delete(e),this._notify("sources"),this._notify("roster")},onEvent:(e,t)=>{this._ingest(e,t)}})}disconnect(){null!==this._removeListener&&(this._removeListener(),this._removeListener=null,this._sources.clear(),this._roster.clear(),this._wiringByPathKey.clear(),this._wiringEntryByBinding=new WeakMap,this._observingSince=null,this._watchFiredCounts.clear(),this._tokenEmitCounts.clear(),this._everAttachedKeys.clear(),this._notify("sources"),this._notify("roster"),this._notify("wiring"),this._notify("coverage"))}get observingSince(){return this._observingSince}onChange(e){return this._changeListeners.add(e),()=>{this._changeListeners.delete(e)}}getSources(){return[...this._sources.values()]}getRoster(){const e=[];for(const t of this._roster.values())e.push(...t);return e}refreshRoster(){for(const e of this._sources.values())this._refreshRosterOf(e);this._notify("roster")}getTimeline(){return this._timeline}clearTimeline(){this._timeline=[],this._notify("timeline")}getWiringForPath(e,t){const n=this._wiringByPathKey.get(d(e,t));return void 0===n?[]:this._collectAlive(n)}getAllWiring(){const e=[];for(const t of this._wiringByPathKey.values())e.push(...this._collectAlive(t));return e}getWiringForNode(e){const t=[];for(const n of this._wiringByPathKey.values())for(const i of this._collectAlive(n)){const n=i.bindingRef.deref();(n.node===e||n.replaceNode===e||e.contains(n.node)||e.contains(n.replaceNode))&&t.push(i)}return t}getCanonicalDeclared(){let e=!1;const t=[],n=new Set;for(const[i,s]of this._sources){if("function"!=typeof s.getDeclaredBindings)continue;e=!0;const o=new Set;for(const e of this._roster.get(i)??[])o.add(e.rootNode);for(const e of o)for(const i of s.getDeclaredBindings(e)){if(this.isHiddenStateName(i.stateName))continue;const e=[i.stateName,i.statePathName,i.propName,i.bindingType,i.origin,i.raw].join(a);n.has(e)||(n.add(e),t.push(i))}}return e?t:null}getCoverageReport(){const e=[];for(const t of this.getRoster()){const n=t.summary;for(const i of n.watchPaths??[]){const s=this._watchFiredCounts.get(d(t.name,i))??0;if(s>0){e.push({stateName:t.name,kind:"watch",name:i,status:"fired",count:s,note:null});continue}const o=void 0!==n.keyedListPaths;let r=null;for(let e=i.indexOf(".*");-1!==e;e=i.indexOf(".*",e+2)){const t=i.slice(0,e);if(!(n.paths.list.has(t)||(n.keyedListPaths?.has(t)??!1))){r=t;break}}null===r?e.push({stateName:t.name,kind:"watch",name:i,status:"never",count:0,note:null}):e.push({stateName:t.name,kind:"watch",name:i,status:"prerequisite-missing",count:0,note:o?`list "${r}" has no for binding and no $listKeys declaration — list writes never reach its rows (only explicit-index writes can fire this watch)`:`no for binding observed for list "${r}" (a $listKeys declaration would still let list writes fire it)`})}for(const i of n.commandTokenNames)e.push(h(t.name,"command",i,this._tokenEmitCounts.get(c(t.name,"command",i))));for(const i of n.eventTokenNames)e.push(h(t.name,"eventToken",i,this._tokenEmitCounts.get(c(t.name,"event",i))))}const t=this.getCanonicalDeclared();if(null!==t){const n=new Set;for(const i of t){if("for"===i.bindingType||"if"===i.bindingType||"elseif"===i.bindingType||"else"===i.bindingType)continue;if(i.propName.startsWith("eventToken."))continue;const t=l(i.stateName,i.statePathName,i.propName);if(n.has(t))continue;n.add(t);const s=this._everAttachedKeys.has(t);e.push({stateName:i.stateName,kind:"binding",name:`${i.propName} ← ${i.statePathName}`,status:s?"attached":"never-attached",count:s?1:0,note:"fragment"===i.origin?"template interior (attaches when rows materialize)":null})}}return e}keysOf(e){const t=this._sources.get(e.sourceId);return void 0===t||"function"!=typeof t.keys?[]:t.keys(e.name,e.rootNode)}readValue(e,t,n){const i=this._sources.get(e.sourceId);if(void 0!==i)return i.read(e.name,e.rootNode,t,n)}writeValue(e,t,n,i){const s=this._sources.get(e.sourceId);void 0!==s&&s.write(e.name,e.rootNode,t,n,i)}_notify(e){for(const t of this._changeListeners)t(e)}_refreshRosterOf(e){const t=[];for(const n of e.getStateElements())this.isHiddenStateName(n.name)||t.push({sourceId:e.id,name:n.name,rootNode:n.rootNode,summary:n});this._roster.set(e.id,t)}_collectAlive(e){const t=[];for(const n of e)void 0!==n.bindingRef.deref()?t.push(n):e.delete(n);return t}_appendTimeline(e){if(this._paused)return;this._timeline.push({...e,seq:this._seq++,time:performance.now()});const t=this._timeline.length-this._timelineCapacity;t>0&&this._timeline.splice(0,t),this._notify("timeline")}_labelOf(e){const t=e.listIndex?.indexes,n=e.absolutePathInfo.pathInfo.path;return void 0!==t?`${n}[${t.join(",")}]`:n}_ingest(e,t){switch(t.type){case"state:element-registered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-registered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:element-unregistered":{if(this.isHiddenStateName(t.name))return;const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-unregistered",stateName:t.name,label:t.name,detail:"",subscriberCount:null})}case"state:write":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.hasOldValue?`${s(t.value)} (was ${s(t.oldValue)})`:s(t.value);return void this._appendTimeline({sourceId:e,kind:"write",stateName:n,label:this._labelOf(t.absoluteAddress),detail:i,subscriberCount:null})}case"state:update-batch":{const n=[];let i=0;for(const e of t.addresses)this.isHiddenStateName(e.absolutePathInfo.stateName)||(i++,n.length<3&&n.push(this._labelOf(e)));if(0===i)return;const s=i>n.length?`, …(${i})`:"";return void this._appendTimeline({sourceId:e,kind:"batch",stateName:null,label:`${i} address${1===i?"":"es"}`,detail:`${n.join(", ")}${s}`,subscriberCount:null})}case"state:binding-added":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;const i=t.absoluteAddress.absolutePathInfo.pathInfo.path,s=d(n,i);let o=this._wiringByPathKey.get(s);void 0===o&&(o=new Set,this._wiringByPathKey.set(s,o));const r={sourceId:e,stateName:n,path:i,propName:t.binding.propName,bindingType:t.binding.bindingType,bindingRef:new WeakRef(t.binding)};return o.add(r),this._wiringEntryByBinding.set(t.binding,r),this._everAttachedKeys.add(l(n,i,t.binding.propName)),this._notify("wiring"),void this._notify("coverage")}case"state:binding-removed":{const e=this._wiringEntryByBinding.get(t.binding);if(void 0===e)return;this._wiringEntryByBinding.delete(t.binding);const n=d(e.stateName,e.path),i=this._wiringByPathKey.get(n);return void 0!==i&&(i.delete(e),0===i.size&&this._wiringByPathKey.delete(n)),void this._notify("wiring")}case"state:binding-cleared":{const e=d(t.absoluteAddress.absolutePathInfo.stateName,t.absoluteAddress.absolutePathInfo.pathInfo.path);return void(this._wiringByPathKey.delete(e)&&this._notify("wiring"))}case"state:token-emit":if(this.isHiddenStateName(t.stateName))return;if(null!==t.stateName){const e=c(t.stateName,t.kind,t.tokenName),n=this._tokenEmitCounts.get(e);void 0===n?this._tokenEmitCounts.set(e,{count:1,zeroSubscriberCount:0===t.subscriberCount?1:0}):(n.count+=1,0===t.subscriberCount&&(n.zeroSubscriberCount+=1)),this._notify("coverage")}return void this._appendTimeline({sourceId:e,kind:t.kind,stateName:t.stateName,label:t.tokenName,detail:r(t.args),subscriberCount:t.subscriberCount});case"state:watch-fired":{if(this.isHiddenStateName(t.stateName))return;const e=d(t.stateName,t.path);return this._watchFiredCounts.set(e,(this._watchFiredCounts.get(e)??0)+1),void this._notify("coverage")}case"state:watch-error":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:"watch-error",stateName:t.stateName,label:t.path,detail:`${t.phase}: ${o(t.error)}`,subscriberCount:null});case"state:watch-chain-limit":return void this._appendTimeline({sourceId:e,kind:"watch-chain-limit",stateName:null,label:`depth > ${t.maxDepth}`,detail:t.paths.join(", "),subscriberCount:null});case"state:path-unresolved":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:"path-unresolved",stateName:t.stateName,label:t.path,detail:`${t.source}: "${t.missingSegment}" is not declared`,subscriberCount:null});case"state:binding-apply-error":if(this.isHiddenStateName(t.stateName))return;return void this._appendTimeline({sourceId:e,kind:"binding-apply-error",stateName:t.stateName,label:t.path,detail:`${t.bindingType}: ${o(t.error)}`,subscriberCount:null});case"propagation:suppressed":return void this._appendTimeline({sourceId:e,kind:"propagation-suppressed",stateName:null,label:t.member,detail:`${t.reason} (tx ${t.transactionId}, edge ${t.edgeId})`,subscriberCount:null});case"propagation:coalesced":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;return void this._appendTimeline({sourceId:e,kind:"propagation-coalesced",stateName:n,label:this._labelOf(t.absoluteAddress),detail:`tx ${t.droppedTransactionId} dropped (winner tx ${t.winnerTransactionId})`,subscriberCount:null})}case"propagation:hop-limit":{const n=t.absoluteAddress.absolutePathInfo.stateName;if(this.isHiddenStateName(n))return;return void this._appendTimeline({sourceId:e,kind:"propagation-hop-limit",stateName:n,label:this._labelOf(t.absoluteAddress),detail:`hop ${t.hop} (tx ${t.transactionId})`,subscriberCount:null})}case"contract:drift":{const n=void 0!==t.member?`: ${t.member}`:"",i="event-mismatch"===t.reason?` (sidecar ${t.sidecarEvent??"?"} / live ${t.liveEvent??"?"})`:"";return void this._appendTimeline({sourceId:e,kind:"contract-drift",stateName:null,label:t.tag,detail:`${t.reason}${n}${i}`,subscriberCount:null})}case"contract:manifest-read":case"contract:unsupported-extension":return}}}const p=["wcs-text","wcs-for","wcs-if","wcs-elseif","wcs-else"];function m(e,t,n){const i=t.trim();if(0===i.length)return null;const s=i.indexOf(":");if(s<0)return null;const o=i.slice(0,s).trim(),r=i.slice(s+1).trim();if(0===o.length||0===r.length)return null;const[a,...d]=r.split("|").map(e=>e.trim());let c=a,l="default";const h=a.lastIndexOf("@");return h>0&&(c=a.slice(0,h).trim(),l=a.slice(h+1).trim()),{element:e,propName:o,path:c,stateName:l,filters:d.filter(e=>e.length>0),origin:n,raw:i}}class g extends HTMLElement{static get observedAttributes(){return["open","dock","hotkey"]}_core=null;_removeCoreListener=null;_panel=null;_badge=null;_stateSelect=null;_paneElements={};_wiringView="wiring";_highlightLayer=null;_dirtyPanes=new Set;_renderScheduled=!1;_selectedRosterKey=null;_selectedPath=null;_pickedNode=null;_pickMode=!1;_expanded=new Set;_hotkeyHandler=null;_pickHandler=null;get core(){return this._core}connectedCallback(){if(document.documentElement.hasAttribute("data-wcs-server"))return;null===this.shadowRoot&&this._buildShadow();const e=Number(this.getAttribute("buffer")??""),t=(this.getAttribute("hidden-states")??"").split(",").map(e=>e.trim()).filter(e=>e.length>0);this._core=new u({timelineCapacity:Number.isFinite(e)&&e>0?e:void 0,hiddenStateNames:t}),this._removeCoreListener=this._core.onChange(e=>{"roster"===e||"sources"===e?(this._markDirty("state"),this._markDirty("wiring")):"wiring"===e?this._markDirty("wiring"):"coverage"===e?"coverage"===this._wiringView&&this._markDirty("wiring"):this._markDirty("timeline")}),this._core.connect(),this._applyDock(),this._applyOpen(),this._installHotkey(),this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline")}disconnectedCallback(){this._removeCoreListener?.(),this._removeCoreListener=null,this._core?.disconnect(),this._core=null,this._uninstallHotkey(),this._exitPickMode()}attributeChangedCallback(e){null!==this.shadowRoot&&("open"===e?this._applyOpen():"dock"===e?this._applyDock():"hotkey"===e&&(this._uninstallHotkey(),this._installHotkey()))}__flushRenderForTest(){this._renderDirty()}_buildShadow(){const e=this.attachShadow({mode:"open"}),t=document.createElement("style");t.textContent='\n:host {\n all: initial;\n position: fixed;\n z-index: 2147483647;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n inset: auto 0 0 auto;\n}\n* { box-sizing: border-box; }\n.badge {\n position: fixed;\n right: 12px;\n bottom: 12px;\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border: 1px solid #2b4f78;\n background: #10263f;\n color: #9fd0ff;\n font-weight: 700;\n cursor: pointer;\n}\n.panel {\n position: fixed;\n display: flex;\n flex-direction: column;\n background: #0d1b2a;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n box-shadow: 0 0 24px rgba(0,0,0,.5);\n}\n.panel.dock-bottom { left: 0; right: 0; bottom: 0; height: 45vh; }\n.panel.dock-right { top: 0; right: 0; bottom: 0; width: 420px; }\n.panel[hidden] { display: none; }\nheader {\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 6px 8px;\n border-bottom: 1px solid #2b4f78;\n background: #10263f;\n}\nheader .title { font-weight: 700; color: #9fd0ff; margin-right: 4px; }\nheader select, header button {\n font: inherit;\n background: #16324f;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n border-radius: 4px;\n padding: 2px 8px;\n cursor: pointer;\n}\nheader button[aria-pressed="true"] { background: #2b5d8f; }\nheader .spacer { flex: 1; }\n.panes { display: flex; flex: 1; min-height: 0; }\n.pane { flex: 1; min-width: 0; overflow: auto; padding: 6px 8px; border-right: 1px solid #1d3a5c; }\n.pane:last-child { border-right: none; }\n.pane h3 {\n margin: 0 0 6px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .08em;\n color: #7ba7d4;\n}\n.tree-row { display: flex; gap: 6px; padding: 1px 0; align-items: baseline; white-space: nowrap; }\n.tree-row .toggle { width: 14px; cursor: pointer; color: #7ba7d4; user-select: none; }\n.tree-row .key { color: #9fd0ff; cursor: pointer; }\n.tree-row .value { color: #ffd9a0; overflow: hidden; text-overflow: ellipsis; }\n.tree-row .value.editable { cursor: pointer; }\n.tree-row input { font: inherit; background: #16324f; color: #ffd9a0; border: 1px solid #2b4f78; }\n.badge-tag {\n display: inline-block;\n padding: 0 4px;\n border-radius: 3px;\n font-size: 10px;\n background: #26456a;\n color: #a8c6e8;\n}\n.badge-tag.warn { background: #6a3326; color: #ffb3a0; }\n.badge-tag.declared { background: #4a4426; color: #efe3a0; }\n.wiring-row, .timeline-row { padding: 1px 0; white-space: nowrap; }\n.wiring-row .prop { color: #b7f0c0; }\n.wiring-row .path { color: #9fd0ff; }\n.timeline-row .t { color: #6f88a3; }\n.timeline-row .label { color: #9fd0ff; }\n.timeline-row .detail { color: #ffd9a0; }\n.timeline-row .kind { display: inline-block; min-width: 52px; text-align: center; }\n.empty { color: #6f88a3; font-style: italic; padding: 4px 0; }\n.notice { color: #efe3a0; padding: 2px 0 6px; }\n.notice button { font: inherit; margin-left: 6px; cursor: pointer; }\n.wiring-row .detail { color: #6f88a3; }\n.wiring-tabs { padding: 0 0 4px; }\n.wiring-tabs button { font: inherit; cursor: pointer; margin-right: 4px; opacity: 0.6; }\n.wiring-tabs button.active { opacity: 1; font-weight: bold; }\n.hl-box {\n position: fixed;\n pointer-events: none;\n border: 1px solid #58c2ff;\n background: rgba(88,194,255,.18);\n}\n',e.append(t);const n=document.createElement("button");n.className="badge",n.title="wcstack DevTools",n.textContent="WCS",n.addEventListener("click",()=>this.toggle()),e.append(n),this._badge=n;const i=document.createElement("div");i.className="panel dock-bottom",i.hidden=!0;const s=document.createElement("header"),o=document.createElement("span");o.className="title",o.textContent="wcstack devtools",s.append(o);const r=document.createElement("select");r.title="state element",r.addEventListener("change",()=>{this._selectedRosterKey=r.value||null,this._selectedPath=null,this._expanded.clear(),this._markDirty("state"),this._markDirty("wiring")}),s.append(r),this._stateSelect=r;const a=this._headerButton(s,"⌖ pick","pick a page element");a.addEventListener("click",()=>{this._pickMode?this._exitPickMode():this._enterPickMode(),a.setAttribute("aria-pressed",String(this._pickMode))}),a.dataset.role="pick";const d=this._headerButton(s,"⏸","pause timeline");d.addEventListener("click",()=>{const e=this._core;null!==e&&(e.paused=!e.paused,d.setAttribute("aria-pressed",String(e.paused)))}),d.dataset.role="pause";const c=this._headerButton(s,"🗑","clear timeline");c.addEventListener("click",()=>{this._core?.clearTimeline()}),c.dataset.role="clear";const l=document.createElement("span");l.className="spacer",s.append(l);const h=this._headerButton(s,"dock","toggle dock position");h.addEventListener("click",()=>{const e="bottom"===(this.getAttribute("dock")??"bottom")?"right":"bottom";this.setAttribute("dock",e)}),h.dataset.role="dock";const u=this._headerButton(s,"×","close");u.addEventListener("click",()=>this.toggle(!1)),u.dataset.role="close",i.append(s);const p=document.createElement("div");p.className="panes";for(const[e,t]of[["state","State"],["wiring","Wiring"],["timeline","Timeline"]]){const n=document.createElement("section");n.className=`pane pane-${e}`;const i=document.createElement("h3");i.textContent=t;const s=document.createElement("div");s.className="pane-body",n.append(i,s),p.append(n),this._paneElements[e]=s}i.append(p),e.append(i),this._panel=i;const m=document.createElement("div");m.className="hl-layer",e.append(m),this._highlightLayer=m}_headerButton(e,t,n){const i=document.createElement("button");return i.textContent=t,i.title=n,i.setAttribute("aria-pressed","false"),e.append(i),i}get open(){return this.hasAttribute("open")}toggle(e){e??!this.open?this.setAttribute("open",""):this.removeAttribute("open")}_applyOpen(){this._panel.hidden=!this.open,this._badge.hidden=this.open,this.open&&(this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline"))}_applyDock(){const e="right"===this.getAttribute("dock")?"right":"bottom";this._panel.classList.toggle("dock-right","right"===e),this._panel.classList.toggle("dock-bottom","bottom"===e)}_installHotkey(){const e=this.getAttribute("hotkey")??"Alt+Shift+D";if("none"===e)return;const t=e.split("+").map(e=>e.trim().toLowerCase()),n=t[t.length-1],i=t.includes("alt"),s=t.includes("shift"),o=t.includes("ctrl"),r=t.includes("meta");this._hotkeyHandler=e=>{e.key.toLowerCase()===n&&e.altKey===i&&e.shiftKey===s&&e.ctrlKey===o&&e.metaKey===r&&(e.preventDefault(),this.toggle())},window.addEventListener("keydown",this._hotkeyHandler)}_uninstallHotkey(){null!==this._hotkeyHandler&&(window.removeEventListener("keydown",this._hotkeyHandler),this._hotkeyHandler=null)}_enterPickMode(){this._pickMode=!0,this._pickHandler=e=>{const t=e.target;t.getRootNode()!==this.shadowRoot&&t!==this&&(e.preventDefault(),e.stopPropagation(),this._pickedNode=t,this._selectedPath=null,this._exitPickMode(),this._markDirty("wiring"))},document.addEventListener("click",this._pickHandler,{capture:!0})}_exitPickMode(){null!==this._pickHandler&&(document.removeEventListener("click",this._pickHandler,{capture:!0}),this._pickHandler=null),this._pickMode=!1;const e=this.shadowRoot?.querySelector('button[data-role="pick"]');e?.setAttribute("aria-pressed","false")}_markDirty(e){this._dirtyPanes.add(e),this._renderScheduled||(this._renderScheduled=!0,requestAnimationFrame(()=>{this._renderDirty()}))}_renderDirty(){if(this._renderScheduled=!1,null===this._core||null===this.shadowRoot)return void this._dirtyPanes.clear();const e=this._dirtyPanes;this._dirtyPanes=new Set,e.has("state")&&this._renderStatePane(),e.has("wiring")&&this._renderWiringPane(),e.has("timeline")&&this._renderTimelinePane()}_rosterKey(e){return`${e.sourceId}:${e.name}`}_selectedRoster(){const e=this._core.getRoster();if(0===e.length)return null;return e.find(e=>this._rosterKey(e)===this._selectedRosterKey)??e[0]}_renderStatePane(){const e=this._core,t=this._paneElements.state,n=this._stateSelect,i=e.getRoster(),s=this._selectedRoster();if(n.replaceChildren(...i.map(e=>{const t=document.createElement("option");return t.value=this._rosterKey(e),t.textContent=`${e.name} (${e.sourceId.slice(0,12)})`,t.selected=null!==s&&this._rosterKey(e)===this._rosterKey(s),t})),t.replaceChildren(),null===s)return void t.append(this._emptyRow("no <wcs-state> elements observed"));this._selectedRosterKey=this._rosterKey(s);const o=e.keysOf(s);if(0!==o.length)for(const e of o)this._renderTreeNode(t,s,{path:e,indexes:[]},e,0);else t.append(this._emptyRow("no readable keys (runtime without keys() API?)"))}_renderTreeNode(e,t,n,i,o){const r=this._core;let a,d=!0;try{a=r.readValue(t,n.path,n.indexes)}catch{d=!1}const c=document.createElement("div");c.className="tree-row",c.style.paddingLeft=14*o+"px";const l=d&&function(e){if(Array.isArray(e))return!0;if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(a),h=function(e){return`${e.path}#${e.indexes.join(",")}`}(n),u=l&&this._expanded.has(h),p=document.createElement("span");p.className="toggle",p.textContent=l?u?"▾":"▸":"",l&&p.addEventListener("click",()=>{this._expanded.has(h)?this._expanded.delete(h):this._expanded.add(h),this._markDirty("state")}),c.append(p);const m=document.createElement("span");m.className="key",m.textContent=`${i}:`,m.title=n.path,m.addEventListener("click",()=>{this._selectedPath=n.path,this._pickedNode=null,this._markDirty("wiring"),this._highlightPath(t,n.path)}),c.append(m);const g=document.createElement("span");if(g.className="value",d){g.textContent=s(a,1);(null===a||"object"!=typeof a)&&"function"!=typeof a&&(g.classList.add("editable"),g.title="click to edit",g.addEventListener("click",()=>{this._beginEdit(c,g,t,n,a)}))}else g.textContent="(unreadable getter)";if(c.append(g),e.append(c),u)if(Array.isArray(a)){const i=Math.min(a.length,20);for(let s=0;s<i;s++)this._renderTreeNode(e,t,{path:`${n.path}.*`,indexes:[...n.indexes,s]},`[${s}]`,o+1);if(a.length>i){const t=this._emptyRow(`…(${a.length} items)`);t.style.paddingLeft=14*(o+1)+"px",e.append(t)}}else for(const i of Object.keys(a))this._renderTreeNode(e,t,{path:`${n.path}.${i}`,indexes:n.indexes},i,o+1)}_beginEdit(e,t,n,i,s){const o=document.createElement("input");o.value="string"==typeof s?s:String(s);const r=()=>{this._core?.writeValue(n,i.path,function(e){const t=e.trim();try{return JSON.parse(t)}catch{return e}}(o.value),i.indexes),this._markDirty("state")};o.addEventListener("keydown",e=>{"Enter"===e.key?r():"Escape"===e.key&&this._markDirty("state")}),e.replaceChild(o,t),o.focus()}_renderWiringPane(){const e=this._core,t=this._paneElements.wiring;t.replaceChildren();const n=document.createElement("div");n.className="wiring-tabs";for(const[e,t]of[["wiring","wiring"],["coverage","coverage"]]){const i=document.createElement("button");i.textContent=t,this._wiringView===e&&i.classList.add("active"),i.addEventListener("click",()=>{this._wiringView=e,this._markDirty("wiring")}),n.append(i)}if(t.append(n),"coverage"===this._wiringView)return void this._renderCoverageView(t);let i,s;if(null!==this._pickedNode){i=e.getWiringForNode(this._pickedNode);const t=this._pickedNode;s=t instanceof Element?`<${t.tagName.toLowerCase()}>`:t.nodeName}else if(null!==this._selectedPath){const t=this._selectedRoster();i=null!==t?e.getWiringForPath(t.name,this._selectedPath):[],s=this._selectedPath}else i=e.getAllWiring(),s="all";const o=document.createElement("div");if(o.textContent=`context: ${s} — ${i.length} live binding${1===i.length?"":"s"}`,t.append(o),i.length>0){for(const e of i)t.append(this._wiringRow(e));return}const r=e.getCanonicalDeclared(),a=this._selectedRoster(),d=null===r&&null!==a?function(e,t="data-wcs"){const n=[];for(const i of e.querySelectorAll(`[${t}]`)){const e=i.getAttribute(t);for(const t of e.split(";")){const e=m(i,t,"attribute");null!==e&&n.push(e)}}const i=(e.ownerDocument??e).createTreeWalker(e,NodeFilter.SHOW_COMMENT);let s=i.nextNode();for(;null!==s;){const e=s.textContent.trim(),t=p.find(t=>e===t||e.startsWith(t+":"));if(void 0!==t){const i=s.parentNode instanceof Element?s.parentNode:null;if(null!==i){const s=e===t?"":e.slice(t.length+1).trim();if(s.length>0){const e="wcs-text"===t?"textContent":t.slice(4);n.push(m(i,`${e}: ${s}`,"comment"))}}}s=i.nextNode()}return n}(this._scanRootOf(a)):[];if(0===(r?.length??0)&&0===d.length)return void t.append(this._emptyRow("no bindings observed"));const c=document.createElement("div");c.className="notice";const l=document.createElement("span");l.className="badge-tag declared",l.textContent=null!==r?"declared (canonical)":"declared",c.append(l,document.createTextNode(" attached late — reload to capture live bindings "));const h=document.createElement("button");if(h.textContent="reload",h.addEventListener("click",()=>{location.reload()}),c.append(h),t.append(c),null!==r)for(const e of r)t.append(this._canonicalDeclaredRow(e));else for(const e of d)t.append(this._declaredRow(e))}_renderCoverageView(e){const t=this._core,n=t.observingSince,i=document.createElement("div"),s=null===n?null:new Date(Date.now()-(performance.now()-n)).toLocaleTimeString();i.textContent=null===s?"not observing":`observing since ${s} (declared vs measured after this point)`,e.append(i);const o=t.getCoverageReport();if(0!==o.length)for(const t of o){const n=document.createElement("div");n.className="wiring-row";const i=document.createElement("span");i.className="badge-tag",i.textContent=t.kind;const s=document.createElement("span");s.className="badge-tag",s.textContent=t.count>1?`${t.status} ×${t.count}`:t.status,"never"===t.status||"never-attached"===t.status||"emitted-unheard"===t.status?s.classList.add("warn"):"prerequisite-missing"===t.status&&s.classList.add("declared");const o=document.createElement("span");if(o.className="path",o.textContent=` ${t.name}@${t.stateName} `,n.append(i,document.createTextNode(" "),o,s),null!==t.note){const e=document.createElement("span");e.className="detail",e.textContent=` ${t.note}`,n.append(e)}e.append(n)}else e.append(this._emptyRow("nothing declared to cover"))}_canonicalDeclaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");s.className="path";const o=e.outFilters.map(e=>` | ${e.filterName}(${e.args.join(",")})`).join("");if(s.textContent=`${e.statePathName}@${e.stateName}${o}`,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),null!==e.node){const n=e.node;t.addEventListener("click",()=>{this._highlightNodes([n])})}return t}_scanRootOf(e){const t=e.rootNode;return t.nodeType===Node.DOCUMENT_NODE||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?t:document}_wiringRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="prop",n.textContent=e.propName;const i=document.createTextNode(" ← "),s=document.createElement("span");s.className="path",s.textContent=`${e.path}@${e.stateName}`;const o=document.createElement("span");return o.className="badge-tag",o.textContent=e.bindingType,t.append(o,document.createTextNode(" "),n,i,s),t.addEventListener("click",()=>{const t=e.bindingRef.deref();void 0!==t&&this._highlightNodes([t.node,t.replaceNode])}),t}_declaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");return s.className="path",s.textContent=`${e.path}@${e.stateName}`,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),t.addEventListener("click",()=>{this._highlightNodes([e.element])}),t}_renderTimelinePane(){const e=this._core,t=this._paneElements.timeline,n=e.getTimeline(),i=Math.max(0,n.length-200),s=[];i>0&&s.push(this._emptyRow(`…(${i} earlier entries)`));for(let e=i;e<n.length;e++)s.push(this._timelineRow(n[e]));0===s.length&&s.push(this._emptyRow("no activity yet")),t.replaceChildren(...s),t.scrollTop=t.scrollHeight}_timelineRow(e){const t=document.createElement("div");t.className="timeline-row";const n=document.createElement("span");n.className="t",n.textContent=`${(e.time/1e3).toFixed(3)}s `;const i=document.createElement("span");i.className="badge-tag kind",i.textContent=e.kind,0===e.subscriberCount&&(i.classList.add("warn"),i.title="emitted with no subscribers"),"watch-error"!==e.kind&&"watch-chain-limit"!==e.kind||(i.classList.add("warn"),i.title="watch-error"===e.kind?"a $watch threw; the runtime isolated it (console.error only)":"a $watch write chain hit the depth limit and was cut off"),"path-unresolved"!==e.kind&&"binding-apply-error"!==e.kind||(i.classList.add("warn"),i.title="path-unresolved"===e.kind?"a wired path does not resolve on the state; its updates are dropped":"a binding threw while applying; the runtime isolated it (console.error only)"),"propagation-hop-limit"!==e.kind&&"contract-drift"!==e.kind||(i.classList.add("warn"),i.title="propagation-hop-limit"===e.kind?"a two-way propagation chain hit the hop limit and was cut off":"sidecar manifest drifted from the live wcBindable declaration (live wins)");const s=document.createElement("span");s.className="label";const o=null!==e.stateName?`@${e.stateName}`:"";s.textContent=` ${e.label}${o} `;const r=document.createElement("span");return r.className="detail",r.textContent=e.detail,t.append(n,i,s,r),t}_emptyRow(e){const t=document.createElement("div");return t.className="empty",t.textContent=e,t}_highlightPath(e,t){const n=this._core,i=[];for(const s of n.getWiringForPath(e.name,t)){const e=s.bindingRef.deref();void 0!==e&&i.push(e.node,e.replaceNode)}this._highlightNodes(i)}_highlightNodes(e){const t=this._highlightLayer;t.replaceChildren();const n=new Set;for(const i of e){const e=i instanceof Element?i:i.parentElement;if(null===e||n.has(e)||!e.isConnected)continue;n.add(e);const s=e.getBoundingClientRect(),o=document.createElement("div");o.className="hl-box",o.style.left=`${s.left}px`,o.style.top=`${s.top}px`,o.style.width=`${s.width}px`,o.style.height=`${s.height}px`,t.append(o)}setTimeout(()=>{t.replaceChildren()},2e3)}}const f="wcs-devtools";function _(){null===document.querySelector(f)&&document.body.appendChild(document.createElement(f))}document.documentElement.hasAttribute("data-wcs-server")||(customElements.get(f)||customElements.define(f,g),null!==document.body?_():document.addEventListener("DOMContentLoaded",_,{once:!0}));
1
+ const e="__WCSTACK_DEVTOOLS_HOOK__";function t(){const t=globalThis,n=t[e];if(void 0!==n)return 2!==n.version&&console.warn(`[wcstack/devtools] hook registry version mismatch: found ${n.version}, expected 2. Keeping the existing registry (first-wins).`),n;const i=function(){const e=new Map,t=new Set,n=e=>{if(0===t.size)return void e._setSink(null);const n=e.id;e._setSink(e=>{for(const i of t)i.onEvent?.(n,e)})};return{version:2,sources:e,register(i){if(!e.has(i.id)){e.set(i.id,i),n(i);for(const e of t)e.onSourceRegistered?.(i)}},unregister(n){const i=e.get(n);if(void 0!==i){i._setSink(null),e.delete(n);for(const e of t)e.onSourceUnregistered?.(n)}},addListener(i){t.add(i);for(const t of e.values())n(t),i.onSourceRegistered?.(t);return()=>{if(t.delete(i))for(const t of e.values())n(t)}}}}();return t[e]=i,i}const n=80;function i(e){const t=e.constructor,n=t?.name;return"string"==typeof n&&n.length>0?n:"Object"}function s(e,t=2){switch(typeof e){case"string":return`"${e.length>n?e.slice(0,n)+"…":e}"`;case"number":case"boolean":case"bigint":return String(e);case"symbol":return e.toString();case"undefined":return"undefined";case"function":return"[[Function]]"}if(null===e)return"null";const o=e;if(Array.isArray(o)){if(t<=0)return`[[Array(${o.length})]]`;const e=o.slice(0,3).map(e=>s(e,t-1)),n=o.length>3?`, …(${o.length})`:"";return`[${e.join(", ")}${n}]`}if(function(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(o)){if(t<=0)return"[[Object]]";const e=Object.keys(o),n=e.slice(0,3).map(e=>`${e}: ${s(o[e],t-1)}`),i=e.length>3?`, …(${e.length})`:"";return`{${n.join(", ")}${i}}`}return`[[${i(o)}]]`}function o(e){if(null!==e&&"object"==typeof e){const{name:t,message:s}=e;if("string"==typeof s){const o="string"==typeof t&&t.length>0?t:i(e),r=s.length>n?s.slice(0,n)+"…":s;return r.length>0?`${o}: ${r}`:o}}return s(e,1)}function r(e){if(0===e.length)return"";const t=e.slice(0,3).map(e=>{const t=s(e,1);return t.length>n?t.slice(0,n)+"…":t}),i=e.length>3?`, …(${e.length})`:"";return`${t.join(", ")}${i}`}const a=String.fromCharCode(0);function c(e){return e}function d(e,t){return e+a+t}function l(e,t){return e+a+t}function h(e){return"undefined"!=typeof ShadowRoot&&e instanceof ShadowRoot?`<${e.host.tagName.toLowerCase()}>`:9===e.nodeType?"document":e.nodeName.toLowerCase()}function u(e,t,n){return void 0===n?{kind:e,name:t,status:"never",count:0,note:null}:n.zeroSubscriberCount===n.count?{kind:e,name:t,status:"emitted-unheard",count:n.count,note:`all ${n.count} emit(s) had 0 subscribers`}:{kind:e,name:t,status:"emitted",count:n.count,note:n.zeroSubscriberCount>0?`${n.zeroSubscriberCount}/${n.count} emit(s) had 0 subscribers`:null}}class p{_timelineCapacity;_removeListener=null;_sources=new Map;_roster=new Map;_wiringByPathKey=new Map;_wiringEntryByBinding=new WeakMap;_timeline=[];_seq=0;_paused=!1;_changeListeners=new Set;_observingSince=null;_watchFiredCounts=new Map;_tokenEmitCounts=new Map;_everAttachedKeys=new Set;constructor(e){this._timelineCapacity=e?.timelineCapacity??500}get connected(){return null!==this._removeListener}get paused(){return this._paused}set paused(e){this._paused=e}connect(){if(null!==this._removeListener)return;this._observingSince=performance.now();const e=t();this._removeListener=e.addListener({onSourceRegistered:e=>{this._sources.set(e.id,e),this._refreshRosterOf(e),this._notify("sources")},onSourceUnregistered:e=>{this._sources.delete(e),this._roster.delete(e),this._notify("sources"),this._notify("roster")},onEvent:(e,t)=>{this._ingest(e,t)}})}disconnect(){null!==this._removeListener&&(this._removeListener(),this._removeListener=null,this._sources.clear(),this._roster.clear(),this._wiringByPathKey.clear(),this._wiringEntryByBinding=new WeakMap,this._observingSince=null,this._watchFiredCounts.clear(),this._tokenEmitCounts.clear(),this._everAttachedKeys.clear(),this._notify("sources"),this._notify("roster"),this._notify("wiring"),this._notify("coverage"))}get observingSince(){return this._observingSince}onChange(e){return this._changeListeners.add(e),()=>{this._changeListeners.delete(e)}}getSources(){return[...this._sources.values()]}getRoster(){const e=[];for(const t of this._roster.values())e.push(...t);return e}refreshRoster(){for(const e of this._sources.values())this._refreshRosterOf(e);this._notify("roster")}getTimeline(){return this._timeline}clearTimeline(){this._timeline=[],this._notify("timeline")}getWiringForPath(e,t){const n=this._wiringByPathKey.get(e);if(void 0===n)return[];const i=this._collectAlive(n);return void 0===t?i:i.filter(e=>null===e.stateElementRef||e.stateElementRef.deref()===t)}getAllWiring(){const e=[];for(const t of this._wiringByPathKey.values())e.push(...this._collectAlive(t));return e}getWiringForNode(e){const t=[];for(const n of this._wiringByPathKey.values())for(const i of this._collectAlive(n)){const n=i.bindingRef.deref();(n.node===e||n.replaceNode===e||e.contains(n.node)||e.contains(n.replaceNode))&&t.push(i)}return t}getCanonicalDeclared(){let e=!1;const t=[],n=new Set;for(const[i,s]of this._sources){if("function"!=typeof s.getDeclaredBindings)continue;e=!0;const o=new Set;for(const e of this._roster.get(i)??[])o.add(e.rootNode);for(const e of o)for(const i of s.getDeclaredBindings(e)){const e=[i.statePathName,i.propName,i.bindingType,i.origin,i.raw].join(a);n.has(e)||(n.add(e),t.push(i))}}return e?t:null}getCoverageReport(){const e=[];for(const t of this.getRoster()){const n=t.summary;for(const t of n.watchPaths??[]){const i=this._watchFiredCounts.get(c(t))??0;if(i>0){e.push({kind:"watch",name:t,status:"fired",count:i,note:null});continue}const s=void 0!==n.keyedListPaths;let o=null;for(let e=t.indexOf(".*");-1!==e;e=t.indexOf(".*",e+2)){const i=t.slice(0,e);if(!(n.paths.list.has(i)||(n.keyedListPaths?.has(i)??!1))){o=i;break}}null===o?e.push({kind:"watch",name:t,status:"never",count:0,note:null}):e.push({kind:"watch",name:t,status:"prerequisite-missing",count:0,note:s?`list "${o}" has no for binding and no $listKeys declaration — list writes never reach its rows (only explicit-index writes can fire this watch)`:`no for binding observed for list "${o}" (a $listKeys declaration would still let list writes fire it)`})}for(const t of n.commandTokenNames)e.push(u("command",t,this._tokenEmitCounts.get(d("command",t))));for(const t of n.eventTokenNames)e.push(u("eventToken",t,this._tokenEmitCounts.get(d("event",t))))}const t=this.getCanonicalDeclared();if(null!==t){const n=new Set;for(const i of t){if("for"===i.bindingType||"if"===i.bindingType||"elseif"===i.bindingType||"else"===i.bindingType)continue;if(i.propName.startsWith("eventToken."))continue;const t=l(i.statePathName,i.propName);if(n.has(t))continue;n.add(t);const s=this._everAttachedKeys.has(t);e.push({kind:"binding",name:`${i.propName} ← ${i.statePathName}`,status:s?"attached":"never-attached",count:s?1:0,note:"fragment"===i.origin?"template interior (attaches when rows materialize)":null})}}return e}keysOf(e){const t=this._sources.get(e.sourceId);return void 0===t||"function"!=typeof t.keys?[]:t.keys(e.rootNode)}readValue(e,t,n){const i=this._sources.get(e.sourceId);if(void 0!==i)return i.read(e.rootNode,t,n)}writeValue(e,t,n,i){const s=this._sources.get(e.sourceId);void 0!==s&&s.write(e.rootNode,t,n,i)}_notify(e){for(const t of this._changeListeners)t(e)}_refreshRosterOf(e){const t=[],n=new Map;for(const i of e.getStateElements()){const s=h(i.rootNode),o=(n.get(s)??0)+1;n.set(s,o),t.push({sourceId:e.id,label:1===o?s:`${s}#${o}`,rootNode:i.rootNode,summary:i})}this._roster.set(e.id,t)}_collectAlive(e){const t=[];for(const n of e)void 0!==n.bindingRef.deref()?t.push(n):e.delete(n);return t}_appendTimeline(e){if(this._paused)return;this._timeline.push({...e,seq:this._seq++,time:performance.now()});const t=this._timeline.length-this._timelineCapacity;t>0&&this._timeline.splice(0,t),this._notify("timeline")}_labelOf(e){const t=e.listIndex?.indexes,n=e.absolutePathInfo.pathInfo.path;return void 0!==t?`${n}[${t.join(",")}]`:n}_ingest(e,t){switch(t.type){case"state:element-registered":{const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-registered",label:h(t.rootNode),detail:"",subscriberCount:null})}case"state:element-unregistered":{const n=this._sources.get(e);return void 0!==n&&(this._refreshRosterOf(n),this._notify("roster")),void this._appendTimeline({sourceId:e,kind:"element-unregistered",label:h(t.rootNode),detail:"",subscriberCount:null})}case"state:write":{const n=t.hasOldValue?`${s(t.value)} (was ${s(t.oldValue)})`:s(t.value);return void this._appendTimeline({sourceId:e,kind:"write",label:this._labelOf(t.absoluteAddress),detail:n,subscriberCount:null})}case"state:update-batch":{const n=[];let i=0;for(const e of t.addresses)i++,n.length<3&&n.push(this._labelOf(e));if(0===i)return;const s=i>n.length?`, …(${i})`:"";return void this._appendTimeline({sourceId:e,kind:"batch",label:`${i} address${1===i?"":"es"}`,detail:`${n.join(", ")}${s}`,subscriberCount:null})}case"state:binding-added":{const n=t.absoluteAddress.absolutePathInfo.pathInfo.path,i=n;let s=this._wiringByPathKey.get(i);void 0===s&&(s=new Set,this._wiringByPathKey.set(i,s));const o=t.absoluteAddress.absolutePathInfo.stateElement,r={sourceId:e,path:n,propName:t.binding.propName,bindingType:t.binding.bindingType,bindingRef:new WeakRef(t.binding),stateElementRef:"object"==typeof o&&null!==o?new WeakRef(o):null};return s.add(r),this._wiringEntryByBinding.set(t.binding,r),this._everAttachedKeys.add(l(n,t.binding.propName)),this._notify("wiring"),void this._notify("coverage")}case"state:binding-removed":{const e=this._wiringEntryByBinding.get(t.binding);if(void 0===e)return;this._wiringEntryByBinding.delete(t.binding);const n=e.path,i=this._wiringByPathKey.get(n);return void 0!==i&&(i.delete(e),0===i.size&&this._wiringByPathKey.delete(n)),void this._notify("wiring")}case"state:binding-cleared":{const e=t.absoluteAddress.absolutePathInfo.pathInfo.path;return void(this._wiringByPathKey.delete(e)&&this._notify("wiring"))}case"state:token-emit":{const n=d(t.kind,t.tokenName),i=this._tokenEmitCounts.get(n);return void 0===i?this._tokenEmitCounts.set(n,{count:1,zeroSubscriberCount:0===t.subscriberCount?1:0}):(i.count+=1,0===t.subscriberCount&&(i.zeroSubscriberCount+=1)),this._notify("coverage"),void this._appendTimeline({sourceId:e,kind:t.kind,label:t.tokenName,detail:r(t.args),subscriberCount:t.subscriberCount})}case"state:watch-fired":{const e=t.path;return this._watchFiredCounts.set(e,(this._watchFiredCounts.get(e)??0)+1),void this._notify("coverage")}case"state:watch-error":return void this._appendTimeline({sourceId:e,kind:"watch-error",label:t.path,detail:`${t.phase}: ${o(t.error)}`,subscriberCount:null});case"state:watch-chain-limit":return void this._appendTimeline({sourceId:e,kind:"watch-chain-limit",label:`depth > ${t.maxDepth}`,detail:t.paths.join(", "),subscriberCount:null});case"state:path-unresolved":return void this._appendTimeline({sourceId:e,kind:"path-unresolved",label:t.path,detail:`${t.source}: "${t.missingSegment}" is not declared`,subscriberCount:null});case"state:binding-apply-error":return void this._appendTimeline({sourceId:e,kind:"binding-apply-error",label:t.path,detail:`${t.bindingType}: ${o(t.error)}`,subscriberCount:null});case"propagation:suppressed":return void this._appendTimeline({sourceId:e,kind:"propagation-suppressed",label:t.member,detail:`${t.reason} (tx ${t.transactionId}, edge ${t.edgeId})`,subscriberCount:null});case"propagation:coalesced":return void this._appendTimeline({sourceId:e,kind:"propagation-coalesced",label:this._labelOf(t.absoluteAddress),detail:`tx ${t.droppedTransactionId} dropped (winner tx ${t.winnerTransactionId})`,subscriberCount:null});case"propagation:hop-limit":return void this._appendTimeline({sourceId:e,kind:"propagation-hop-limit",label:this._labelOf(t.absoluteAddress),detail:`hop ${t.hop} (tx ${t.transactionId})`,subscriberCount:null});case"contract:drift":{const n=void 0!==t.member?`: ${t.member}`:"",i="event-mismatch"===t.reason?` (sidecar ${t.sidecarEvent??"?"} / live ${t.liveEvent??"?"})`:"";return void this._appendTimeline({sourceId:e,kind:"contract-drift",label:t.tag,detail:`${t.reason}${n}${i}`,subscriberCount:null})}case"contract:manifest-read":case"contract:unsupported-extension":return}}}const m=["wcs-text","wcs-for","wcs-if","wcs-elseif","wcs-else"];function g(e,t,n){const i=t.trim();if(0===i.length)return null;const s=i.indexOf(":");if(s<0)return null;const o=i.slice(0,s).trim(),r=i.slice(s+1).trim();if(0===o.length||0===r.length)return null;const[a,...c]=r.split("|").map(e=>e.trim());return{element:e,propName:o,path:a,filters:c.filter(e=>e.length>0),origin:n,raw:i}}class f extends HTMLElement{static get observedAttributes(){return["open","dock","hotkey"]}_core=null;_removeCoreListener=null;_panel=null;_badge=null;_stateSelect=null;_paneElements={};_wiringView="wiring";_highlightLayer=null;_dirtyPanes=new Set;_renderScheduled=!1;_selectedRosterKey=null;_selectedPath=null;_pickedNode=null;_pickMode=!1;_expanded=new Set;_hotkeyHandler=null;_pickHandler=null;get core(){return this._core}connectedCallback(){if(document.documentElement.hasAttribute("data-wcs-server"))return;null===this.shadowRoot&&this._buildShadow();const e=Number(this.getAttribute("buffer")??"");this._core=new p({timelineCapacity:Number.isFinite(e)&&e>0?e:void 0}),this._removeCoreListener=this._core.onChange(e=>{"roster"===e||"sources"===e?(this._markDirty("state"),this._markDirty("wiring")):"wiring"===e?this._markDirty("wiring"):"coverage"===e?"coverage"===this._wiringView&&this._markDirty("wiring"):this._markDirty("timeline")}),this._core.connect(),this._applyDock(),this._applyOpen(),this._installHotkey(),this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline")}disconnectedCallback(){this._removeCoreListener?.(),this._removeCoreListener=null,this._core?.disconnect(),this._core=null,this._uninstallHotkey(),this._exitPickMode()}attributeChangedCallback(e){null!==this.shadowRoot&&("open"===e?this._applyOpen():"dock"===e?this._applyDock():"hotkey"===e&&(this._uninstallHotkey(),this._installHotkey()))}__flushRenderForTest(){this._renderDirty()}_buildShadow(){const e=this.attachShadow({mode:"open"}),t=document.createElement("style");t.textContent='\n:host {\n all: initial;\n position: fixed;\n z-index: 2147483647;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n inset: auto 0 0 auto;\n}\n* { box-sizing: border-box; }\n.badge {\n position: fixed;\n right: 12px;\n bottom: 12px;\n width: 40px;\n height: 40px;\n border-radius: 20px;\n border: 1px solid #2b4f78;\n background: #10263f;\n color: #9fd0ff;\n font-weight: 700;\n cursor: pointer;\n}\n.panel {\n position: fixed;\n display: flex;\n flex-direction: column;\n background: #0d1b2a;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n box-shadow: 0 0 24px rgba(0,0,0,.5);\n}\n.panel.dock-bottom { left: 0; right: 0; bottom: 0; height: 45vh; }\n.panel.dock-right { top: 0; right: 0; bottom: 0; width: 420px; }\n.panel[hidden] { display: none; }\nheader {\n display: flex;\n gap: 6px;\n align-items: center;\n padding: 6px 8px;\n border-bottom: 1px solid #2b4f78;\n background: #10263f;\n}\nheader .title { font-weight: 700; color: #9fd0ff; margin-right: 4px; }\nheader select, header button {\n font: inherit;\n background: #16324f;\n color: #d7e3f4;\n border: 1px solid #2b4f78;\n border-radius: 4px;\n padding: 2px 8px;\n cursor: pointer;\n}\nheader button[aria-pressed="true"] { background: #2b5d8f; }\nheader .spacer { flex: 1; }\n.panes { display: flex; flex: 1; min-height: 0; }\n.pane { flex: 1; min-width: 0; overflow: auto; padding: 6px 8px; border-right: 1px solid #1d3a5c; }\n.pane:last-child { border-right: none; }\n.pane h3 {\n margin: 0 0 6px;\n font-size: 11px;\n text-transform: uppercase;\n letter-spacing: .08em;\n color: #7ba7d4;\n}\n.tree-row { display: flex; gap: 6px; padding: 1px 0; align-items: baseline; white-space: nowrap; }\n.tree-row .toggle { width: 14px; cursor: pointer; color: #7ba7d4; user-select: none; }\n.tree-row .key { color: #9fd0ff; cursor: pointer; }\n.tree-row .value { color: #ffd9a0; overflow: hidden; text-overflow: ellipsis; }\n.tree-row .value.editable { cursor: pointer; }\n.tree-row input { font: inherit; background: #16324f; color: #ffd9a0; border: 1px solid #2b4f78; }\n.badge-tag {\n display: inline-block;\n padding: 0 4px;\n border-radius: 3px;\n font-size: 10px;\n background: #26456a;\n color: #a8c6e8;\n}\n.badge-tag.warn { background: #6a3326; color: #ffb3a0; }\n.badge-tag.declared { background: #4a4426; color: #efe3a0; }\n.wiring-row, .timeline-row { padding: 1px 0; white-space: nowrap; }\n.wiring-row .prop { color: #b7f0c0; }\n.wiring-row .path { color: #9fd0ff; }\n.timeline-row .t { color: #6f88a3; }\n.timeline-row .label { color: #9fd0ff; }\n.timeline-row .detail { color: #ffd9a0; }\n.timeline-row .kind { display: inline-block; min-width: 52px; text-align: center; }\n.empty { color: #6f88a3; font-style: italic; padding: 4px 0; }\n.notice { color: #efe3a0; padding: 2px 0 6px; }\n.notice button { font: inherit; margin-left: 6px; cursor: pointer; }\n.wiring-row .detail { color: #6f88a3; }\n.wiring-tabs { padding: 0 0 4px; }\n.wiring-tabs button { font: inherit; cursor: pointer; margin-right: 4px; opacity: 0.6; }\n.wiring-tabs button.active { opacity: 1; font-weight: bold; }\n.hl-box {\n position: fixed;\n pointer-events: none;\n border: 1px solid #58c2ff;\n background: rgba(88,194,255,.18);\n}\n',e.append(t);const n=document.createElement("button");n.className="badge",n.title="wcstack DevTools",n.textContent="WCS",n.addEventListener("click",()=>this.toggle()),e.append(n),this._badge=n;const i=document.createElement("div");i.className="panel dock-bottom",i.hidden=!0;const s=document.createElement("header"),o=document.createElement("span");o.className="title",o.textContent="wcstack devtools",s.append(o);const r=document.createElement("select");r.title="state element",r.addEventListener("change",()=>{this._selectedRosterKey=r.value||null,this._selectedPath=null,this._expanded.clear(),this._markDirty("state"),this._markDirty("wiring")}),s.append(r),this._stateSelect=r;const a=this._headerButton(s,"⌖ pick","pick a page element");a.addEventListener("click",()=>{this._pickMode?this._exitPickMode():this._enterPickMode(),a.setAttribute("aria-pressed",String(this._pickMode))}),a.dataset.role="pick";const c=this._headerButton(s,"⏸","pause timeline");c.addEventListener("click",()=>{const e=this._core;null!==e&&(e.paused=!e.paused,c.setAttribute("aria-pressed",String(e.paused)))}),c.dataset.role="pause";const d=this._headerButton(s,"🗑","clear timeline");d.addEventListener("click",()=>{this._core?.clearTimeline()}),d.dataset.role="clear";const l=document.createElement("span");l.className="spacer",s.append(l);const h=this._headerButton(s,"dock","toggle dock position");h.addEventListener("click",()=>{const e="bottom"===(this.getAttribute("dock")??"bottom")?"right":"bottom";this.setAttribute("dock",e)}),h.dataset.role="dock";const u=this._headerButton(s,"×","close");u.addEventListener("click",()=>this.toggle(!1)),u.dataset.role="close",i.append(s);const p=document.createElement("div");p.className="panes";for(const[e,t]of[["state","State"],["wiring","Wiring"],["timeline","Timeline"]]){const n=document.createElement("section");n.className=`pane pane-${e}`;const i=document.createElement("h3");i.textContent=t;const s=document.createElement("div");s.className="pane-body",n.append(i,s),p.append(n),this._paneElements[e]=s}i.append(p),e.append(i),this._panel=i;const m=document.createElement("div");m.className="hl-layer",e.append(m),this._highlightLayer=m}_headerButton(e,t,n){const i=document.createElement("button");return i.textContent=t,i.title=n,i.setAttribute("aria-pressed","false"),e.append(i),i}get open(){return this.hasAttribute("open")}toggle(e){e??!this.open?this.setAttribute("open",""):this.removeAttribute("open")}_applyOpen(){this._panel.hidden=!this.open,this._badge.hidden=this.open,this.open&&(this._markDirty("state"),this._markDirty("wiring"),this._markDirty("timeline"))}_applyDock(){const e="right"===this.getAttribute("dock")?"right":"bottom";this._panel.classList.toggle("dock-right","right"===e),this._panel.classList.toggle("dock-bottom","bottom"===e)}_installHotkey(){const e=this.getAttribute("hotkey")??"Alt+Shift+D";if("none"===e)return;const t=e.split("+").map(e=>e.trim().toLowerCase()),n=t[t.length-1],i=t.includes("alt"),s=t.includes("shift"),o=t.includes("ctrl"),r=t.includes("meta");this._hotkeyHandler=e=>{e.key.toLowerCase()===n&&e.altKey===i&&e.shiftKey===s&&e.ctrlKey===o&&e.metaKey===r&&(e.preventDefault(),this.toggle())},window.addEventListener("keydown",this._hotkeyHandler)}_uninstallHotkey(){null!==this._hotkeyHandler&&(window.removeEventListener("keydown",this._hotkeyHandler),this._hotkeyHandler=null)}_enterPickMode(){this._pickMode=!0,this._pickHandler=e=>{const t=e.target;t.getRootNode()!==this.shadowRoot&&t!==this&&(e.preventDefault(),e.stopPropagation(),this._pickedNode=t,this._selectedPath=null,this._exitPickMode(),this._markDirty("wiring"))},document.addEventListener("click",this._pickHandler,{capture:!0})}_exitPickMode(){null!==this._pickHandler&&(document.removeEventListener("click",this._pickHandler,{capture:!0}),this._pickHandler=null),this._pickMode=!1;const e=this.shadowRoot?.querySelector('button[data-role="pick"]');e?.setAttribute("aria-pressed","false")}_markDirty(e){this._dirtyPanes.add(e),this._renderScheduled||(this._renderScheduled=!0,requestAnimationFrame(()=>{this._renderDirty()}))}_renderDirty(){if(this._renderScheduled=!1,null===this._core||null===this.shadowRoot)return void this._dirtyPanes.clear();const e=this._dirtyPanes;this._dirtyPanes=new Set,e.has("state")&&this._renderStatePane(),e.has("wiring")&&this._renderWiringPane(),e.has("timeline")&&this._renderTimelinePane()}_rosterKey(e){return`${e.sourceId}:${e.label}`}_selectedRoster(){const e=this._core.getRoster();if(0===e.length)return null;return e.find(e=>this._rosterKey(e)===this._selectedRosterKey)??e[0]}_renderStatePane(){const e=this._core,t=this._paneElements.state,n=this._stateSelect,i=e.getRoster(),s=this._selectedRoster();if(n.replaceChildren(...i.map(e=>{const t=document.createElement("option");return t.value=this._rosterKey(e),t.textContent=`${e.label} (${e.sourceId.slice(0,12)})`,t.selected=null!==s&&this._rosterKey(e)===this._rosterKey(s),t})),t.replaceChildren(),null===s)return void t.append(this._emptyRow("no <wcs-state> elements observed"));this._selectedRosterKey=this._rosterKey(s);const o=e.keysOf(s);if(0!==o.length)for(const e of o)this._renderTreeNode(t,s,{path:e,indexes:[]},e,0);else t.append(this._emptyRow("no readable keys (runtime without keys() API?)"))}_renderTreeNode(e,t,n,i,o){const r=this._core;let a,c=!0;try{a=r.readValue(t,n.path,n.indexes)}catch{c=!1}const d=document.createElement("div");d.className="tree-row",d.style.paddingLeft=14*o+"px";const l=c&&function(e){if(Array.isArray(e))return!0;if(null===e||"object"!=typeof e)return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}(a),h=function(e){return`${e.path}#${e.indexes.join(",")}`}(n),u=l&&this._expanded.has(h),p=document.createElement("span");p.className="toggle",p.textContent=l?u?"▾":"▸":"",l&&p.addEventListener("click",()=>{this._expanded.has(h)?this._expanded.delete(h):this._expanded.add(h),this._markDirty("state")}),d.append(p);const m=document.createElement("span");m.className="key",m.textContent=`${i}:`,m.title=n.path,m.addEventListener("click",()=>{this._selectedPath=n.path,this._pickedNode=null,this._markDirty("wiring"),this._highlightPath(t,n.path)}),d.append(m);const g=document.createElement("span");if(g.className="value",c){g.textContent=s(a,1);(null===a||"object"!=typeof a)&&"function"!=typeof a&&(g.classList.add("editable"),g.title="click to edit",g.addEventListener("click",()=>{this._beginEdit(d,g,t,n,a)}))}else g.textContent="(unreadable getter)";if(d.append(g),e.append(d),u)if(Array.isArray(a)){const i=Math.min(a.length,20);for(let s=0;s<i;s++)this._renderTreeNode(e,t,{path:`${n.path}.*`,indexes:[...n.indexes,s]},`[${s}]`,o+1);if(a.length>i){const t=this._emptyRow(`…(${a.length} items)`);t.style.paddingLeft=14*(o+1)+"px",e.append(t)}}else for(const i of Object.keys(a))this._renderTreeNode(e,t,{path:`${n.path}.${i}`,indexes:n.indexes},i,o+1)}_beginEdit(e,t,n,i,s){const o=document.createElement("input");o.value="string"==typeof s?s:String(s);const r=()=>{this._core?.writeValue(n,i.path,function(e){const t=e.trim();try{return JSON.parse(t)}catch{return e}}(o.value),i.indexes),this._markDirty("state")};o.addEventListener("keydown",e=>{"Enter"===e.key?r():"Escape"===e.key&&this._markDirty("state")}),e.replaceChild(o,t),o.focus()}_renderWiringPane(){const e=this._core,t=this._paneElements.wiring;t.replaceChildren();const n=document.createElement("div");n.className="wiring-tabs";for(const[e,t]of[["wiring","wiring"],["coverage","coverage"]]){const i=document.createElement("button");i.textContent=t,this._wiringView===e&&i.classList.add("active"),i.addEventListener("click",()=>{this._wiringView=e,this._markDirty("wiring")}),n.append(i)}if(t.append(n),"coverage"===this._wiringView)return void this._renderCoverageView(t);let i,s;if(null!==this._pickedNode){i=e.getWiringForNode(this._pickedNode);const t=this._pickedNode;s=t instanceof Element?`<${t.tagName.toLowerCase()}>`:t.nodeName}else if(null!==this._selectedPath){const t=this._selectedRoster();i=null!==t?e.getWiringForPath(this._selectedPath,t.summary.element):[],s=this._selectedPath}else i=e.getAllWiring(),s="all";const o=document.createElement("div");if(o.textContent=`context: ${s} — ${i.length} live binding${1===i.length?"":"s"}`,t.append(o),i.length>0){for(const e of i)t.append(this._wiringRow(e));return}const r=e.getCanonicalDeclared(),a=this._selectedRoster(),c=null===r&&null!==a?function(e,t="data-wcs"){const n=[];for(const i of e.querySelectorAll(`[${t}]`)){const e=i.getAttribute(t);for(const t of e.split(";")){const e=g(i,t,"attribute");null!==e&&n.push(e)}}const i=(e.ownerDocument??e).createTreeWalker(e,NodeFilter.SHOW_COMMENT);let s=i.nextNode();for(;null!==s;){const e=s.textContent.trim(),t=m.find(t=>e===t||e.startsWith(t+":"));if(void 0!==t){const i=s.parentNode instanceof Element?s.parentNode:null;if(null!==i){const s=e===t?"":e.slice(t.length+1).trim();if(s.length>0){const e="wcs-text"===t?"textContent":t.slice(4);n.push(g(i,`${e}: ${s}`,"comment"))}}}s=i.nextNode()}return n}(this._scanRootOf(a)):[];if(0===(r?.length??0)&&0===c.length)return void t.append(this._emptyRow("no bindings observed"));const d=document.createElement("div");d.className="notice";const l=document.createElement("span");l.className="badge-tag declared",l.textContent=null!==r?"declared (canonical)":"declared",d.append(l,document.createTextNode(" attached late — reload to capture live bindings "));const h=document.createElement("button");if(h.textContent="reload",h.addEventListener("click",()=>{location.reload()}),d.append(h),t.append(d),null!==r)for(const e of r)t.append(this._canonicalDeclaredRow(e));else for(const e of c)t.append(this._declaredRow(e))}_renderCoverageView(e){const t=this._core,n=t.observingSince,i=document.createElement("div"),s=null===n?null:new Date(Date.now()-(performance.now()-n)).toLocaleTimeString();i.textContent=null===s?"not observing":`observing since ${s} (declared vs measured after this point)`,e.append(i);const o=t.getCoverageReport();if(0!==o.length)for(const t of o){const n=document.createElement("div");n.className="wiring-row";const i=document.createElement("span");i.className="badge-tag",i.textContent=t.kind;const s=document.createElement("span");s.className="badge-tag",s.textContent=t.count>1?`${t.status} ×${t.count}`:t.status,"never"===t.status||"never-attached"===t.status||"emitted-unheard"===t.status?s.classList.add("warn"):"prerequisite-missing"===t.status&&s.classList.add("declared");const o=document.createElement("span");if(o.className="path",o.textContent=` ${t.name} `,n.append(i,document.createTextNode(" "),o,s),null!==t.note){const e=document.createElement("span");e.className="detail",e.textContent=` ${t.note}`,n.append(e)}e.append(n)}else e.append(this._emptyRow("nothing declared to cover"))}_canonicalDeclaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");s.className="path";const o=e.outFilters.map(e=>` | ${e.filterName}(${e.args.join(",")})`).join("");if(s.textContent=`${e.statePathName}${o}`,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),null!==e.node){const n=e.node;t.addEventListener("click",()=>{this._highlightNodes([n])})}return t}_scanRootOf(e){const t=e.rootNode;return t.nodeType===Node.DOCUMENT_NODE||t.nodeType===Node.DOCUMENT_FRAGMENT_NODE?t:document}_wiringRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="prop",n.textContent=e.propName;const i=document.createTextNode(" ← "),s=document.createElement("span");s.className="path",s.textContent=e.path;const o=document.createElement("span");return o.className="badge-tag",o.textContent=e.bindingType,t.append(o,document.createTextNode(" "),n,i,s),t.addEventListener("click",()=>{const t=e.bindingRef.deref();void 0!==t&&this._highlightNodes([t.node,t.replaceNode])}),t}_declaredRow(e){const t=document.createElement("div");t.className="wiring-row";const n=document.createElement("span");n.className="badge-tag declared",n.textContent=e.origin;const i=document.createElement("span");i.className="prop",i.textContent=e.propName;const s=document.createElement("span");return s.className="path",s.textContent=e.path,t.append(n,document.createTextNode(" "),i,document.createTextNode(" ← "),s),t.addEventListener("click",()=>{this._highlightNodes([e.element])}),t}_renderTimelinePane(){const e=this._core,t=this._paneElements.timeline,n=e.getTimeline(),i=Math.max(0,n.length-200),s=[];i>0&&s.push(this._emptyRow(`…(${i} earlier entries)`));for(let e=i;e<n.length;e++)s.push(this._timelineRow(n[e]));0===s.length&&s.push(this._emptyRow("no activity yet")),t.replaceChildren(...s),t.scrollTop=t.scrollHeight}_timelineRow(e){const t=document.createElement("div");t.className="timeline-row";const n=document.createElement("span");n.className="t",n.textContent=`${(e.time/1e3).toFixed(3)}s `;const i=document.createElement("span");i.className="badge-tag kind",i.textContent=e.kind,0===e.subscriberCount&&(i.classList.add("warn"),i.title="emitted with no subscribers"),"watch-error"!==e.kind&&"watch-chain-limit"!==e.kind||(i.classList.add("warn"),i.title="watch-error"===e.kind?"a $watch threw; the runtime isolated it (console.error only)":"a $watch write chain hit the depth limit and was cut off"),"path-unresolved"!==e.kind&&"binding-apply-error"!==e.kind||(i.classList.add("warn"),i.title="path-unresolved"===e.kind?"a wired path does not resolve on the state; its updates are dropped":"a binding threw while applying; the runtime isolated it (console.error only)"),"propagation-hop-limit"!==e.kind&&"contract-drift"!==e.kind||(i.classList.add("warn"),i.title="propagation-hop-limit"===e.kind?"a two-way propagation chain hit the hop limit and was cut off":"sidecar manifest drifted from the live wcBindable declaration (live wins)");const s=document.createElement("span");s.className="label",s.textContent=` ${e.label} `;const o=document.createElement("span");return o.className="detail",o.textContent=e.detail,t.append(n,i,s,o),t}_emptyRow(e){const t=document.createElement("div");return t.className="empty",t.textContent=e,t}_highlightPath(e,t){const n=this._core,i=[];for(const s of n.getWiringForPath(t,e.summary.element)){const e=s.bindingRef.deref();void 0!==e&&i.push(e.node,e.replaceNode)}this._highlightNodes(i)}_highlightNodes(e){const t=this._highlightLayer;t.replaceChildren();const n=new Set;for(const i of e){const e=i instanceof Element?i:i.parentElement;if(null===e||n.has(e)||!e.isConnected)continue;n.add(e);const s=e.getBoundingClientRect(),o=document.createElement("div");o.className="hl-box",o.style.left=`${s.left}px`,o.style.top=`${s.top}px`,o.style.width=`${s.width}px`,o.style.height=`${s.height}px`,t.append(o)}setTimeout(()=>{t.replaceChildren()},2e3)}}const _="wcs-devtools";function b(){null===document.querySelector(_)&&document.body.appendChild(document.createElement(_))}document.documentElement.hasAttribute("data-wcs-server")||(customElements.get(_)||customElements.define(_,f),null!==document.body?b():document.addEventListener("DOMContentLoaded",b,{once:!0}));
2
2
  //# sourceMappingURL=auto.min.js.map