Files
houseplan-card/custom_components/houseplan/frontend/houseplan-assets/iso-scene-render-B6PFBRuR.js
T
Codex 5afdb644c7 Смена пространства выбрасывает слой, а не сверяет его поэлементно
#525 увёл оба списка сцены с `map()` на `repeat(items, (item) => item.id, …)`,
чтобы Lit не переиспользовал узлы по позиции и не проигрывал анимацию двери,
которой не было. Правка верная, но на плане с двумя сотнями маркеров она
оказалась дорогой ровно там, где пользы не приносит: при смене пространства
ключи не пересекаются вовсе, и `repeat` строит две карты ключей и обходит оба
списка, чтобы затем всё равно выбросить всё и создать заново.

Бисект по медиане `switchCycleMs` на `large-house`: 871,2 перед #525 → 953,5
после. На раннере эти 80 мс распадаются на шесть-девять дополнительных длинных
задач, и `longTask.countP95` вышел за порог стабильного гейта.

Теперь оба списка рендерятся как `keyed(space.id, repeat(…))`. Внешний ключ
делает смену пространства: поддерево выбрасывается целиком, дифа нет. Внутренний
остаётся, потому что состав списков едет и внутри пространства — у маркеров от
призраков редактора и живого синка, у проёмов от записи с нерешённым хостом,
которая живёт только в режиме plan, — а переходы на `.device-shell-frame`,
`.op-leaf` и `.op-arc` никуда не делись.

Замер после правки: `switchCycleMs` 889,1 против 936,0 на `main` и 871,2 до
#525. Потолок карточки поднят на одну строку — на `import { keyed }`;
переносить нечего, сам рендер не вырос ни на символ.

Issue: #534
User-Visible: yes
2026-09-11 22:30:11 +03:00

74 lines
38 KiB
JavaScript

globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b3e08d50a47faaba7562dc080f267ca13de845113735892a9115a6cdd991392a";import{dB as e,dC as t,b1 as n,dD as o,dE as a,h as i,dF as r,dG as s,dH as l,dI as c,a1 as d,dJ as h,ag as u,bU as f,bT as p,dK as m,ah as g,L as w,dL as y,cR as v,dM as x,A as M,w as b,dN as S,dO as $,dP as k,dQ as z,dR as I}from"./houseplan-card-bOJWMeFY.js";import{i as P}from"./guard-zx2aaPuf.js";const C=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function j(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n],a=e[(n+1)%e.length];t+=o[0]*a[1]-a[0]*o[1]}return t/2}function N(e,t){const n=function(e){const t=(Array.isArray(e)?e:[]).filter(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])).map(e=>[Number(e[0]),Number(e[1])]),n=t[t.length-1];return t.length>1&&t[0][0]===n[0]&&t[0][1]===n[1]&&t.pop(),t}(e);if(n.length<3)return[];const o=!t;return j(n)>0===o?n:[...n].reverse()}function O(e,t,o){return e.length?`M ${e.map(e=>C(n(e,o,t))).join(" L ")} Z`:""}function A(e,t,n){const o=t[1]-e[1],a=-(t[0]-e[0]),i=n.rotDeg*Math.PI/180;return o*Math.sin(i)+a*Math.cos(i)}function B(t,o,a=e){if(!Number.isFinite(o)||o<0)throw new Error("invalid floor edge height");const i=(t||[]).map(e=>(e||[]).map((e,t)=>function(e,t){const n=N(e,t);if(!n.length)return n;let o=0;for(let e=1;e<n.length;e++)(n[e][0]<n[o][0]||n[e][0]===n[o][0]&&n[e][1]<n[o][1])&&(o=e);return[...n.slice(o),...n.slice(0,o)]}(e,t>0)).filter(e=>e.length>=3&&Math.abs(j(e))>=1e-9)).filter(e=>e.length&&j(e[0])>0);i.sort((e,t)=>{const n=e[0][0],o=t[0][0];return n[0]-o[0]||n[1]-o[1]||Math.abs(j(t[0]))-Math.abs(j(e[0]))});const r=[],s=[];let l=0;for(let e=0;e<i.length;e++){const t=i[e];for(const e of t)r.push(O(e,a,0));const c=t[0];l+=c.length;for(let t=0;t<c.length;t++){const i=c[t],r=c[(t+1)%c.length];if(A(i,r,a)<=1e-9)continue;const l=n(i,0,a),d=n(r,0,a),h=n(r,-o,a),u=n(i,-o,a);s.push({d:`M ${C(l)} L ${C(d)} L ${C(h)} L ${C(u)} Z`,depth:Math.max(u[1],h[1]),component:e,edge:t,planEdge:[i,r]})}}return s.sort((e,t)=>e.depth-t.depth||e.component-t.component||e.edge-t.edge),{footprintPath:r.join(" "),sides:s,componentCount:i.length,edgeCount:l}}function R(e,t){return e^=Math.round(64*(Number.isFinite(t)?t:0)),Math.imul(e,16777619)>>>0}const H=Object.freeze({revision:1,leafThicknessRatio:.04,frameThicknessRatio:.055,gateTurnDeg:10,gateTopRatio:.88,windowBottomRatio:.27,windowTopRatio:.78,doorTopRatio:.92});H.leafThicknessRatio,H.frameThicknessRatio;const F=e=>e.every(Number.isFinite);function T(e,t){return Object.freeze([Object.is(e,-0)?0:e,Object.is(t,-0)?0:t])}function L(e,t){return[e[0]+t[0],e[1]+t[1]]}function V(e,t){return[e[0]-t[0],e[1]-t[1]]}function G(e,t){return[e[0]*t,e[1]*t]}function W(e,t,n,o){const a=e[0]*n,i=e[1]*o,r=t*Math.PI/180;return[a*Math.cos(r)-i*Math.sin(r),a*Math.sin(r)+i*Math.cos(r)]}function E(e,t,n,a,i,r,s){const l=e.flipH?-1:1,c="gate"===e.type?1:e.flipV?-1:1,d=o(e.type,e.flipV,e.angle,e.face);return{leaf:t,hinge:L([e.x+d.ox,e.y+d.oy],W(n,e.angle,l,c)),closedVector:W(a,e.angle,l,c),quarterVector:W([-a[1],a[0]],e.angle,l,c),turnDeg:i,bottom:r,top:s}}const q=e=>`${Number(e[0].toFixed(4))} ${Number(e[1].toFixed(4))}`;function D(e,t,o,a,i={}){const r=o.map(e=>n(e.point,e.z,a));return Object.freeze({kind:e,material:t,d:`M ${r.map(q).join(" L ")} Z`,depth:Math.max(...r.map(e=>e[1])),...i})}function _(e,t,n,o,a,i,r,s={}){return D(e,t,[{point:n,z:a},{point:o,z:a},{point:o,z:i},{point:n,z:i}],r,s)}function U(t,o,a=e){const i=Math.max(0,Math.min(1,Number.isFinite(o)?o:0));return t.leaves.map(e=>{const o=function(e,t){const n=e.turnDeg*t*Math.PI/180;return[e.hinge[0]+e.closedVector[0]*Math.cos(n)+e.quarterVector[0]*Math.sin(n),e.hinge[1]+e.closedVector[1]*Math.cos(n)+e.quarterVector[1]*Math.sin(n)]}(e,i),r=n(e.hinge,e.bottom,a),s=n(o,e.bottom,a),l=n(o,e.top,a),c=n(e.hinge,e.top,a),d="window"===t.type?"light-window":"matte-leaf",h="window"===t.type?Object.freeze([_("window-insert","light-window",e.hinge,o,e.bottom,e.top,a)]):function(e,t,n,o){const a=V(t,e.hinge),i=Math.hypot(a[0],a[1]);if(!(i>1e-9&&n>0))return Object.freeze([]);const r=T(-a[1]*n/(2*i),a[0]*n/(2*i)),s=L(e.hinge,r),l=L(t,r),c=V(e.hinge,r),d=V(t,r),h=[_("leaf-back","matte-leaf",d,c,e.bottom,e.top,o),_("leaf-front","matte-leaf",s,l,e.bottom,e.top,o),_("leaf-edge","matte-leaf",c,s,e.bottom,e.top,o,{edge:"hinge"}),_("leaf-edge","matte-leaf",l,d,e.bottom,e.top,o,{edge:"tip"}),D("leaf-top","matte-leaf",[{point:s,z:e.top},{point:c,z:e.top},{point:d,z:e.top},{point:l,z:e.top}],o)];return Object.freeze(h.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||String(e.edge||"").localeCompare(String(t.edge||""))))}(e,o,t.leafThickness,a);return Object.freeze({id:t.id,sourceIndex:t.sourceIndex,type:t.type,leaf:e.leaf,d:`M ${q(r)} L ${q(s)} L ${q(l)} L ${q(c)} Z`,shadowD:`M ${q(n(e.hinge,0,a))} L ${q(n(o,0,a))}`,depth:Math.max(r[1],s[1]),material:d,thickness:"window"===t.type?0:t.leafThickness,surfaces:h})})}const K=1e-9,Z=e=>e.length>=2&&Number.isFinite(e[0])&&Number.isFinite(e[1]);function J(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n],a=e[(n+1)%e.length];t+=o[0]*a[1]-a[0]*o[1]}return t/2}function Q(e){return e.length>=3&&e.every(Z)&&Math.abs(J(e))>K}function X(e,t,n){const o=n[0]-t[0],a=n[1]-t[1],i=o*o+a*a,r=i?Math.max(0,Math.min(1,((e[0]-t[0])*o+(e[1]-t[1])*a)/i)):0;return Math.hypot(e[0]-t[0]-r*o,e[1]-t[1]-r*a)}function Y(e,t,n=1e-7){for(let o=0;o<t.length;o++)if(X(e,t[o],t[(o+1)%t.length])<=n)return!0;return!1}function ee(e,t){let n=!1;for(let o=0,a=t.length-1;o<t.length;a=o++){const i=t[o],r=t[a];i[1]>e[1]!=r[1]>e[1]&&e[0]<(r[0]-i[0])*(e[1]-i[1])/(r[1]-i[1])+i[0]&&(n=!n)}return n}function te(e){return Math.max(0,Math.abs(J(e.outer))-(e.holes||[]).reduce((e,t)=>e+Math.abs(J(t)),0))}function ne(e){return!!e.id&&Q(e.outer)&&(e.holes||[]).every(Q)&&te(e)>K}function oe(e,t){if(!ne(t)||Y(e,t.outer)||!ee(e,t.outer))return!1;for(const n of t.holes||[])if(Y(e,n)||ee(e,n))return!1;return!0}function ae(e){if(!ne(e))return null;if(e.safePoint&&oe(e.safePoint,e))return[e.safePoint[0],e.safePoint[1]];const t=e.outer.map(e=>e[0]),n=e.outer.map(e=>e[1]),o=Math.min(...t),a=Math.max(...t),i=Math.min(...n),r=Math.max(...n),s=[[(o+a)/2,(i+r)/2],[t.reduce((e,t)=>e+t,0)/t.length,n.reduce((e,t)=>e+t,0)/n.length]];for(let t=0;t<e.outer.length;t++){const n=e.outer[(t+e.outer.length-1)%e.outer.length],o=e.outer[t],a=e.outer[(t+1)%e.outer.length];s.push([(n[0]+o[0]+a[0])/3,(n[1]+o[1]+a[1])/3])}let l=null,c=-1/0;const d=t=>{if(!oe(t,e))return;const n=function(e,t){let n=1/0;for(const o of[t.outer,...t.holes||[]])for(let t=0;t<o.length;t++)n=Math.min(n,X(e,o[t],o[(t+1)%o.length]));return n}(t,e);n>c+K&&(l=t,c=n)};s.forEach(d);for(let e=1;e<16;e++)for(let t=1;t<16;t++)d([o+(a-o)*e/16,i+(r-i)*t/16]);return l}function ie(e){if(!Z(e.floorAnchor))return null;const t=e.roomsValidated?e.rooms:e.rooms.filter(ne),n=e.preferredRoomId&&t.find(t=>t.id===e.preferredRoomId)||null;let o=null;return"device"===e.kind?(n&&oe(e.floorAnchor,n)&&(o=n),o||(o=t.filter(t=>oe(e.floorAnchor,t)).sort((e,t)=>te(e)-te(t)||((e,t)=>e<t?-1:e>t?1:0)(e.id,t.id))[0]||null)):o=n,o?{id:o.id,area:te(o),safePoint:e.roomsValidated&&o.safePoint?[o.safePoint[0],o.safePoint[1]]:ae(o)}:null}function re(t,o,a,i=e,r=[0,0]){if(!Z(t)||!Z(o)||o[0]<0||o[1]<0||!Number.isFinite(a)||!Z(r))throw new Error("invalid isometric overlay footprint");return[[t[0]-o[0],t[1]-o[1]],[t[0]+o[0],t[1]-o[1]],[t[0]+o[0],t[1]+o[1]],[t[0]-o[0],t[1]+o[1]]].map(e=>{const t=n(e,a,i);return[t[0]+r[0],t[1]+r[1]]})}function se(e,t,n){return(t[0]-e[0])*(n[1]-e[1])-(t[1]-e[1])*(n[0]-e[0])}function le(e,t,n,o){const a=se(e,t,n),i=se(e,t,o),r=se(n,o,e),s=se(n,o,t);return(a>K&&i<-K||a<-K&&i>K)&&(r>K&&s<-K||r<-K&&s>K)||(Math.abs(a)<=K&&X(n,e,t)<=K||Math.abs(i)<=K&&X(o,e,t)<=K||Math.abs(r)<=K&&X(e,n,o)<=K||Math.abs(s)<=K&&X(t,n,o)<=K)}function ce(e,t,n,o){return le(e,t,n,o)?0:Math.min(X(e,n,o),X(t,n,o),X(n,e,t),X(o,e,t))}const de=new WeakMap;function he(e){if(!e.length)return null;let t=1/0,n=1/0,o=-1/0,a=-1/0;for(const i of e){if(!Z(i))return null;t=Math.min(t,i[0]),n=Math.min(n,i[1]),o=Math.max(o,i[0]),a=Math.max(a,i[1])}return[t,n,o,a]}function ue(e,t){if(!t)return he(e.outer);if(de.has(e))return de.get(e)??null;const n=he(e.outer);return de.set(e,n),n}function fe(e,t,n){return e[0]<=t[2]+n&&e[2]>=t[0]-n&&e[1]<=t[3]+n&&e[3]>=t[1]-n}function pe(e,t,n,o){return Math.min(t[0],n[0])<=e[2]+o&&Math.max(t[0],n[0])>=e[0]-o&&Math.min(t[1],n[1])<=e[3]+o&&Math.max(t[1],n[1])>=e[1]-o}function me(e,t,n,o,a){const i=ue(n,a);if(!i||!fe(t,i,o))return!1;if(e.some(e=>function(e,t){return!!ee(e,t.outer)&&!(t.holes||[]).some(t=>ee(e,t))}(e,n)))return!0;if(n.outer.some(n=>n[0]>=t[0]&&n[0]<=t[2]&&n[1]>=t[1]&&n[1]<=t[3]&&ee(n,e)))return!0;for(const a of[n.outer,...n.holes||[]])for(let n=0;n<e.length;n++){const i=(n+1)%e.length;for(let r=0;r<a.length;r++){const s=(r+1)%a.length;if(pe(t,a[r],a[s],o)&&ce(e[n],e[i],a[r],a[s])<=o+K)return!0}}return!1}function ge(e){return Q(e.outer)&&(e.holes||[]).every(Q)}function we(e,t,n){if(!oe(e,n)||!oe(t,n))return!1;for(const o of[n.outer,...n.holes||[]])for(let n=0;n<o.length;n++)if(le(e,t,o[n],o[(n+1)%o.length]))return!1;return!0}function ye(e,t,n){const o=t[0]-e[0],a=t[1]-e[1];return{from:e,to:t,visible:n,length:Math.hypot(o,a),angleDeg:180*Math.atan2(a,o)/Math.PI}}const ve="b3e08d50a47faaba7562dc080f267ca13de845113735892a9115a6cdd991392a",xe=e=>"wall-side"===e.layer?0:"wall-top"===e.layer?1:2,Me=e=>{if("wall-side"===e.layer)return`${e.face.polygon}:${e.face.ring}:${e.face.edge}`;if("wall-top"===e.layer)return String(e.face.component);const t=e.surface;return`${t.sourceIndex}:${t.leaf??-1}:${t.kind}:${t.jamb??-1}:${t.edge??""}:${t.id}:${t.material}`};function be(e,t){const n=[...e.sides.map(e=>({layer:"wall-side",depth:e.depth,face:e})),...e.topFaces.map(e=>({layer:"wall-top",depth:e.depth,face:e})),...t.map(e=>({layer:"opening",depth:e.depth,surface:e}))];return n.sort((e,t)=>e.depth-t.depth||xe(e)-xe(t)||Me(e).localeCompare(Me(t))),Object.freeze(n)}const Se=Object.freeze({textLatinAdvance:.72,textWideAsciiAdvance:1,textWideAdvance:1.1,textSpaceAdvance:.4,textWidthSafety:1.08,deviceShellInset:.134375,deviceShellGap:.1,deviceSectionGap:.08,deviceBadgeMinWidth:.7875,deviceBadgeHeight:.7875,deviceBadgeInlinePadding:.28,deviceValueInlinePadding:.32,deviceAuxiliaryExtent:.7,deviceLqiFontSize:.38,deviceLqiTop:.734375,deviceLqiBelowBottomBadgeTop:1.571875,devicePadding:.08,roomNameLineHeight:1.25,roomAreaLinkWidth:1.1,roomMetricsTopGap:.15,roomMetricFontSize:.75,roomMetricLineHeight:1.25,roomMetricIconWidth:1.05,roomMetricInnerGap:.12,roomMetricRowGap:.55,roomMetricMinWidth:11,roomPadding:.4,openingLockHalfSize:.62,roomMetricTextCharacters:Object.freeze({temperature:10,humidity:8,lqi:6,light:24})});function $e(e){return[...String(e)].reduce((e,t)=>/\s/.test(t)?e+Se.textSpaceAdvance:/[MW@#%&]/.test(t)?e+Se.textWideAsciiAdvance:e+(t.codePointAt(0)>255?Se.textWideAdvance:Se.textLatinAdvance),0)*Se.textWidthSafety}function ke(e,t){return $e(e)*z(t||e)}function ze(e,t){return[Math.max(Math.abs(e.left),Math.abs(e.right))+t,Math.max(Math.abs(e.top),Math.abs(e.bottom))+t]}function Ie(e){if("opening-lock"===e.kind){const t=(Number.isFinite(e.size)&&e.size>0?e.size:0)*Se.openingLockHalfSize;return[t,t]}if("room-label"===e.kind){const t=Number.isFinite(e.font)&&e.font>0?e.font:0,n=v(e.room.settings?.name_scale),o=v(e.room.settings?.label_scale),a=($e(e.room.name||"")+(e.room.area?Se.roomAreaLinkWidth:0))*n,i=Se.roomNameLineHeight*n,r=[e.display.labelTemp?Se.roomMetricTextCharacters.temperature:0,e.display.labelHum?Se.roomMetricTextCharacters.humidity:0,e.display.labelLqi&&e.room.area?Se.roomMetricTextCharacters.lqi:0,e.display.labelLight?Se.roomMetricTextCharacters.light:0].filter(e=>e>0),s=Se.roomMetricFontSize*o,l=r.length?Math.max(Se.roomMetricMinWidth,r.reduce((e,t)=>e+Se.roomMetricIconWidth+Se.roomMetricInnerGap+t*Se.textLatinAdvance*Se.textWidthSafety,0)+(r.length-1)*Se.roomMetricRowGap)*s:0,c=r.length?s*Se.roomMetricLineHeight:0,d=ze({left:-Math.max(a,l)/2,right:Math.max(a,l)/2,top:-i/2,bottom:r.length?i/2+Se.roomMetricsTopGap+c:i/2},Se.roomPadding);return[d[0]*t,d[1]*t]}const t=Number.isFinite(e.core)&&e.core>0?e.core:0,n=e.presentation,o=null==n.valueText?1:Math.max(1,ke(n.valueText,n.valueFullText||n.valueText)+Se.deviceValueInlinePadding),a=[];n.valueBadge&&a.push(Math.max(Se.deviceBadgeMinWidth,ke(n.valueBadge.text,n.valueBadge.fullText||n.valueBadge.text)+Se.deviceBadgeInlinePadding));for(const e of x(n)){const t=e.text+e.suffix;a.push(Math.max(Se.deviceBadgeMinWidth,ke(t,t)+Se.deviceBadgeInlinePadding))}const i=n.valueBadge?.position||"right";let r;if(!a.length||"left"!==i&&"right"!==i)if(a.length){const e=a.reduce((e,t)=>e+t,0)+(a.length-1)*Se.deviceSectionGap,t=Math.max(o,e),n=1+Se.deviceShellGap+Se.deviceBadgeHeight;r="bottom"===i?{left:-t/2-Se.deviceShellInset,right:t/2+Se.deviceShellInset,top:-.5-Se.deviceShellInset,bottom:-.5+n+Se.deviceShellInset}:{left:-t/2-Se.deviceShellInset,right:t/2+Se.deviceShellInset,top:.5-n-Se.deviceShellInset,bottom:.5+Se.deviceShellInset}}else r={left:-.5-Se.deviceShellInset,right:-.5+o+Se.deviceShellInset,top:-.5-Se.deviceShellInset,bottom:.5+Se.deviceShellInset};else{const e=Math.max(...a),t=a.length*Se.deviceBadgeHeight+(a.length-1)*Se.deviceSectionGap,n=o+Se.deviceShellGap+e,s=Math.max(1,t);r="right"===i?{left:-.5-Se.deviceShellInset,right:-.5+n+Se.deviceShellInset,top:-s/2-Se.deviceShellInset,bottom:s/2+Se.deviceShellInset}:{left:.5-n-Se.deviceShellInset,right:.5+Se.deviceShellInset,top:-s/2-Se.deviceShellInset,bottom:s/2+Se.deviceShellInset}}const s=Se.deviceAuxiliaryExtent;if(r.left=Math.min(r.left,-s),r.right=Math.max(r.right,s),r.top=Math.min(r.top,-s),r.bottom=Math.max(r.bottom,s),n.pulse.animated){const e=Math.max(1,n.pulse.diameterScale)/2;r.left=Math.min(r.left,-e),r.right=Math.max(r.right,e),r.top=Math.min(r.top,-e),r.bottom=Math.max(r.bottom,e)}if(null!=n.lqiText){const e="bottom"===n.valueBadge?.position?Se.deviceLqiBelowBottomBadgeTop:Se.deviceLqiTop,t=$e(n.lqiText)*Se.deviceLqiFontSize/2;r.left=Math.min(r.left,-t),r.right=Math.max(r.right,t),r.bottom=Math.max(r.bottom,e+Se.deviceLqiFontSize)}const l=ze(r,Se.devicePadding);return[l[0]*t,l[1]*t]}function Pe(e,t){return e.flatMap((e,n)=>e.orphanReason?[]:[{id:String(e.id||n),sourceIndex:n,type:e.type,x:e.rx,y:e.ry,angle:Number(e.angle)||0,length:e.rlen>0?e.rlen:.9*t,flipH:!!e.flip_h,flipV:!!e.flip_v}])}function Ce(e){return{id:e.id,x:e.x,y:e.y,w:e.w,h:e.h,poly:e.poly,wall_ids:e.wall_ids}}function je(e,t){const n=e?.partitionHost;if(!n)return null;const o="gate"===t.type?!t.flipV:t.flipV;return{sourceIndex:t.sourceIndex,hostId:n.host.id,t:n.t,depth:n.depth,face:p(n,o)}}function Ne(n,o=H){const a=Pe(n.openings,n.coordinateScale),r=a.map(e=>je(n.openings[e.sourceIndex],e)),p=i(t,n.cellCm),m=i(s,n.cellCm),g=i(l,n.cellCm);return{key:`${n.space.id}|${function(e){let t=2166136261;const n=e=>{if("number"!=typeof e)if("string"!=typeof e)if("boolean"!=typeof e)if(Array.isArray(e)){t=R(t,e.length);for(const t of e)n(t)}else{if(e&&"object"==typeof e){const t=e;for(const e of Object.keys(t).sort())n(e),n(t[e]);return}t=R(t,-1)}else t=R(t,e?1:0);else for(const n of e)t=R(t,n.codePointAt(0)||0);else t=R(t,e)};return n(e),t.toString(36)}({rooms:n.space.rooms.map(Ce),walls:n.walls,openCuts:n.openCuts,openings:a,openingHosts:r,openingGeometryPolicy:o,partitions:n.space.partitions,columns:n.space.wall_columns,cellCm:n.cellCm,gridPitch:n.gridPitch,wallKeyPitch:n.wallKeyPitch,camera:e,wallHeight:p,raisedHeight:g,floorEdgeHeight:m,algorithm:4})}`,build:()=>{n.onBuild();const i=c(n.space,n.cellCm,n.gridPitch,2e-4*n.gridPitch,n.partitionCuts()).all,s=n.roomOpenings(),l=n.walls.length||i.length?d(n.space.rooms,n.walls,n.openCuts,s,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale,i):null;if(l&&("failed-core"===l.status||"not-applicable"===l.status))throw new Error("wall boolean geometry failed");const m=l?.paperGeom??h(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale);if(!m)throw new Error("floor boolean geometry failed");const g=l?.openingIndex||u(n.space.rooms,n.walls,n.openCuts,n.wallKeyPitch,n.cellCm,n.gridPitch,n.coordinateScale),w=a.map((e,a)=>{const i=r[a],s="gate"===e.type?!e.flipV:e.flipV,l=i?i.face:n.walls.length||"gate"===e.type?f(g,{x:e.x,y:e.y,angle:e.angle,length:e.length,flip_v:s}):{ox:0,oy:0,cm:0,side:-1};return function(e,n=t,o=H){const a=e.face.cm??0;if(!F([e.x,e.y,e.angle,e.length,e.face.ox,e.face.oy,a,n])||!(e.length>0)||!(n>0)||-1!==e.face.side&&1!==e.face.side||a<0)throw new Error("invalid isometric opening input");const i=e.length/2,r=e.angle*Math.PI/180,s=T(Math.cos(r),Math.sin(r)),l=T(-Math.sin(r),Math.cos(r)),c=T(e.x,e.y),d=T(e.x-s[0]*i,e.y-s[1]*i),h=T(e.x+s[0]*i,e.y+s[1]*i),u=T(e.face.ox,e.face.oy),f=T(d[0]+u[0],d[1]+u[1]),p=T(h[0]+u[0],h[1]+u[1]),m=T(d[0]-u[0],d[1]-u[1]),g=T(h[0]-u[0],h[1]-u[1]),w=Object.freeze({center:c,tangent:s,normal:l,start:d,end:h}),y=Object.freeze({side:e.face.side,cm:a,depth:2*Math.hypot(e.face.ox,e.face.oy),offset:u,selectedStart:f,selectedEnd:p,oppositeStart:m,oppositeEnd:g}),v="passage"===e.type?[]:[Object.freeze({jamb:0,center:d,selected:f,opposite:m}),Object.freeze({jamb:1,center:h,selected:p,opposite:g})];let x;if("passage"===e.type)x=[];else if("gate"===e.type){const t=e.face.side*o.gateTurnDeg;x=[E(e,0,[-i,0],[i,0],t,0,n*o.gateTopRatio),E(e,1,[i,0],[-i,0],-t,0,n*o.gateTopRatio)]}else x="window"===e.type?[E(e,0,[-i,0],[i,0],-90,n*o.windowBottomRatio,n*o.windowTopRatio),E(e,1,[i,0],[-i,0],90,n*o.windowBottomRatio,n*o.windowTopRatio)]:[E(e,0,[-i,0],[e.length,0],-90,0,n*o.doorTopRatio)];return Object.freeze({id:e.id,sourceIndex:e.sourceIndex,type:e.type,wallHeight:n,leafThickness:n*o.leafThicknessRatio,frameThickness:n*o.frameThicknessRatio,axis:w,face:y,reveals:Object.freeze(v),leaves:Object.freeze(x.map(e=>Object.freeze({...e,hinge:T(e.hinge[0],e.hinge[1]),closedVector:T(e.closedVector[0],e.closedVector[1]),quarterVector:T(e.quarterVector[0],e.quarterVector[1])})))})}({...e,face:l},p,o)}),y=Object.freeze(w);return{walls:l?.components.flatMap(e=>e.geom)||[],floor:m,openings:y,openingSurfaces:Object.freeze(y.flatMap(t=>function(t,n=e){if("passage"===t.type)return Object.freeze([]);const o=[];if(t.face.depth>1e-9)for(const e of t.reveals)o.push(_("jamb-reveal","reveal",e.selected,e.opposite,0,t.wallHeight,n,{jamb:e.jamb}));if("window"!==t.type||!t.leaves.length)return Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)));const a=Math.min(...t.leaves.map(e=>e.bottom)),i=Math.max(...t.leaves.map(e=>e.top)),r=Math.min(t.frameThickness,Math.hypot(t.axis.end[0]-t.axis.start[0],t.axis.end[1]-t.axis.start[1])/4,(i-a)/4),s=L(t.axis.start,G(t.axis.tangent,r)),l=V(t.axis.end,G(t.axis.tangent,r)),c=t.face.depth>1e-9?[t.face.offset,T(-t.face.offset[0],-t.face.offset[1])]:[t.face.offset];for(const e of c){const c=L(t.axis.start,e),d=L(t.axis.end,e),h=L(s,e),u=L(l,e);o.push(_("window-frame-side","light-frame",c,h,a,i,n,{jamb:0}),_("window-frame-side","light-frame",u,d,a,i,n,{jamb:1}),_("window-frame-top","light-frame",h,u,Math.max(a,i-r),i,n))}return t.face.depth>1e-9&&o.push(D("window-sill","light-sill",[{point:t.face.selectedStart,z:a},{point:t.face.selectedEnd,z:a},{point:t.face.oppositeEnd,z:a},{point:t.face.oppositeStart,z:a}],n)),Object.freeze(o.sort((e,t)=>e.depth-t.depth||e.kind.localeCompare(t.kind)||(e.jamb??0)-(t.jamb??0)))}(t).map(e=>Object.freeze({...e,id:t.id,sourceIndex:t.sourceIndex,type:t.type}))))}}}}const Oe=e=>Array.isArray(e)?e:[];function Ae(e,t){const o=e=>Oe(e).flatMap(e=>Array.isArray(e)&&Number.isFinite(e[0])&&Number.isFinite(e[1])?[n([Number(e[0]),Number(e[1])],t)]:[]);return Oe(e).flatMap(e=>{const t=Oe(e);if(!t.length)return[];const n=o(t[0]);if(n.length<3)return[];return[{outer:n,holes:t.slice(1).map(o).filter(e=>e.length>=3)}]})}function Be(o){const a=i(t,o.cellCm),r=i(s,o.cellCm),c=i(l,o.cellCm),d=S(o.cache,o.source.key);let h=d.hit?d.value:void 0;if(!h){const i=o.source.build(),s=function(o,a=e,i=t){if(!Number.isFinite(i)||i<0)throw new Error("invalid wall height");const r=[],s=[],l=[],c=[];let d=0;for(let e=0;e<(o||[]).length;e++){const t=o[e],h=[];let u=-1/0;for(let o=0;o<(t||[]).length;o++){const s=N(t[o],o>0);if(s.length<3||Math.abs(j(s))<1e-9)continue;const f=O(s,a,i);r.push(f),h.push(f),u=Math.max(u,...s.map(e=>n(e,i,a)[1])),d+=s.length;for(let t=0;t<s.length;t++){const r=s[t],d=s[(t+1)%s.length],h=n(r,0,a),u=n(d,0,a);if(c.push(`M ${C(h)} L ${C(u)}`),A(r,d,a)<=1e-9)continue;const f=n(d,i,a),p=n(r,i,a),m=Object.freeze([h,u,f,p]);l.push({d:`M ${m.map(C).join(" L ")} Z`,points:m,depth:Math.max(h[1],u[1]),polygon:e,ring:o,edge:t})}}h.length&&s.push({d:h.join(" "),depth:u,component:e})}return l.sort((e,t)=>e.depth-t.depth||e.polygon-t.polygon||e.ring-t.ring||e.edge-t.edge),s.sort((e,t)=>e.depth-t.depth||e.component-t.component),{topPath:r.join(" "),topFaces:s,sides:l,contactPath:c.join(" "),edgeCount:d}}(i.walls,e,a),l=Ae(i.walls,a);h={geometry:s,floor:B(i.floor,r),wallSilhouettes:Object.freeze([...l,...s.sides.map(e=>({outer:e.points}))]),openings:i.openings,openingSurfaces:i.openingSurfaces},$(o.cache,o.source.key,h,8)}const u=function(e){let t=1/0,n=1/0,o=-1/0,a=-1/0;const i=(e,i=0)=>{t=Math.min(t,e[0]-i),n=Math.min(n,e[1]-i),o=Math.max(o,e[0]+i),a=Math.max(a,e[1]+i)};for(const t of e)if("passage"!==t.type){i(t.axis.start),i(t.axis.end),i(t.face.selectedStart),i(t.face.selectedEnd),i(t.face.oppositeStart),i(t.face.oppositeEnd);for(const e of t.leaves){const n=Math.hypot(e.closedVector[0],e.closedVector[1])+t.leafThickness/2;i(e.hinge,n)}}return F([t,n,o,a])?{x:t,y:n,w:o-t,h:a-n}:null}(h.openings),f=u?Re(o.liveFrame,u):o.liveFrame,p=k({rect:f,wallHeight:a,openingHeight:a,floorDepth:r,raisedHeight:c});return{key:o.source.key,...h,frame:p}}const Re=(e,t)=>{const n=Math.min(e.x,t.x),o=Math.min(e.y,t.y);return{x:n,y:o,w:Math.max(e.x+e.w,t.x+t.w)-n,h:Math.max(e.y+e.h,t.y+t.h)-o}},He=e=>{if(!e.length||!e.every(e=>Number.isFinite(e[0])&&Number.isFinite(e[1])))return null;const t=e.map(e=>e[0]),n=e.map(e=>e[1]),o=Math.min(...t),a=Math.min(...n);return{x:o,y:a,w:Math.max(...t)-o,h:Math.max(...n)-a}},Fe=(e,t)=>{const n=e.placement,o=t?n.visualScene:n.raisedScene,[a,i]=e.screenHalfSize,r=t?n.footprint:n.footprint.map(e=>[e[0]-n.nudgeScene[0],e[1]-n.nudgeScene[1]]);return[n.floorScene,...r,[o[0]-a,o[1]-i],[o[0]+a,o[1]-i],[o[0]+a,o[1]+i],[o[0]-a,o[1]+i]]},Te=(e,t)=>void 0===t?e:e.filter(e=>e.placement.owner?.id===t);function Le(e,t){return e?He(Te(e.entries,t).flatMap(e=>Fe(e,!0))):null}function Ve(e){const t=Te(e.entries,e.ownerId),n=He(t.flatMap(e=>Fe(e,!1))),o=n?Re(e.baseBounds,n):e.baseBounds,a=e.targetView(o);if(!(a&&a.w>0&&a.h>0&&[a.x,a.y,a.w,a.h].every(Number.isFinite)))return null;const i=e.stageSize;if(!(n&&i&&i.width>0&&i.height>0))return{bounds:o,view:a};const r=e=>Math.max(e.w/i.width,e.h/i.height),s=t=>{const o=48*t,a={x:n.x-o,y:n.y-o,w:n.w+2*o,h:n.h+2*o},i=Re(e.baseBounds,a),r=e.targetView(i);return r&&[r.x,r.y,r.w,r.h].every(Number.isFinite)&&r.w>0&&r.h>0?{bounds:i,view:r}:null};let l=0,c=Math.max(r(a),Number.EPSILON),d=s(c);for(let e=0;d&&r(d.view)>c*(1+1e-10)&&e<24;e++)l=c,c*=2,d=s(c);if(!d)return null;for(let e=0;e<40;e++){const e=(l+c)/2,t=s(e);if(!t)return null;r(t.view)<=e?(c=e,d=t):l=e}return d}const Ge=new WeakMap,We=2048,Ee=new WeakMap,qe=new WeakMap,De=new WeakMap;function _e(e,t){if(e.size!==t.size)return!1;for(const[n,o]of t)if(e.get(n)!==o)return!1;return!0}function Ue(e){const t=Ge.get(e.rooms);if(t)return t;const n=e.rooms.flatMap((e,t)=>{const n=w(e);return n&&n.length>=3?[{room:e,index:t,poly:n}]:[]}),o=Object.freeze(n.map(({room:e,index:t,poly:o})=>{const a=y(o,n.filter(e=>e.index!==t).map(e=>e.poly)),i={id:e.id||`room-index-${t}`,outer:o.map(e=>[e[0],e[1]]),holes:a.map(e=>e.map(e=>[e[0],e[1]]))};return{room:e,overlayRoom:{...i,safePoint:ae(i)||void 0}}}));return Ge.set(e.rooms,o),o}function Ke(o){const s=o.stageSize&&o.stageSize.width>0&&o.stageSize.height>0?Math.max(o.view.w/o.stageSize.width,o.view.h/o.stageSize.height):Math.max(o.view.w,o.view.h)/1e3,l=Ue(o.space),c=l.map(e=>e.overlayRoom),d=i(t,o.cellCm),h=i(a,o.cellCm),u=new Map,f=new Map,p=new Map,m=[];let g=Ee.get(o.wallSilhouettes);g||(g=new Map,Ee.set(o.wallSilhouettes,g));let w=qe.get(l);w||(w=new Map,qe.set(l,w));const y=o.iconPct*r(o.space)*o.kioskIconScale/100,v=o.deviceBasePct*r(o.space)*o.kioskIconScale/100,x=(i,r,l,u,f,p=!1)=>{const m=`${!1===o.resolveCollisions?"fit":"live"}\0${i}\0${r}`,y=[l[0],l[1],u[0],u[1],f||"",d,h,o.layers.shadows?1:0,p?1:0].join("|"),v=`${y}|${s}`,x=S(g,m);if(x.hit&&x.value.signature===v)return x.value.placement;if(x.hit&&x.value.shapeSignature===y&&s<=x.value.unitsPerPixel){const e=x.value.placement,t=e.nudgeDistanceCss*x.value.unitsPerPixel/s;if(!e.nearWallBefore||e.cleared&&t<=48)return e}const M=`${i}\0${r}`,b=[l[0],l[1],f||""].join("|"),k=S(w,M),z=k.hit&&k.value.signature===b?k.value.owner:ie({kind:i,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:f});k.hit&&k.value.signature===b||$(w,M,{signature:b,owner:z},We);const I=function(o){const i=o.camera||e,r=o.wallHeight??t,s=o.visualOffset??a,l=o.sceneUnitsPerCssPixel??1,c=o.safetyGapCssPx??4,d=o.maxNudgeCssPx??48;if(!Z(o.floorAnchor)||!Z(o.footprintHalfSize)||o.footprintHalfSize[0]<0||o.footprintHalfSize[1]<0||!Number.isFinite(r)||r<0||!Number.isFinite(s)||s<0||!Number.isFinite(l)||l<=0||!Number.isFinite(c)||c<0||!Number.isFinite(d)||d<0)throw new Error("invalid isometric overlay input");const h=[o.floorAnchor[0],o.floorAnchor[1]],u=n(h,0,i),f=(p=o.kind,!o.showBorders||"device"!==p&&"room-label"!==p&&"opening-lock"!==p?"floor":"raised");var p;if("floor"===f)return{plane:f,owner:null,floorAnchor:h,floorScene:u,raisedScene:u,visualScene:u,footprint:[],nudgeScene:[0,0],nudgeCss:[0,0],nudgeDistanceCss:0,nudged:!1,nearWallBefore:!1,nearWallAfter:!1,cleared:!0,capped:!1,grounding:{center:u,visible:!1},tether:ye(u,u,!1),status:"ok",reason:null};const m=r+s,g=n(h,m,i),w=o.ownerAlreadyResolved?o.resolvedOwner??null:ie(o),y=o.wallGeometryValidated??o.wallSilhouettes.every(ge),v=c*l,x=re(h,o.footprintHalfSize,m,i),M=e=>{const t=he(e);return!!t&&o.wallSilhouettes.some(n=>me(e,t,n,v,!0===o.wallGeometryValidated))},b=!y||M(x);let S=0,$=[0,0],k=null,z=!1,I=y?"ok":"degraded",P=y?null:"invalid-wall-geometry";if(y&&b)if(w)if(w.safePoint){const e=o.rooms.find(e=>e.id===w.id)||null,t=n(w.safePoint,m,i),a=t[0]-g[0],r=t[1]-g[1],s=Math.hypot(a,r);if(s<=K)I="degraded",P="invalid-safe-point";else{const t=a/s,n=r/s,i=Math.min(d,s/l),c=i*l/s,u=[h[0]+(w.safePoint[0]-h[0])*c,h[1]+(w.safePoint[1]-h[1])*c],f=[t*i*l,n*i*l],p=he([...x,...x.map(e=>[e[0]+f[0],e[1]+f[1]])]),m=p?o.wallSilhouettes.filter(e=>{const t=ue(e,!0===o.wallGeometryValidated);return!!t&&fe(p,t,v)}):o.wallSilhouettes,g=!!e&&we(h,u,e),y=e=>{const a=[t*e*l,n*e*l],i=x.map(e=>[e[0]+a[0],e[1]+a[1]]),r=he(i);return!!r&&m.some(e=>me(i,r,e,v,!0===o.wallGeometryValidated))},M=o.nudgeHintCss;if(Number.isFinite(M)&&M>=0&&M<=i){const t=M*l/s,n=[h[0]+(w.safePoint[0]-h[0])*t,h[1]+(w.safePoint[1]-h[1])*t];(g||e&&we(h,n,e))&&!y(M)&&(S=M,k=!1)}if(null===k){let t=null,n=0,o=!1;const a=Math.ceil(i);for(let r=1;r<=a;r++){const a=Math.min(i,r),c=a*l/s,d=[h[0]+(w.safePoint[0]-h[0])*c,h[1]+(w.safePoint[1]-h[1])*c];if(!(g||e&&we(h,d,e))){o=!0;break}if(!y(a)){t=a;break}n=a}if(null!==t){let e=n,o=t;for(let t=0;t<14;t++){const t=(e+o)/2;y(t)?e=t:o=t}S=o}else S=n,z=!0,I="degraded",P=o?"owner-boundary":"nudge-cap"}$=[t*S*l,n*S*l]}}else I="degraded",P="invalid-safe-point";else I="degraded",P="missing-owner";const C=[g[0]+$[0],g[1]+$[1]],j=re(h,o.footprintHalfSize,m,i,$),N=!y||(k??M(j)),O=S>K,A=O||b||N||!!o.hovered||!!o.focused||!!o.selected;return{plane:f,owner:w,floorAnchor:h,floorScene:u,raisedScene:g,visualScene:C,footprint:j,nudgeScene:$,nudgeCss:[$[0]/l,$[1]/l],nudgeDistanceCss:S,nudged:O,nearWallBefore:b,nearWallAfter:N,cleared:!N,capped:z,grounding:{center:u,visible:!1!==o.filtersSupported},tether:ye(u,C,A),status:I,reason:P}}({kind:i,floorAnchor:l,rooms:c,roomsValidated:!0,preferredRoomId:f,ownerAlreadyResolved:!0,resolvedOwner:z,nudgeHintCss:x.hit&&x.value.shapeSignature===y?x.value.placement.nudgeDistanceCss*x.value.unitsPerPixel/s:void 0,showBorders:!0,wallSilhouettes:!1===o.resolveCollisions?[]:o.wallSilhouettes,wallGeometryValidated:!0,footprintHalfSize:u,wallHeight:d,visualOffset:h,sceneUnitsPerCssPixel:s,filtersSupported:o.layers.shadows,hovered:!0,selected:p});return $(g,m,{signature:v,shapeSignature:y,unitsPerPixel:s,placement:I},We),I};for(const e of o.devices){const t=o.positionOf(e),n=o.presentationOf(e,o.showLqi),a=v*n.scale,i=Ie({kind:"device",core:a,presentation:n}),r=e.marker?.room_id||l.find(t=>!!e.area&&t.room.area===e.area)?.overlayRoom.id||null,s=x("device",e.id,[t.x,t.y],i,r,o.selectedDeviceId===e.id);u.set(e.id,s),m.push({id:e.id,kind:"device",placement:s,groundRadius:Math.max(.32*a,2),screenHalfSize:i})}for(const{room:e,overlayRoom:t}of l){if(!o.display.showNames||!e.name)continue;const n=o.labelPositionOf(e,o.space.id),a=.5*y*(o.labelScaleOf(e)*o.kioskFontScale*o.display.cardFontScale),i=Ie({kind:"room-label",font:a,room:e,display:o.display}),r=x("room-label",t.id,[n.x,n.y],i,t.id,o.focusedRoomId===e.id);f.set(e,r),m.push({id:t.id,kind:"room-label",placement:r,groundRadius:Math.max(.75*a,2),screenHalfSize:i})}const M=o.openings.filter(e=>!e.orphanReason&&("door"===e.type||"gate"===e.type)&&"string"==typeof e.lock&&!!e.lock&&o.openingEntityAvailable(e.lock));if(M.length){const e=o.openingWallIndex();for(const t of M){const n=Je(t,e,o.cellCm),a=n.floorAnchor,i=.62*y,r=Ie({kind:"opening-lock",size:i}),s=x("opening-lock",String(t.id),a,r,n.preferredRoomId,o.selectedOpeningId===t.id);p.set(String(t.id),s),m.push({id:String(t.id),kind:"opening-lock",placement:s,groundRadius:Math.max(.28*i,2),screenHalfSize:r})}}const b={devices:u,rooms:f,locks:p,entries:Object.freeze(m)},k=!1===o.resolveCollisions?"fit":"live";let z=De.get(o.wallSilhouettes);z||(z=new Map,De.set(o.wallSilhouettes,z));const I=z.get(k);return I&&function(e,t){return e.length===t.length&&t.every((t,n)=>{const o=e[n];return o.id===t.id&&o.kind===t.kind&&o.placement===t.placement&&o.groundRadius===t.groundRadius&&o.screenHalfSize[0]===t.screenHalfSize[0]&&o.screenHalfSize[1]===t.screenHalfSize[1]})}(I.entries,b.entries)&&_e(I.devices,b.devices)&&_e(I.rooms,b.rooms)&&_e(I.locks,b.locks)?I:(z.set(k,b),b)}function Ze(e,t,n){return Je(e,t,n).floorAnchor}function Je(e,t,n){const o=!e.flip_v,a="gate"===e.type?e.partitionHost?p(e.partitionHost,o):f(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen,flip_v:o}):null,[i,r]=m({x:e.rx,y:e.ry,angle:e.angle,flipV:!!e.flip_v,gateFace:a},n);if(e.partitionHost)return{floorAnchor:i,preferredRoomId:null};const s=g(t,{x:e.rx,y:e.ry,angle:e.angle,length:e.rlen},!0),l=r?"negative":"positive";return{floorAnchor:i,preferredRoomId:s[l]?.roomId||null}}function Qe(e){let t=!1;try{t="undefined"!=typeof CSS&&"function"==typeof CSS.supports&&CSS.supports("filter","blur(1px)")}catch{t=!1}let n=!1;try{n="function"==typeof matchMedia&&matchMedia("(forced-colors: active)").matches}catch{n=!0}return function(e){const t=!!e.showBorders;return{structural:t,panels:t&&!e.hideOpenings,shadows:t&&e.filtersSupported&&!e.forcedColors,materialNuance:t&&e.filtersSupported&&!e.forcedColors,floorSymbols:!e.hideOpenings&&!t}}({showBorders:e.showBorders,hideOpenings:e.hideOpenings,filtersSupported:t,forcedColors:n})}function Xe(e,t,n,o){if(!e.panels||!t)return[];return t.openings.flatMap(e=>{const t=n[e.sourceIndex];return t?U(e,o(t)):[]}).sort((e,t)=>e.depth-t.depth||e.sourceIndex-t.sourceIndex||e.leaf-t.leaf)}function Ye(e){const t=Qe(e.display),n=t.panels?Xe(t,e.scene,e.openings,e.amountOf):[],o=e.overlays(t),a=t=>({layers:t,panels:n,overlays:o,underlay:it(t,e.scene?.floor,e.cellCm),shadows:rt(t,n,e.scene?.geometry,e.cellCm),walls:st(e.projection,t,e.scene,n,e.cellCm),grounds:ot(o,t,e.cellCm),raised:at(o)});try{return a(t)}catch(e){if(!t.shadows&&!t.materialNuance)throw e;return a({...t,shadows:!1,materialNuance:!1})}}const et=()=>b``;function tt(e){return`translate(${i(4,e)} ${i(8,e)})`}function nt(e,t,n){const o=I(n);return b`<defs>
${"walls"===t&&e.materialNuance?b`
<linearGradient id="hp-iso-wall-side" data-hp-iso-material-def x1="0" y1="0" x2="0" y2="1">
<stop offset="0" class="iso-side-hi"></stop><stop offset="1" class="iso-side-lo"></stop>
</linearGradient>
<linearGradient id="hp-iso-wall-top" data-hp-iso-material-def x1="0" y1="0" x2="1" y2="1">
<stop offset="0" class="iso-top-hi"></stop><stop offset="1" class="iso-top-lo"></stop>
</linearGradient>
<pattern id="hp-iso-wall-texture" data-hp-iso-material-def patternUnits="userSpaceOnUse"
width="${12*o}" height="${12*o}">
<circle class="iso-texture-mark" cx="${2*o}" cy="${2*o}"
r="${.55*o}"></circle>
<path class="iso-texture-line" d="M ${5*o} ${10*o}
l ${5*o} ${-5*o}"></path>
</pattern>`:M}
${"underlay"===t&&e.materialNuance?b`
<pattern id="hp-iso-floor-texture" data-hp-iso-material-def patternUnits="userSpaceOnUse"
width="${14*o}" height="${14*o}">
<circle class="iso-texture-mark" cx="${3*o}" cy="${3*o}"
r="${.5*o}"></circle>
</pattern>`:M}
${"underlay"===t&&e.shadows?b`
<filter id="hp-iso-ambient-shadow" data-hp-iso-material-def x="-12%" y="-12%" width="124%" height="130%">
<feGaussianBlur stdDeviation="${7*o}"></feGaussianBlur>
</filter>`:M}
${"shadows"===t&&e.shadows?b`
<filter id="hp-iso-contact-shadow" data-hp-iso-material-def x="-8%" y="-20%" width="116%" height="140%">
<feGaussianBlur stdDeviation="${2.5*o}"></feGaussianBlur>
</filter>
<filter id="hp-iso-leaf-shadow" data-hp-iso-material-def x="-12%" y="-30%" width="124%" height="160%">
<feGaussianBlur stdDeviation="${2*o}"></feGaussianBlur>
</filter>`:M}
${"overlays"===t&&e.shadows?b`
<filter id="hp-iso-overlay-ground" data-hp-iso-material-def x="-45%" y="-80%" width="190%" height="260%">
<feGaussianBlur stdDeviation="${3*o}"></feGaussianBlur>
</filter>`:M}
</defs>`}function ot(e,t,n){if(!e)return et();const o=e.entries.map(e=>{const t=e.placement.grounding;return`${e.kind}\0${e.id}\0${t.center[0]}\0${t.center[1]}\0${t.visible?1:0}\0${e.groundRadius}`}).join("");return P([o,t.shadows,n],()=>b`
${nt(t,"overlays",n)}
<g class="iso-overlay-grounds" data-hp="iso-overlay-grounds"
aria-hidden="true" pointer-events="none">${e.entries.map(e=>{if(!t.shadows||!e.placement.grounding.visible)return M;const[o,a]=e.placement.grounding.center;return b`<ellipse class="iso-overlay-ground"
data-hp-iso-overlay-kind=${e.kind} data-id=${e.id}
cx=${o} cy=${a} rx=${e.groundRadius} ry=${Math.max(1,.32*e.groundRadius)}
transform=${tt(n)}></ellipse>`})}</g>`)}function at(e){return e?P([e],()=>b`
<g class="iso-raised-overlays" data-hp="iso-raised-overlays"
aria-hidden="true" pointer-events="none">
<g class="iso-overlay-tethers">${e.entries.map(e=>{const t=e.placement.tether;return t.visible?b`<line class="iso-overlay-tether"
data-hp-iso-overlay-kind=${e.kind} data-id=${e.id}
x1=${t.from[0]} y1=${t.from[1]}
x2=${t.to[0]} y2=${t.to[1]}></line>`:M})}</g>
</g>`):et()}function it(e,t,n){return e.structural&&t?b`<g class="iso-underlay" data-hp="iso-underlay" aria-hidden="true" pointer-events="none">
${nt(e,"underlay",n)}
${e.shadows&&t.footprintPath?b`<path class="iso-ambient-shadow" d=${t.footprintPath}
transform=${tt(n)}></path>`:M}
<g class="iso-floor-edge">${t.sides.map(t=>b`<path class="iso-floor-side" d=${t.d} data-component=${t.component}
data-edge=${t.edge}></path>${e.materialNuance?b`<path class="iso-material-texture iso-floor-texture" d=${t.d}></path>`:M}`)}</g>
</g>`:et()}function rt(e,t,n,o){return e.shadows&&n?b`<g class="iso-shadows" data-hp="iso-shadows" aria-hidden="true" pointer-events="none">
${nt(e,"shadows",o)}
<path class="iso-contact-shadow" d=${n.contactPath}
transform=${tt(o)}></path>
<g class="iso-leaf-shadows">${t.map(e=>b`<path class="iso-leaf-shadow" d=${e.shadowD}
data-id=${e.id} data-leaf=${e.leaf}
transform=${tt(o)}></path>`)}</g>
</g>`:et()}function st(e,t,n,o,a){if("iso"!==e||!t.structural||!n)return et();const i=t.panels?[...n.openingSurfaces,...o.flatMap(e=>e.surfaces.map(t=>({...t,id:e.id,sourceIndex:e.sourceIndex,type:e.type,leaf:e.leaf})))]:[],r=be(n.geometry,i);return b`<g class="iso-walls" data-hp="iso-walls" data-fingerprint=${n.key}>
${nt(t,"walls",a)}
<g class=${t.panels?"iso-wall-depth-queue iso-openings":"iso-wall-depth-queue"}
data-hp=${t.panels?"iso-openings":M}
aria-hidden="true" pointer-events="none">${r.map(e=>{if("wall-side"===e.layer){const n=e.face;return b`<path class="iso-wall-side" d=${n.d} data-edge=${n.edge}></path>${t.materialNuance?b`<path class="iso-material-texture iso-wall-texture" d=${n.d}></path>`:M}`}if("wall-top"===e.layer){const n=e.face;return b`<path class="iso-wall-top" d=${n.d} data-component=${n.component}
fill-rule="evenodd"></path>${t.materialNuance?b`<path class="iso-material-texture iso-wall-texture" d=${n.d}
fill-rule="evenodd"></path>`:M}`}const n=e.surface;return b`<path class="iso-opening-panel iso-${n.type} iso-opening-${n.kind} iso-material-${n.material}"
d=${n.d} data-id=${n.id} data-kind=${n.type}
data-surface=${n.kind} data-leaf=${n.leaf??M}></path>${t.materialNuance?b`<path class="iso-material-texture iso-wall-texture iso-opening-texture"
d=${n.d}></path>`:M}`})}</g>
</g>`}export{We as ISO_OVERLAY_PLACEMENT_CACHE_LIMIT,Se as ISO_RAISED_FOOTPRINT,ve as ISO_SCENE_RUNTIME_FINGERPRINT,Ke as buildIsoOverlayRenderScene,be as buildIsoWallDepthQueue,Ne as createIsoStructuralSource,tt as isoFixedLightTransform,Ze as isoOpeningLockAnchor,Je as isoOpeningLockPlacement,Ue as isoOverlayRooms,Le as isoOverlaySceneBounds,Ie as isoRaisedOverlayHalfSize,Pe as isoSourceOpenings,je as isoStructuralOpeningHost,Ce as isoStructuralRoomGeometry,Ae as isoWallSilhouettesOf,ot as renderIsoOverlayGrounds,at as renderIsoRaisedOverlays,rt as renderIsoShadows,it as renderIsoUnderlay,st as renderIsoWalls,Qe as resolveIsoDecorationLayers,Ye as resolveIsoFramePresentation,Xe as resolveIsoOpeningPanels,Ve as resolveIsoOverlayFitEnvelope,Be as resolveIsoScene};