+ `],customElements.get("houseplan-space-card")||customElements.define("houseplan-space-card",_r),window.customCards=window.customCards||[],window.customCards.find(t=>"houseplan-space-card"===t.type)||window.customCards.push({type:"houseplan-space-card",name:"House Plan — Space (static)",description:"Read-only static schematic of a single houseplan space, with a deep-link button.",preview:!1,documentation:"https://github.com/Matysh/houseplan-card"});const gr=4.166666666666667e-9;function mr(t){if(!Number.isFinite(t))return t;const e=Math.round(t/qs)*qs;return Math.abs(e-t)<=gr?t:e}const fr=(t,e,i,s)=>Math.hypot(i-t,s-e),vr=(t,e,i,s,n,o,r,a)=>Math.hypot(Math.max(Math.abs(n-t),Math.abs(n+r-(t+i))),Math.max(Math.abs(o-e),Math.abs(o+a-(e+s)))),br=(t,e,i,s,n,o,r)=>{const a=Math.max(Number(s)||0,0)/2,l=Math.PI/180,c=Math.cos(i*l)*a,h=Math.sin(i*l)*a,d=Math.cos(r*l)*a,p=Math.sin(r*l)*a,u=Math.max(fr(t+c,e+h,n+d,o+p),fr(t-c,e-h,n-d,o-p)),_=Math.max(fr(t+c,e+h,n-d,o-p),fr(t-c,e-h,n+d,o+p));return Math.min(u,_)},yr=t=>{const e=Number(t?.cell_cm);return e>0?e:5};const wr="1.59.0-beta.9",kr=1500,$r=new Map;let xr=0;const Sr=t=>`${window.innerWidth}x${window.innerHeight}|${location.pathname}|${JSON.stringify(t??{})}`;let Mr=1e4;const Cr="houseplan_card_layout_v1",Dr="houseplan_card_cfg_v1",Tr="houseplan_card_zoom_v1",zr="houseplan_card_nav_v1",Pr="houseplan_card_kiosk_v1",Ar=1e3,Rr=(t,e)=>{const i=Math.min(t.x,e.x),s=Math.min(t.y,e.y);return{x:i,y:s,w:Math.max(t.x+t.w,e.x+e.w)-i,h:Math.max(t.y+t.h,e.y+e.h)-s}},Er=(t,e,i)=>{const s=new Event(e,{bubbles:!0,composed:!0});s.detail=i??{},t.dispatchEvent(s)},Nr=(t,e)=>{let i,s=null;const n=(...n)=>{clearTimeout(i),s=n,i=window.setTimeout(()=>{i=void 0;const e=s;s=null,e&&t(...e)},e)};return n.flush=()=>{if(void 0===i)return;clearTimeout(i),i=void 0;const e=s;s=null,e&&t(...e)},n.pending=()=>void 0!==i,n},Or=t=>{try{t.target?.setPointerCapture?.(t.pointerId)}catch{}};class Ir extends lt{constructor(){super(...arguments),this._space="f1",this._layout={},this._serverStorage=!1,this._loadOk=!1,this._serverCanWrite=null,this._loading=!1,this._loadTries=0,this._serverCfg=null,this._cfgRev=0,this._unsubCfg=null,this._unsubLayout=null,this._layoutRev=0,this._devices=[],this._regSignature="",this._defPos={},this._newSyncKey="",this._tip=null,this._selId=null,this._toast="",this._mode="view",this._pendingNavMode=null,this._decorTool="select",this._decorStyle={color:"#607d8b",width:3,fill:!1},this._decorDraft=null,this._decorMove=null,this._decorSel=null,this._decorTextDialog=null,this._furnPalette=null,this._dtBox=null,this._dtDrag=null,this._bdDrag=null,this._slide="",this._tool="draw",this._wallDialog=null,this._drawWallField=null,this._rszSel=null,this._rszDrag=null,this._rszUndo=[],this._rszPreview=null,this._rszLive=null,this._path=[],this._cursorPt=null,this._mergeSel=null,this._openingDialog=null,this._openingInfo=null,this._opDrag=null,this._opMeasure=null,this._opShift=!1,this._mergeDialog=null,this._openWallAnchor=null,this._splitSel=null,this._pendingSplit=null,this._areaSel="",this._nameSel="",this._roomDialog=!1,this._roomEditId=null,this._roomFill="",this._roomTempSrc="",this._roomHumSrc="",this._roomSrcOpen=null,this._roomSrcFilter="",this._roomNameScale=1,this._roomLabelScale=1,this._zoom=1,this._view=null,this._zoomBySpace={},this._viewModeSnap=null,this._pointers=new Map,this._panStart=null,this._panLock=null,this._pinchStart=null,this._suppressClick=!1,this._hdrH=118,this._booting=!0,this._bootFading=!1,this._bootLastH=-1,this._bootStart=0,this._bootLastChange=0,this._bootSoft=!1,this._tapConfirm=null,this._onboardingShown=!1,this._rulesDialog=null,this._alignDialog=null,this._settingsDialog=null,this._sunRaysCache=null,this._skyElev=null,this._skySnap=!1,this._skySnapRaf=0,this._compassDrag=!1,this._importDialog=null,this._importQueue=[],this._importTotal=0,this._rulesCompiledSrc="",this._infoCard=null,this._markerDialog=null,this._spaceDialog=null,this._keyHandler=t=>this._onKey(t),this._warmVp=null,this._warmVpArmed=!1,this._warmRevivePending=!1,this._warmGen=++xr,this._warmKey=null,this._warmSlot=null,this._hashApplied=!1,this._navApplied=!1,this._kioskScale={icon:1,font:1},this._kioskDialog=!1,this._senseRt=new Map,this._vacRt=new Map,this._vacViewKey="",this._vacLastView=null,this._vacRaf=0,this._vacSrvTrails={},this._vacJumpOnce=!1,this._vacVisHandler=()=>{"visible"===document.visibilityState&&(this._vacJumpOnce=!0,this._skyElev=null,this.requestUpdate())},this._vacFit=null,this._kioskDots=!1,this._cyclePausedUntil=0,this._swipeStart=null,this._lastTap=0,this._onHashChange=()=>{const t=this._hashSpace();t&&this._model.find(e=>e.id===t)&&t!==this._space&&(this._space=t,this._selId=null,this._restoreZoom(),this.requestUpdate())},this._drag=null,this._rlResize=null,this._holdFired=!1,this._cfgEpoch=0,this._modelCache=null,this._showHidden=!1,this._connHooked=null,this._onConnReady=()=>{this._loadTries=0,clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._loading||(this._loadOk&&this._unsubCfg?this._reloadConfigOnly():this._loadFromServer())},this._signer=new ko(()=>this.requestUpdate()),this._dirtyPos=new Set,this._sentPos=new Map,this._persistLayout=Nr(()=>{if(this._serverStorage){const t=[...this._dirtyPos];this._dirtyPos.clear();for(const e of t){const t=this._layout[e];t&&(this._sentPos.set(e,t),this.hass.callWS({type:"houseplan/layout/update",device_id:e,pos:t}).then(t=>this._noteLayoutRev(t)).catch(t=>this._showToast(this._t("toast.pos_save_failed",{err:this._errText(t)}))).finally(()=>{this._sentPos.get(e)===t&&this._sentPos.delete(e)}))}this._cacheSnapshot()}else localStorage.setItem(Cr,JSON.stringify(this._layout))},600),this._frame=null,this._showFar=!1,this._writesPending=0,this._writeChain=Promise.resolve(),this._saveConfigDebounced=Nr(()=>{this._serverCfg&&this._writeConfig().catch(t=>{"conflict"===t?.code?(this._showToast(this._t("toast.conflict")),this._cancelPath(),this._reloadConfigOnly(!0)):this._showToast(this._t("toast.cfg_save_failed",{err:this._errText(t)}))})},500),this._toggleServerPlans=async()=>{const t=this._spaceDialog;if(t)if(t.pickSaved)this._spaceDialog={...t,pickSaved:!1};else{this._spaceDialog={...t,pickSaved:!0,savedBusy:!0};try{const t=await this.hass.callWS({type:"houseplan/plans/list"}),e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:t?.plans||[],savedBusy:!1})}catch(t){const e=this._spaceDialog;e&&(this._spaceDialog={...e,saved:[],savedBusy:!1}),this._showToast(this._t("toast.plans_list_failed",{err:this._errText(t)}))}}},this._aspectJob=null,this._sunShown=!1,this._sunOut=!1,this._sunOutTimer=0,this._openSettingsDialog=()=>{if(!this._norm)return;const t=this._glowRadiusCm,e=this._imperial?Math.round(t/30.48*10)/10:Math.round(t)/100;this._settingsDialog={colors:JSON.parse(JSON.stringify(this._fillColors)),glowRadius:e,bgColor:vi(this._settings,{bgColor:null})||null,northDeg:Ss(this._settings,{}),bgMode:Ms(this._settings,{}),sunRays:Cs(this._settings,{}),weatherEntity:Ds(this._settings)||"",busy:!1}},this._openAlignDialog=()=>{if(!this._norm||!this._serverCfg)return;const t=this._serverCfg.spaces||[],e=function(t,e){const i=JSON.parse(JSON.stringify(t||[])),s=JSON.parse(JSON.stringify(e||{}));let n=0,o=0,r=0,a=0,l="",c=0;const h={};let d=5;for(const t of i){const e=yr(t);null!=t?.id&&(h[String(t.id)]=e),e>d&&(d=e)}const p=(t,e,i,s=!1)=>{if(!(t>gr||s))return;n++,t>r&&(r=t);const o=t*Fs*e;o>a&&(a=o,l=i)};for(const t of i){const e=yr(t),i=null!=t?.id?String(t.id):"";for(const s of t.rooms||[]){o++;let t=0;if(s.poly?.length)s.poly=s.poly.map(e=>{const i=[mr(e[0]),mr(e[1])];return t=Math.max(t,fr(e[0],e[1],i[0],i[1])),i});else if(null!=s.x&&null!=s.y){const e=s.x,i=s.y,n=s.w||0,o=s.h||0,r=mr(e+n),a=mr(i+o),l=mr(e),c=mr(i),h=Math.max(qs,r-l),d=Math.max(qs,a-c);t=vr(e,i,n,o,l,c,h,d),s.x=l,s.y=c,s.w=h,s.h=d}p(t,e,i)}for(const s of t.decor||[]){o++;let t=0;if("line"===s.kind){const e=[mr(s.x1),mr(s.y1)],i=[mr(s.x2),mr(s.y2)];t=Math.max(fr(s.x1,s.y1,e[0],e[1]),fr(s.x2,s.y2,i[0],i[1])),s.x1=e[0],s.y1=e[1],s.x2=i[0],s.y2=i[1]}else{const e=mr(s.x),i=mr(s.y);if(null!=s.w&&null!=s.h){const n=mr(s.x+s.w),o=mr(s.y+s.h),r=Math.max(qs,n-e),a=Math.max(qs,o-i);t=vr(s.x,s.y,s.w,s.h,e,i,r,a),s.w=r,s.h=a}else t=fr(s.x,s.y,e,i);s.x=e,s.y=i}p(t,e,i)}for(const s of t.openings||[]){o++;const n=De([s.x,s.y],t.rooms||[],.025,{step:qs,length:Number(s.length)||0});if(!n)continue;const r=Number(s.angle),a=!(Number.isFinite(r)&&r===n.angle),l=br(s.x,s.y,Number.isFinite(r)?r:n.angle,Number(s.length)||0,n.x,n.y,n.angle);s.x=n.x,s.y=n.y,s.angle=n.angle,a&&c++,p(l,e,i,a)}}for(const[t,e]of Object.entries(s)){if(!e||"object"!=typeof e)continue;const i=e;if("number"!=typeof i.x||"number"!=typeof i.y)continue;o++;const n=mr(i.x),r=mr(i.y),a=fr(i.x,i.y,n,r);s[t]={...i,x:n,y:r};const l="string"==typeof i.s?i.s:"";p(a,h[l]??d,l)}return{spaces:i,layout:s,report:{moved:n,total:o,maxShift:r,maxShiftCm:a,maxSpace:l,rotated:c},changed:n>0}}(t,this._layout||{}),i=Math.ceil(10*e.report.maxShiftCm)/10,s=t.find(t=>null!=t?.id&&String(t.id)===e.report.maxSpace),n=t.length>1&&s?String(s.title||s.id):"";this._alignDialog={report:e.report,spaces:e.spaces,layout:e.layout,cm:i,where:n,busy:!1}},this._openRulesDialog=()=>{if(!this._norm)return;const t=this._settings.icon_rules,e=(t&&t.length?t:dt).map(t=>({...t}));this._rulesDialog={rules:e,test:"",busy:!1}},this._climateCache=null,this._gearPtCache=new WeakMap}get _canEdit(){return!!this._norm&&(!0===this._serverCanWrite||!1!==this._serverCanWrite&&!0===this.hass?.user?.is_admin)}get _kiosk(){return!!this._config?.kiosk}_showKioskDots(){this._kioskDots=!0,clearTimeout(this._kioskDotsTimer),this._kioskDotsTimer=window.setTimeout(()=>this._kioskDots=!1,2500)}_slideTo(t,e){if(t===this._space)return;const i=window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;this._space=t,this._selId=null,this._restoreZoom(),i||(this._slide=e,clearTimeout(this._slideTimer),this._slideTimer=window.setTimeout(()=>{this._slide="",this.requestUpdate()},260),this.requestUpdate())}_cycleTick(){if(this._kiosk&&Number(this._config?.cycle)>0&&Date.now()>=this._cyclePausedUntil&&this._model.length>1&&this._zoom<=1.001){const t=this._model.map(t=>t.id),e=t.indexOf(this._space);this._slideTo(t[(e+1)%t.length],"left"),this._showKioskDots()}}get _editing(){return"plan"===this._mode||"devices"===this._mode||"decor"===this._mode}get _markup(){return"plan"===this._mode}_hashSpace(){const t=/(?:^|[#&])space=([^&]+)/.exec(window.location.hash||"");return t?decodeURIComponent(t[1]):""}connectedCallback(){document.addEventListener("visibilitychange",this._vacVisHandler),super.connectedCallback(),window.addEventListener("keydown",this._keyHandler),this._signer.start(()=>this.hass,()=>Fi(this._serverCfg)),this._config?.kiosk&&Number(this._config?.cycle)>0&&(clearInterval(this._cycleTimer),this._cycleTimer=window.setInterval(()=>this._cycleTick(),1e3*Number(this._config.cycle))),window.addEventListener("hashchange",this._onHashChange),this._booting?this._bootWatch():this._bootFading&&(clearTimeout(this._bootTimer),this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220)),this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},kr)),!this._loadOk&&this._serverCfg&&this.hass&&this._scheduleLoadRetry(),!this._warmSlot&&this._config&&this._warmAdopt(),this._warmVp&&!this._warmRevivePending&&void 0===this._warmReviveTimer&&(this._warmRevivePending=!0,this._warmReviveTimer=window.setTimeout(()=>this._warmReviveDialog(),0))}disconnectedCallback(){document.removeEventListener("visibilitychange",this._vacVisHandler),this._vacRaf&&(cancelAnimationFrame(this._vacRaf),this._vacRaf=0),this._skySnapRaf&&(cancelAnimationFrame(this._skySnapRaf),this._skySnapRaf=0);for(const t of this._senseRt.values())clearTimeout(t.timer);window.removeEventListener("keydown",this._keyHandler),clearInterval(this._cycleTimer),clearTimeout(this._kioskDotsTimer),clearTimeout(this._kioskHoldTimer),clearTimeout(this._reloadRetry),clearTimeout(this._loadRetryTimer),this._loadRetryTimer=void 0,this._connHooked?.removeEventListener?.("ready",this._onConnReady),this._connHooked=null,this._signer.dispose(),clearTimeout(this._toastTimer),clearTimeout(this._slideTimer),clearTimeout(this._bootTimer),this._bootTimer=void 0,clearTimeout(this._bootSoftTimer),this._saveConfigDebounced.flush(),window.removeEventListener("hashchange",this._onHashChange),clearTimeout(this._holdTimer),this._roViewport?.disconnect(),this._roViewport=void 0,this._roHdr?.disconnect(),this._roHdr=void 0,this._onWinResize&&(window.removeEventListener("resize",this._onWinResize),this._onWinResize=void 0),this._unsubCfg&&(this._unsubCfg(),this._unsubCfg=null),this._unsubLayout&&(this._unsubLayout(),this._unsubLayout=null),clearTimeout(this._layoutSyncTimer),this._warmSnapshot(),this._warmRevivePending=!1,clearTimeout(this._warmReviveTimer),this._warmReviveTimer=void 0,this._warmRelease(),super.disconnectedCallback()}_onKey(t){if("Escape"===t.key&&this._vacFit)return this._vacFit=null,this._showToast(this._t("vac.cal_cancelled")),void t.stopPropagation();if("Escape"===t.key){if(this._tapConfirm)return void(this._tapConfirm=null);if(this._openingInfo)return void(this._openingInfo=null);if(this._infoCard)return void(this._infoCard=null);if(this._rulesDialog)return void(this._rulesDialog=null);if(this._alignDialog)return void(this._alignDialog=null);if(this._settingsDialog)return void(this._settingsDialog=null);if(this._markerDialog)return void(this._markerDialog=null);if(this._openingDialog)return void(this._openingDialog=null);if(this._decorTextDialog)return void(this._decorTextDialog=null);if(this._spaceDialog&&!this._roomDialog)return this._spaceDialog=null,this._importQueue=[],void(this._importTotal=0)}if("decor"===this._mode)return"Delete"!==t.key&&"Backspace"!==t.key||!this._decorSel||t.target?.closest?.("input, textarea, select")?void("Escape"===t.key&&(t.preventDefault(),this._decorDraft?this._decorDraft=null:this._furnPalette?this._furnPalette=null:this._decorSel?this._decorSel=null:"select"!==this._decorTool?this._decorTool="select":this._setMode("view"))):(t.preventDefault(),void this._decorDeleteSel());if(!this._markup)return;const e="Escape"===t.key||(t.ctrlKey||t.metaKey)&&"z"===t.key.toLowerCase();if(e){if(this._roomDialog)return t.preventDefault(),void this._roomDialogCancel();if("draw"===this._tool&&this._path.length)return t.preventDefault(),void this._undoPoint();if(e)return"resize"===this._tool?(t.preventDefault(),this._rszDrag?void this._rszCancelDrag():(t.ctrlKey||t.metaKey)&&"z"===t.key.toLowerCase()?void this._rszUndoPop():void(this._rszSel?this._rszSel=null:this._tool="draw")):"split"===this._tool?(t.preventDefault(),void(this._splitSel?.pts?.length?(this._splitSel={...this._splitSel,pts:this._splitSel.pts.slice(0,-1)},this._splitSel.pts.length||(this._cursorPt=null)):this._splitSel?this._splitSel=null:this._tool="draw")):"merge"===this._tool?(t.preventDefault(),void(this._mergeSel?this._mergeSel=null:this._tool="draw")):this._wallDialog?(t.preventDefault(),void(this._wallDialog=null)):"openwall"===this._tool?(t.preventDefault(),void(this._openWallAnchor?this._openWallAnchor=null:this._tool="draw")):void("opening"!==this._tool&&"wallthick"!==this._tool&&"delroom"!==this._tool||(t.preventDefault(),this._tool="draw"))}}_undoPoint(){this._path.length&&(this._path=this._path.slice(0,-1))}static getConfigElement(){return document.createElement("houseplan-card-editor")}static getStubConfig(){return{type:"custom:houseplan-card"}}static _warmBootReset(t){for(const t of $r.values())for(const e of t)clearTimeout(e.evict);$r.clear(),Mr=t&&t>0?t:1e4}static _warmBootStats(){let t=0,e=0;const i=[];for(const s of $r.values())for(const n of s)t++,n.dlg&&(e++,i.push(n.dlg.kind));return{keys:$r.size,slots:t,dlgs:e,drafts:i}}setConfig(t){this._config={icon_size:2.5,show_temperature:!0,live_states:!0,show_signal:!0,...t},this._config.kiosk&&(this._booting=!1,this._bootFading=!1),t.default_floor&&(this._space=t.default_floor);try{this._zoomBySpace=JSON.parse(localStorage.getItem(Tr)||"{}")||{}}catch{this._zoomBySpace={}}try{const t=JSON.parse(localStorage.getItem(Pr)||"null");this._kioskScale={icon:Hi(t?.icon),font:Hi(t?.font)}}catch{}try{const e=JSON.parse(localStorage.getItem(Dr)||"null");if(e&&e.config&&Array.isArray(e.config.spaces)){this._serverCfg=e.config,this._cfgEpoch++,this._cfgRev=e.rev||0,this._layout=e.layout||{},this._serverStorage=!0;const i=this._hashSpace(),s=this._savedNav();i&&this._model.find(t=>t.id===i)?(this._space=i,this._hashApplied=!0):s?.space&&this._model.find(t=>t.id===s.space)?(this._space=s.space,this._navApplied=!0):t.default_floor?this._space=t.default_floor:this._model.find(t=>t.id===this._space)||(this._space=this._model[0]?.id||this._space),s?.mode&&"view"!==s.mode&&!t.kiosk&&(this._canEdit?this._mode=s.mode:this._pendingNavMode=s.mode)}}catch{}"view"!==this._mode||this._view||(this._zoom=this._zoomBySpace[this._space]||1),this.isConnected&&this._warmAdopt()}_warmAdopt(){if(this._config?.kiosk)return;const t=Sr(this._config);if(this._warmKey===t&&this._warmSlot)return;this._warmSlot&&this._warmRelease();const e=this.parentNode,i=this._warmIdx(e),s=$r.get(t);if(!s||!s.length)return;const n=s.find(t=>t.owner===this._warmGen);if(n)return clearTimeout(n.evict),n.evict=0,n.freed=0,n.live=!0,this._warmSlot=n,void(this._warmKey=t);const{slot:o,sure:r}=((t,e,i,s)=>{const n=t=>{const e=!!i&&t.place?.deref()===i;return e&&t.idx===s?4:t.live?0:e?3:2};let o=null,r=0,a=0,l=null;for(const i of t){if(i.owner===e)continue;l=i;const t=n(i);t<=0||(t>r?(o=i,r=t,a=1):t===r&&a++)}return!o||a>1?{slot:o||l,sure:!1}:{slot:o,sure:!0}})(s,this._warmGen,e,i);o&&(this._booting=!1,this._bootFading=!1,this._hdrH=o.hdrH,this._bootSoft=!0,this.isConnected&&(clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},kr)),this._warmKey=t,r?(clearTimeout(o.evict),o.evict=0,o.owner=this._warmGen,o.place=e?new WeakRef(e):null,o.idx=i,o.live=!0,this._warmSlot=o,this._warmVp=o.vp,this._warmAdoptViewport(this._config)):(this._warmSlot={owner:this._warmGen,place:e?new WeakRef(e):null,idx:i,live:!0,hdrH:o.hdrH,stageH:o.stageH,vp:null,dlg:null,freed:0,evict:0},s.push(this._warmSlot),this._warmTrim(s)))}_warmIdx(t){const e=t?.children;if(!e)return-1;for(let t=0;t
4;){const e=t.findIndex(t=>!t.live);if(e<0)break;clearTimeout(t[e].evict),t.splice(e,1)}}_warmScheduleEvict(t,e){if(clearTimeout(t.evict),!t.dlg)return;const i=t.freed,s=t.owner;t.evict=window.setTimeout(()=>{if(t.evict=0,t.freed!==i||t.owner!==s)return;t.dlg=null;const n=$r.get(e);if(!t.live&&n&&n.length>1){const e=n.indexOf(t);e>=0&&n.splice(e,1)}},Mr+250)}_warmAdoptViewport(t){const e=this._warmVp;e&&(!this._hashApplied&&this._model.find(t=>t.id===e.space)?(this._space=e.space,this._navApplied=!0,this._mode="view"!==e.mode&&this._canEdit&&!t.kiosk?e.mode:"view",this._pendingNavMode="view"===e.mode||this._canEdit||t.kiosk?null:e.mode,this._zoom=e.zoom,this._view=e.view?{...e.view}:null,this._viewModeSnap=e.snap?{...e.snap}:null,this._tool=e.tool,this._decorTool=e.decorTool,this._showHidden=e.showHidden,this._showFar!==e.showFar&&(this._showFar=e.showFar,this._frame=null),this._selId=e.selId,this._rszSel=e.rszSel,this._decorSel=e.decorSel,this._warmVpArmed=!0):this._warmVp=null)}_warmPatch(t,e=!1){if(this._config?.kiosk)return;const i=Sr(this._config);if(!this._warmSlot||this._warmKey===i){if(!this._warmSlot){if(!e)return;const t=this.parentNode;this._warmKey=i,this._warmSlot={owner:this._warmGen,place:t?new WeakRef(t):null,idx:this._warmIdx(t),live:!0,hdrH:this._hdrH,stageH:0,vp:null,dlg:null,freed:0,evict:0};const s=$r.get(i)||[];for(s.push(this._warmSlot),$r.set(i,s),this._warmTrim(s);$r.size>8;){const t=$r.keys().next().value;if(void 0===t||t===i)break;for(const e of $r.get(t)||[])clearTimeout(e.evict);$r.delete(t)}}Object.assign(this._warmSlot,t)}}_warmViewportState(){return{space:this._space,mode:this._mode,zoom:this._zoom,view:this._view?{...this._view}:null,snap:this._viewModeSnap?{...this._viewModeSnap}:null,tool:this._tool,decorTool:this._decorTool,showHidden:this._showHidden,showFar:this._showFar,selId:this._selId,rszSel:this._rszSel,decorSel:this._decorSel}}_warmDialogState(){const t=(t,e)=>({kind:t,space:this._space,mode:this._mode,data:e});return this._tapConfirm||this._alignDialog||this._mergeDialog||this._importDialog?null:this._openingInfo?t("openingInfo",this._openingInfo.id):this._infoCard?t("info",this._infoCard.id):this._rulesDialog?this._rulesDialog.busy?null:t("rules",this._rulesDialog):this._settingsDialog?this._settingsDialog.busy?null:t("settings",this._settingsDialog):this._markerDialog?this._markerDialog.busy?null:t("marker",this._markerDialog):this._openingDialog?t("opening",this._openingDialog):this._decorTextDialog?t("decorText",this._decorTextDialog):this._roomDialog?t("room",{editId:this._roomEditId,fill:this._roomFill,tempSrc:this._roomTempSrc,humSrc:this._roomHumSrc,srcOpen:this._roomSrcOpen,srcFilter:this._roomSrcFilter,nameScale:this._roomNameScale,labelScale:this._roomLabelScale,areaSel:this._areaSel,nameSel:this._nameSel,pendingSplit:this._pendingSplit,path:this._path}):this._spaceDialog?this._spaceDialog.busy?null:t("space",this._spaceDialog):null}_warmSnapshot(){if(this._booting||this._config?.kiosk)return;const t={vp:this._warmViewportState()};if(this._warmRevivePending||(t.dlg=this._warmDialogState()),this.isConnected&&this._warmSlot?.owner===this._warmGen){const e=this.parentNode;t.place=e?new WeakRef(e):null,t.idx=this._warmIdx(e)}this._warmPatch(t)}_warmReviveDialog(){this._warmRevivePending=!1;const t=this._warmSlot;if(this._warmReviveTimer=void 0,!t||!t.dlg)return;const e=t.dlg,i=t.freed;if(t.dlg=null,t.freed=0,clearTimeout(t.evict),t.evict=0,i&&!(Date.now()-i>Mr)&&e.space===this._space&&e.mode===this._mode){switch(e.kind){case"space":this._spaceDialog={...e.data,busy:!1,savedBusy:!1};break;case"marker":this._markerDialog={...e.data,busy:!1};break;case"settings":this._settingsDialog={...e.data,busy:!1};break;case"rules":this._rulesDialog={...e.data,busy:!1};break;case"opening":this._openingDialog={...e.data};break;case"decorText":this._decorTextDialog={...e.data};break;case"room":{const t=e.data;this._roomEditId=t.editId,this._roomFill=t.fill,this._roomTempSrc=t.tempSrc,this._roomHumSrc=t.humSrc,this._roomSrcOpen=t.srcOpen,this._roomSrcFilter=t.srcFilter,this._roomNameScale=t.nameScale,this._roomLabelScale=t.labelScale,this._areaSel=t.areaSel,this._nameSel=t.nameSel,this._pendingSplit=t.pendingSplit,this._path=t.path,this._roomDialog=!0;break}case"info":{const t=this._devices.find(t=>t.id===e.data);t&&(this._infoCard=t);break}case"openingInfo":{const t=(this._curSpaceCfg?.openings||[]).find(t=>t.id===e.data);t&&(this._openingInfo=t);break}}this.requestUpdate()}}_cacheSnapshot(){if(this._serverCfg)try{localStorage.setItem(Dr,JSON.stringify({config:this._serverCfg,rev:this._cfgRev,layout:this._layout}))}catch{}}getCardSize(){return 12}get _norm(){return!(!this._serverCfg||!this._serverCfg.spaces.length)}_cfgFingerprint(){const t=this._serverCfg?.spaces||[];let e=t.length+":";for(const i of t){e+=(i.id||"")+","+(i.plan_aspect||"")+","+(i.plan_url||"").length+","+(i.plan_x??"")+","+(i.plan_y??"")+","+(i.plan_scale??"")+","+(i.rooms?.length||0)+","+(i.openings?.length||0)+","+(i.decor?.length||0)+";";for(const t of i.rooms||[]){const i=t.poly?.[0],s=t.poly?.[t.poly.length-1];e+=(t.poly?.length||0)+"."+(t.id||"")+"."+(t.open_to||[]).join("+")+"."+(t.area||"")+"."+JSON.stringify(t.settings||0)+"."+(t.x??"")+","+(t.y??"")+","+(t.w??"")+","+(t.h??"")+","+(i?i[0]+"/"+i[1]:"")+","+(s?s[0]+"/"+s[1]:"")+";"}}return e}get _model(){if(!this._serverCfg)return[];const t=this._cfgEpoch+"|"+this._cfgFingerprint();if(this._modelCache&&this._modelCache.key===t)return this._modelCache.model;const e=this._buildModel();return this._modelCache={key:t,model:e},e}_buildModel(){if(!this._serverCfg)return[];const t=this._renderCfg;return Ns(t).map((e,i)=>{const s=t.spaces[i]?.plan_url;return e.bg&&s?{...e,bg:{...e.bg,href:s}}:e})}_spaceModel(t){const e=this._model;return e.find(e=>e.id===(t??this._space))||e[0]}get _areaToSpace(){const t={};for(const e of this._model)for(const i of e.rooms)i.area&&(t[i.area]={space:e.id,room:i});return t}get _settings(){return this._serverCfg?.settings||{}}get _showAll(){return this._settings.filter_seeded?this._showHidden:!!this._settings.show_all}_toggleShowAll(){if(this._serverCfg){if(this._settings.filter_seeded)return this._showHidden=!this._showHidden,void this.requestUpdate();this._serverCfg={...this._serverCfg,settings:{...this._serverCfg.settings,show_all:!this._settings.show_all}},this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}}_seedHiddenDevices(){if(!this._serverCfg||!this._norm||!this._canEdit)return;const t=this._serverCfg,e=function(t){const{hass:e,areaToSpace:i,markers:s,settings:n,excluded:o,iconRules:r}=t,a=!1!==n.group_lights,l=Vo(e,a),c=new Set(l.map(t=>t.area)),h=Oo(e),d=new Set(s.map(t=>t.binding)),p=[];for(const t of Object.values(e.devices)){const s=t.area_id;if(!s||!i[s])continue;if("service"===t.entry_type)continue;if(d.has("device:"+t.id))continue;const n=h[t.id]||[],l=Io(e,t,n);let u=o.has(l)||"Group"===t.model||/scene/i.test(t.model||"")||/bridge/i.test((t.model||"")+(t.name||""))||"myheat"===l&&!!t.via_device_id;!u&&a&&c.has(s)&&"mdi:lightbulb"===Go(e,(t.name_by_user||t.name||"").trim(),t.model,n,r)&&(u=!0),u&&p.push("device:"+t.id)}return p}({hass:this.hass,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,firstSpaceId:this._model[0]?.id||"",iconRules:this._iconRules});if(!e.length&&t.settings?.filter_seeded)return;t.markers=t.markers||[];const i=[];for(const s of e){const e="h"+s.slice(s.indexOf(":")+1);t.markers.push({id:e,binding:s,hidden:!0}),i.push(s.slice(s.indexOf(":")+1))}const s={...t.settings||{},filter_seeded:!0};delete s.show_all,i.length&&Array.isArray(s.new_device_ids)&&(s.new_device_ids=s.new_device_ids.filter(t=>!i.includes(t))),t.settings=s,this._regSignature="",this._maybeRebuildDevices(),this._saveConfig(),this.requestUpdate()}get _iconRules(){const t=this._settings.icon_rules;if(!t||!Array.isArray(t)||!t.length)return;const e=JSON.stringify(t);return e!==this._rulesCompiledSrc&&(this._rulesCompiledSrc=e,this._rulesCompiled=pt(t)),this._rulesCompiled}get _fillColors(){return wi(this._settings)}get _excluded(){const t=this._settings.exclude_integrations;return t?new Set(t):ht}willUpdate(t){t?.has?.("hass")&&(this._vacTick(),this._senseTick()),this._skyPlan(),t.has("hass")&&this.hass&&(this._hookConnection(),!this._loadOk&&!this._loading&&this._loadTries<8&&this._loadFromServer(),this._maybeRebuildDevices())}updated(){this._skyRelease(),this._warmSnapshot(),this._dtMeasure();const t=this._stageEl;t&&!this._roViewport&&(this._roViewport=new ResizeObserver(()=>this._refitView()),this._roViewport.observe(t)),t&&this._booting&&!this._bootTimer&&this._bootWatch();const e=this.renderRoot.querySelector(".hdr");if(e&&t&&!this._roHdr){const i=()=>{const e=this.renderRoot.querySelector("ha-card");if(!e)return;const i=t.getBoundingClientRect().top-e.getBoundingClientRect().top,s=Math.min(Math.max(e.getBoundingClientRect().top,0),120),n=Math.round(i+s);n>=0&&Math.abs(n-this._hdrH)>1&&(this._hdrH=n),n>=0&&!this._booting&&!this._config?.kiosk&&t.clientHeight>0&&this._warmPatch({hdrH:n,stageH:t.clientHeight})};this._roHdr=new ResizeObserver(()=>requestAnimationFrame(i)),this._roHdr.observe(e),this._onWinResize=()=>requestAnimationFrame(i),window.addEventListener("resize",this._onWinResize),i()}if(t&&!this._view&&this._refitView(),this._serverStorage&&this._loadOk&&0===this._model.length&&!this._spaceDialog&&!this._importDialog&&!this._onboardingShown){this._onboardingShown=!0;const t=function(t){const e=t?.floors;if(!e||"object"!=typeof e)return[];const i=[];for(const t of Object.values(e))t&&t.floor_id&&i.push({id:t.floor_id,name:t.name||t.floor_id,level:t.level??null});return i.sort((t,e)=>{const i=t.level??1e9,s=e.level??1e9;return i!==s?i-s:t.name.localeCompare(e.name)}),i}(this.hass);t.length?this._importDialog={floors:t.map(t=>({...t,checked:!0}))}:this._openSpaceDialog("create")}}async _loadFromServer(){this._loading=!0,this._loadTries++;try{const[t,e]=await Promise.all([this.hass.callWS({type:"houseplan/config/get"}),this.hass.callWS({type:"houseplan/layout/get"})]);this._loadOk=!0,this._serverStorage=!0,"boolean"==typeof t?.can_write&&(this._serverCanWrite=t.can_write),this._pendingNavMode&&this._canEdit&&!this._config?.kiosk&&(this._mode=this._pendingNavMode,this._pendingNavMode=null);const i=t?.config;this._serverCfg=i&&Array.isArray(i.spaces)?i:null,this._cfgEpoch++,this._cfgRev=t?.rev||0,this._layout=e?.layout||{},this._layoutRev=e?.rev??0,this._unsubCfg||(this._unsubCfg=await this.hass.connection.subscribeEvents(t=>{(t?.data?.rev??-1)!==this._cfgRev&&this._reloadConfigOnly()},"houseplan_config_updated")),this.hass.callWS({type:"houseplan/trail/get"}).then(t=>{this._vacSrvTrails=t?.trails||{},this.requestUpdate()}).catch(()=>{}),this._unsubTrail||(this._unsubTrail=await this.hass.connection.subscribeEvents(async()=>{try{const t=await this.hass.callWS({type:"houseplan/trail/get"});this._vacSrvTrails=t?.trails||{},this.requestUpdate()}catch{}},"houseplan_trail_updated")),this._unsubLayout||(this._unsubLayout=await this.hass.connection.subscribeEvents(t=>this._onLayoutEvent(Number(t?.data?.rev??-1)),"houseplan_layout_updated"));const s=this._hashSpace(),n=this._savedNav();!this._hashApplied&&s&&this._model.find(t=>t.id===s)?(this._space=s,this._hashApplied=!0):n?.space&&!this._navApplied&&!this._hashApplied&&this._model.find(t=>t.id===n.space)?(this._space=n.space,this._navApplied=!0):this._norm&&!this._model.find(t=>t.id===this._space)&&(this._space=this._model[0]?.id||this._space),this._cacheSnapshot(),this._warmVpArmed&&this._space===this._warmVp?.space?this._warmVpArmed=!1:this._restoreZoom()}catch(t){if(this._serverCfg)this._scheduleLoadRetry();else if(this._loadTries>=8){this._serverStorage=!1;try{this._layout=JSON.parse(localStorage.getItem(Cr)||"{}")||{}}catch{this._layout={}}}}finally{this._loading=!1}this._regSignature="",this.requestUpdate()}async _reloadConfigOnly(t=!1){if(!t&&(this._saveConfigDebounced.pending()&&this._saveConfigDebounced.flush(),this._cfgWriting))return clearTimeout(this._reloadRetry),void(this._reloadRetry=window.setTimeout(()=>this._reloadConfigOnly(),400));try{const t=await this.hass.callWS({type:"houseplan/config/get"}),e=t?.config;this._serverCfg=e&&Array.isArray(e.spaces)?e:null,this._cfgEpoch++,this._cfgRev=t?.rev||0,"boolean"==typeof t?.can_write&&(this._serverCanWrite=t.can_write),this._pendingNavMode&&this._canEdit&&!this._config?.kiosk&&(this._mode=this._pendingNavMode,this._pendingNavMode=null),this._cacheSnapshot(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate()}catch(t){this._showToast(this._t("toast.cfg_reload_failed",{err:this._errText(t)}))}}_scheduleLoadRetry(){if(void 0!==this._loadRetryTimer)return;const t=Math.min(8e3,500*2**Math.min(4,Math.max(1,this._loadTries-7)));this._loadRetryTimer=window.setTimeout(()=>{this._loadRetryTimer=void 0,this._loadOk||this._loading||!this.hass||this._loadFromServer()},t)}_hookConnection(){const t=this.hass?.connection;t&&t!==this._connHooked&&(this._connHooked?.removeEventListener?.("ready",this._onConnReady),t.addEventListener?.("ready",this._onConnReady),this._connHooked=t)}_display(t){return this._signer.display(this.hass,t)}_resign(){this._signer.resign(this.hass,Fi(this._serverCfg))}_onLayoutEvent(t){t<=this._layoutRev||(clearTimeout(this._layoutSyncTimer),this._layoutSyncTimer=window.setTimeout(()=>{t<=this._layoutRev||this._reloadLayoutOnly()},200))}_noteLayoutRev(t){const e=t?.rev;"number"==typeof e&&e>this._layoutRev&&(this._layoutRev=e)}async _reloadLayoutOnly(){if(!this._serverStorage||!this.hass?.callWS)return;const t=new Map;for(const e of this._dirtyPos)this._layout[e]&&t.set(e,this._layout[e]);this._persistLayout.pending()&&this._persistLayout.flush();for(const[e,i]of this._sentPos)t.set(e,i);try{const e=await this.hass.callWS({type:"houseplan/layout/get"}),i={...e?.layout||{}};for(const[e,s]of t)i[e]=s;this._layout=i,this._layoutRev=e?.rev??this._layoutRev,this._cacheSnapshot(),this.requestUpdate()}catch{}}_maybeRebuildDevices(){const t=this.hass;if(!t?.devices||!t?.entities||!t?.areas)return;const e=Object.keys(t.devices).length+":"+Object.keys(t.entities).length+":"+Object.keys(t.areas).length+":"+(this._norm?"n":"l")+":"+er(t,this._config?.language);e===this._regSignature&&this._devices.length||(this._regSignature=e,this._devices=Yo({hass:t,areaToSpace:Object.fromEntries(Object.entries(this._areaToSpace).map(([t,e])=>[t,e.space])),markers:this._markers,settings:this._settings,excluded:this._excluded,showAll:this._showAll,firstSpaceId:this._model[0]?.id||"",loc:t=>this._t(t),iconRules:this._iconRules}),this._defPos=this._defaultPositions(),this._syncNewDevices(),this._seedHiddenDevices())}_syncNewDevices(){if(!this._norm||!this._loadOk||!this._serverCfg)return;const t=this._devices.filter(t=>!t.marker&&!t.virtual).map(t=>t.id).sort(),e=t.join(",");if(e===this._newSyncKey)return;this._newSyncKey=e;const i=this._settings,{fresh:s,known:n}=function(t,e){if(!Array.isArray(e))return{fresh:[],known:[...t]};const i=new Set(e),s=t.filter(t=>!i.has(t));return{fresh:s,known:s.length?[...e,...s]:e}}(t,i.known_devices);if(!Array.isArray(i.known_devices)||s.length){const t=[...new Set([...i.new_device_ids||[],...s])];this._serverCfg={...this._serverCfg,settings:{...i,known_devices:n,new_device_ids:t}},this._saveConfig()}}get _newIds(){const t=this._settings.new_device_ids;return new Set(Array.isArray(t)?t:[])}_ackNewDevice(t){if(!this._newIds.has(t)||!this._serverCfg)return;const e=this._settings;this._serverCfg={...this._serverCfg,settings:{...e,new_device_ids:(e.new_device_ids||[]).filter(e=>e!==t)}},this._saveConfig(),this.requestUpdate()}get _markers(){return this._serverCfg?.markers||[]}_roomLqi(t){if(!t)return null;const e=[];for(const i of this._devices){if(i.area!==t||i.virtual)continue;const s=Ho(this.hass,i.entities);null!=s&&e.push(s)}return Ye(e)}_roomBounds(t){if(t.poly&&t.poly.length){const e=t.poly.map(t=>t[0]),i=t.poly.map(t=>t[1]),s=Math.min(...e),n=Math.min(...i);return{x:s,y:n,w:Math.max(...e)-s,h:Math.max(...i)-n}}return{x:t.x??0,y:t.y??0,w:t.w??0,h:t.h??0}}_defaultPositions(){const t={},e=this._config?.icon_size??2.5;for(const i of this._model){const s=e/100*sn(i)*1.3;for(const e of i.rooms){if(!e.area)continue;const n=this._devices.filter(t=>t.area===e.area&&t.space===i.id);if(!n.length)continue;const o=this._roomBounds(e),r=.1*Math.min(o.w,o.h),a=o.w-2*r,l=o.h-2*r,c=Math.max(1,Math.round(Math.sqrt(n.length*a/Math.max(l,1)))),h=Math.ceil(n.length/c),d=a/c,p=l/Math.max(h,1),u=n.map((t,e)=>({x:o.x+r+d*(e%c+.5),y:o.y+r+p*(Math.floor(e/c)+.5)}));Ze(u,o,s,.5*r),n.forEach((e,i)=>t[e.id]=Us(u[i]))}}return t}_pos(t){const e=this._spaceModel(t.space),i=this._layout[t.id];if(i)if(this._norm){if(i.s===t.space)return{x:i.x*Ar,y:i.y*Ar}}else if(void 0===i.s)return{x:i.x,y:i.y};return this._defPos[t.id]?this._defPos[t.id]:Us(en(e))}_savePos(t,e,i,s=!1){if(this._norm){const n=this._gridPitch,o=s?e:Math.round(e/n)*n,r=s?i:Math.round(i/n)*n,a=this._layout[t.id]?.k;this._layout={...this._layout,[t.id]:{s:t.space,x:Bs(o/Ar),y:Bs(r/Ar),...a?{k:a}:{}}}}else this._layout={...this._layout,[t.id]:{x:Math.round(e),y:Math.round(i)}};this._dirtyPos.add(t.id),this._persistLayout()}_coverIndicator(t){return"cover"===t.tapAction?ri(t.entities):null}_actEntity(t){return this._coverIndicator(t)||t.primary}_stateClass(t){if(!this._config?.live_states)return"";const e=this._coverIndicator(t);if(e){const t=this.hass.states[e];return t?"unavailable"===t.state?"unavail":ai(t.state)?"covermove":"":""}const i=(t.marker?.controls||[]).filter(Ai);if(i.length)return i.some(t=>"on"===this.hass.states[t]?.state)?"on":"";if(qo(this.hass,t))return"on";const s=this._actEntity(t),n=s?this.hass.states[s]:void 0;if(!n)return"";if("unavailable"===n.state)return"unavail";const o=s.split(".")[0];if(["light","switch","fan","humidifier"].includes(o))return"on"===n.state?"on":"";if("climate"===o){const t=n.attributes?.hvac_action;return null!=t?["heating","cooling","drying","fan"].includes(t)?"on":"":["off","unknown"].includes(n.state)?"":"on"}if("cover"===o)return ai(n.state)?"covermove":"";if("valve"===o)return["open","opening"].includes(n.state)?"open":"";if("lock"===o)return["unlocked","open"].includes(n.state)?"open":"";if("binary_sensor"===o){const e=n.attributes?.device_class;if(["door","window","garage_door","opening","gas","smoke","moisture","problem"].includes(e))return"on"===n.state?"open":"";if("motion"===e){const e=this._senseRt.get(t.id);return e&&e.flashTs&&Date.now()-e.flashTs<3300?e.gen%2==0?"senseflash sf2":"senseflash":""}if(["occupancy","presence"].includes(e))return"on"===n.state?"sensehold":""}return"media_player"===o?["playing","on"].includes(n.state)?"on":"":"vacuum"===o&&["cleaning","returning"].includes(n.state)?"on":""}_liveTemp(t){if(!this._config?.show_temperature)return null;if(!0===t.marker?.use_climate_temp){const e=Wo(this.hass,t.entities);if(null!=e)return e}return"mdi:thermometer"!==t.icon&&"mdi:air-filter"!==t.icon?null:Uo(this.hass,t.entities)}_bindingHasClimate(t){if(t.startsWith("entity:"))return t.slice(7).startsWith("climate.");if(t.startsWith("device:")){const e=t.slice(7);for(const[t,i]of Object.entries(this.hass?.entities||{}))if(i?.device_id===e&&t.startsWith("climate."))return!0}return!1}_bindingCoverEntity(t){if(t.startsWith("entity:"))return ri([t.slice(7)]);if(t.startsWith("device:")){const e=t.slice(7);return ri(Object.entries(this.hass?.entities||{}).filter(([,t])=>t?.device_id===e).map(([t])=>t))}return null}_bindingCoverTap(t){const e=this._bindingCoverEntity(t);if(!e)return!1;const i=String(this.hass?.states?.[e]?.attributes?.device_class||"");return!oi.has(i)}_liveHum(t){return this._config?.show_temperature&&t.primary&&Bo(this.hass,t.primary)?jo(this.hass,t.entities):null}_openMoreInfo(t){t?Er(this,"hass-more-info",{entityId:t}):this._showToast(this._t("toast.no_entity"))}_ctxDevice(t,e){"view"===this._mode&&(t.preventDefault(),t.stopPropagation(),e.primary?this._openMoreInfo(e.primary):this._infoCard=e)}_clickDevice(t,e){if(t.stopPropagation(),this._drag?.moved||this._suppressClick||this._holdFired)return;if("plan"===this._mode)return;if("devices"===this._mode)return void this._openMarkerDialog(e);const i=this._coverIndicator(e),s=this._actEntity(e),n=s?s.split(".")[0]:null,o=(t,i)=>{e.marker?.tap_confirm?this._tapConfirm={text:t,exec:i}:i()},r=(e.marker?.controls||[]).filter(Ai);if("toggle"===e.tapAction&&r.length){const t=(a=r.map(t=>this.hass.states[t]?.state),a.some(t=>"on"===t)?"turn_off":"turn_on");return void o(this._t("confirm.tap_toggle",{name:e.name}),()=>{this.hass.callService("homeassistant",t,{entity_id:r}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))})}var a;const l=function(t,e,i,s){const n=t||e||("light"===i?"toggle":"info");return"more-info"===n?"more-info":"run"===n?"run"===t?"run":"info":"cover"===n?"cover"!==t||"cover"!==i||oi.has(String(s||""))?"info":"cover":"toggle"!==n||!i||ni.has(i)?"info":"toggle"===t?"toggle":si.has(i)?"cover"===i&&oi.has(String(s||""))?"info":"toggle":"info"}(e.tapAction,void 0,n,s?this.hass.states[s]?.attributes?.device_class:null);if("run"===l){const t=e.marker?.tap_target||"",i=function(t){const e=String(t||"").split(".")[0];return"automation"===e?{domain:"automation",service:"trigger"}:"script"===e?{domain:"script",service:"turn_on"}:"scene"===e?{domain:"scene",service:"turn_on"}:null}(t),s=this.hass.states[t];if(!i||!s)return void this._showToast(this._t("toast.run_target_missing"));const n=s.attributes?.friendly_name||t;return void o(this._t("confirm.tap_run",{name:n}),()=>{this.hass.callService(i.domain,i.service,{entity_id:t}).then(()=>this._showToast(this._t("toast.run_started",{name:n}))).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))})}if("cover"===l&&i){const t=function(t){const e=String(t||"");return"closed"===e?"open_cover":"open"===e?"close_cover":"opening"===e||"closing"===e?"stop_cover":"toggle"}(this.hass.states[i]?.state);return void o(this._t("confirm.tap_cover",{name:e.name}),()=>{this.hass.callService("cover",t,{entity_id:i}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))})}"toggle"===l&&e.primary?o(this._t("confirm.tap_toggle",{name:e.name}),()=>{this.hass.callService("homeassistant","toggle",{entity_id:e.primary}).catch(t=>this._showToast(this._t("toast.error",{err:this._errText(t)})))}):"more-info"===l&&e.primary?this._openMoreInfo(e.primary):this._infoCard=e}_t(t,e){return ir(er(this.hass,this._config?.language),t,e)}get _stageEl(){return this.renderRoot.querySelector(".stage")}_contentItems(t){const e=[];for(const i of this._devices){if(i.space!==t.id||i.hidden)continue;const s=this._pos(i);e.push({minX:s.x,minY:s.y,maxX:s.x,maxY:s.y})}if(t.id===this._space){for(const t of this._openingsR){const i=Number(t.angle)*Math.PI/180,s=Math.cos(i)*t.rlen/2,n=Math.sin(i)*t.rlen/2,o=Gs([[t.rx-s,t.ry-n],[t.rx+s,t.ry+n]]);o&&e.push(o)}const t=this._decorH;for(const i of this._decorList){const s=Gs("line"===i.kind?[[i.x1*Ar,i.y1*t],[i.x2*Ar,i.y2*t]]:[[i.x*Ar,i.y*t],[(i.x+(i.w||0))*Ar,(i.y+(i.h||0))*t]]);s&&e.push(s)}}return Ys(t,e)}_frameOf(){const t=this._spaceModel(),e=this._frame,i="view"!==this._mode;if(e&&e.id===t.id&&this._bdDrag)return e;if(e&&e.id===t.id&&e.model===t&&e.layout===this._layout&&e.devs===this._devices&&e.far===this._showFar&&e.grow===i)return e;const s=Qs(this._contentItems(t));let n=s.all||tn(t),o=this._showFar?n:s.core||tn(t);return e&&e.id===t.id&&i&&e.grow&&(o=Rr(e.rect,o),n=Rr(e.all,n)),this._frame={id:t.id,model:t,layout:this._layout,devs:this._devices,far:this._showFar,grow:i,rect:o,all:n,outliers:s.outliers},this._frame}_baseVb(){const t=this._frameOf().rect;return[t.x,t.y,t.w,t.h]}get _outliers(){return this._showFar?0:this._frameOf().outliers}_fitFar(){this._showFar=!0,this._frame=null,this._resetZoom()}_fitAll(){this._resetZoom()}_renderFarHint(){return this._kiosk||"view"!==this._mode||this._booting||!this._outliers?V:W`
${this._t("canvas.far_objects",{n:this._outliers})}
@@ -2635,7 +2635,7 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
style="left:${s.toFixed(1)}%;top:${n.toFixed(1)}%"
@click=${t=>{t.stopPropagation(),this._fitAll()}}>
- `}_stageAspect(){const t=this._stageEl,e=this._baseVb();return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(t){return this._view&&this._view.w?this._view:Xe(t,this._stageAspect())}_screenToVb(t,e){const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i?.clientWidth||1,o=i?.clientHeight||1;return[s.x+t/n*s.w,s.y+e/o*s.h]}_clampView(t,e){const i=(t,e,i,s)=>{const n=1*Math.max(e,s),o=i-n,r=i+s-e+n;return Math.max(Math.min(o,r),Math.min(Math.max(o,r),t))};return{w:t.w,h:t.h,x:i(t.x,t.w,e.x,e.w),y:i(t.y,t.h,e.y,e.h)}}_applyView(t,e,i){const s=this._baseVb(),n=Xe(s,this._stageAspect()),o=Math.min(Or.ZOOM_MAX,Math.max(Or.ZOOM_MIN,t)),r=n.w/o,a=n.h/o,l=this._viewOr(s),c=e??l.x+l.w/2,h=i??l.y+l.h/2;this._zoom=o,this._view=this._clampView({x:c-r/2,y:h-a/2,w:r,h:a},n)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const t=()=>{if(!this._booting)return;const e=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=e);const s=e-this._bootStart;s>=1200||s>=700&&i>0&&e-this._bootLastChange>=250?this._bootSettled():this._bootTimer=window.setTimeout(t,100)};this._bootTimer=window.setTimeout(t,100)}_bootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1;const t=this._stageEl?.clientHeight??0;!this._config?.kiosk&&t>0&&this._warmPatch({hdrH:this._hdrH,stageH:t,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},wr)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_refitView(){if(!this._stageEl)return;const t=this._view;this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}_zoomAt(t,e,i){const s=this._stageEl;if(!s)return;const n=Xe(this._baseVb(),this._stageAspect()),o=Math.min(Or.ZOOM_MAX,Math.max(Or.ZOOM_MIN,i)),r=s.clientWidth,a=s.clientHeight,l=this._screenToVb(t,e),c=n.w/o,h=n.h/o;this._zoom=o,this._view=this._clampView({x:l[0]-t/r*c,y:l[1]-e/a*h,w:c,h:h},n)}_onWheel(t){const e=this._stageEl;if(!e)return;t.preventDefault();const i=e.getBoundingClientRect(),s=t.deltaY<0?1.15:1/1.15;this._zoomAt(t.clientX-i.left,t.clientY-i.top,this._zoom*s),this._saveZoom()}_stepZoom(t){const e=this._stageEl;e&&(this._zoomAt(e.clientWidth/2,e.clientHeight/2,this._zoom*(t>0?1.4:1/1.4)),this._saveZoom())}_resetZoom(){const t=this._baseVb();this._zoom=1,this._view=Xe(t,this._stageAspect()),this._saveZoom()}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(Dr,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){const t=this._zoomBySpace[this._space]||1;this._zoom=t;const e=this._stageEl;if(e&&e.clientHeight){const e=this._baseVb();return this._applyView(t,e[0]+e[2]/2,e[1]+e[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const e=this._baseVb();this._applyView(t,e[0]+e[2]/2,e[1]+e[3]/2),this.requestUpdate()})}_stagePointerDown(t){if(this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:t.clientX,y:t.clientY,id:t.pointerId},t.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag)return;if(this._markup&&t.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&t.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(t))return;this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:t.clientX,sy:t.clientY,vx:e.x,vy:e.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){const t=[...this._pointers.values()],e=Math.hypot(t[0].x-t[1].x,t[0].y-t[1].y);this._pinchStart={dist:e,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(t){if(this._dtDrag?.pid!==t.pointerId)if(this._bdDrag?.pid!==t.pointerId)if(this._decorDraft?.pid!==t.pointerId)if(this._decorMove?.pid!==t.pointerId)if(this._pointers.has(t.pointerId)){if(this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(t),this._pinchStart&&this._pointers.size>=2){const t=[...this._pointers.values()],e=Math.hypot(t[0].x-t[1].x,t[0].y-t[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),s=(t[0].x+t[1].x)/2-i.left,n=(t[0].y+t[1].y)/2-i.top;this._zoomAt(s,n,this._pinchStart.zoom*e),this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const e=t.clientX-this._panStart.sx,i=t.clientY-this._panStart.sy;Math.abs(e)+Math.abs(i)>4&&(this._suppressClick=!0,clearTimeout(this._holdTimer)),null===this._panLock&&Math.abs(e)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(e)>1.5*Math.abs(i)?"swipe":"pan");const s=this._stageEl;if("pan"===this._panLock&&s){const t=this._baseVb(),n=this._viewOr(t),o=Xe(t,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-e/(s.clientWidth||1)*n.w,y:this._panStart.vy-i/(s.clientHeight||1)*n.h,w:n.w,h:n.h},o)}}}else this._markupMove(t);else this._decorMoveUpdate(t);else this._decorDraft={...this._decorDraft,b:this._snap(this._svgPoint(t),t)};else this._bdMove(t);else this._dtMove(t)}_stagePointerUp(t){if(this._kiosk){clearTimeout(this._kioskHoldTimer);const e=this._swipeStart;if(this._swipeStart=null,e&&e.id===t.pointerId){const i=t.clientX-e.x,s=t.clientY-e.y;if(Math.abs(i)+Math.abs(s)<8){const t=Date.now();t-this._lastTap<350&&this._resetZoom(),this._lastTap=t}const n="pan"===this._panLock?null:function(t,e,i,s,n,o=60){if(i>1.001||s.length<2)return null;if(Math.abs(t)
t.id),this._space);n&&(this._slideTo(n,i<0?"left":"right"),this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}if(this._dtDrag?.pid!==t.pointerId)if(this._bdDrag?.pid!==t.pointerId)if(this._decorDraft?.pid!==t.pointerId){if(this._decorMove?.pid===t.pointerId)return this._decorMove.moved&&this._saveConfig(),void(this._decorMove=null);this._pointers.delete(t.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,setTimeout(()=>this._suppressClick=!1,0))}else this._decorCommitDraft();else this._bdUp();else this._dtUp()}_clickRoom(t){var e;!this._suppressClick&&t.area&&(e="/config/areas/area/"+t.area,history.pushState(null,"",e),Rr(window,"location-changed",{replace:!1}))}_pointerDown(t,e){if("plan"===this._mode)return;if("view"===this._mode)return this._holdFired=!1,clearTimeout(this._holdTimer),void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._infoCard=e},600));t.preventDefault();const i=this._pos(e);this._drag={id:e.id,sx:t.clientX,sy:t.clientY,ox:i.x,oy:i.y,moved:!1},Nr(t),this._tip=null}_pointerMove(t,e){if(!this._drag||this._drag.id!==e.id)return;const i=this.renderRoot.querySelector(".stage");if(!i)return;const s=this._baseVb(),n=i.getBoundingClientRect(),o=this._viewOr(s),r=(t.clientX-this._drag.sx)/n.width*o.w,a=(t.clientY-this._drag.sy)/n.height*o.h;Math.abs(t.clientX-this._drag.sx)+Math.abs(t.clientY-this._drag.sy)>3&&(this._drag.moved=!0,clearTimeout(this._holdTimer));const l=Ws(this._drag.ox+r),c=Ws(this._drag.oy+a);this._savePos(e,l,c,t.shiftKey)}_pointerUp(t,e){if(clearTimeout(this._holdTimer),!this._drag||this._drag.id!==e.id)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&(this._selId=e.id,window.setTimeout(()=>this._drag=null,0))}_showToast(t){this._toast=t,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}get _noHover(){return Or._noHoverMq||Or._touchSeen}_notePointer(t){"touch"!==t.pointerType&&"pen"!==t.pointerType||(Or._touchSeen=!0,this._tip&&(this._tip=null))}_showTip(t,e,i,s,n){this._noHover||this._drag||(this._tip={x:t.clientX,y:t.clientY,title:e,meta:i,lqi:s,temp:n})}get _gridPitch(){return Ls}get _cellCm(){const t=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(t)&&t>0?t:5}_fmtLen(t,e){const i=function(t,e,i,s){return Math.hypot(e[0]-t[0],e[1]-t[1])/i*s}(t,e,this._gridPitch,this._cellCm);return $e(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const t=this._rszPreview;return t&&t.space===this._space?t.sp:this._serverCfg?.spaces.find(t=>t.id===this._space)}get _renderCfg(){const t=this._rszPreview;return t&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(e=>e.id===t.space?t.sp:e)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,Pr}get _segments(){const t=this._curSpaceCfg,e=this._spaceH;return Ce(t?.rooms||[]).map(t=>[t[0]*Pr,t[1]*e,t[2]*Pr,t[3]*e])}_savedNav(){try{return JSON.parse(localStorage.getItem(Tr)||"null")}catch{return null}}_saveNav(){try{localStorage.setItem(Tr,JSON.stringify({space:this._space,mode:this._mode}))}catch{}}_setMode(t){if(this._kiosk&&"view"!==t)return;if(this._mode===t)return;if(this._bootSoftCancel(),("plan"===t||"decor"===t)&&!this._norm)return void this._showToast(this._t("toast.markup_needs_server"));const e=!this._spaceModel().bg&&"view"===t!=("view"===this._mode);if("view"===this._mode&&"view"!==t){const t=this._view;this._viewModeSnap={space:this._space,zoom:this._zoom,cx:t?t.x+t.w/2:void 0,cy:t?t.y+t.h/2:void 0}}if(this._mode=t,e&&(this._zoom=1,this._view=null),"view"===t){const t=this._viewModeSnap;this._viewModeSnap=null,t&&t.space===this._space?(this._zoom=t.zoom,this._view=null,requestAnimationFrame(()=>{this._stageEl&&"view"===this._mode&&this._space===t.space&&(this._applyView(t.zoom,t.cx,t.cy),this._saveZoom(),this.requestUpdate())})):t&&this._restoreZoom()}this._path=[],this._cursorPt=null,this._tool="draw",this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._selId=null,this._rszSel=null,this._rszDrag=null,this._rszLive=null,this._rszPreview=null,this._rszUndo=[],this._tip=null,this._decorDraft=null,this._decorSel=null,this._decorTool="decor"===t&&this._curSpaceCfg?.plan_url?"backdrop":"select",this._bdDrag=null,this._dtDrag=null,this._dtBox=null,"plan"===t&&this._primeDrawWallField(),this._saveNav()}_primeDrawWallField(){null===this._drawWallField&&(this._drawWallField=kn(15,this._imperial))}get _drawWallFieldValue(){return null===this._drawWallField?kn(15,this._imperial):this._drawWallField}get _drawWallCm(){return $n(this._drawWallFieldValue,this._imperial)}_svgPoint(t){const e=this.renderRoot.querySelector(".stage").getBoundingClientRect();return this._screenToVb(t.clientX-e.left,t.clientY-e.top)}_snap(t,e=!1){const i="boolean"==typeof e?e:!!e?.shiftKey,s=this._gridPitch;return i?[Ws(t[0]),Ws(t[1])]:[Ws(ke(t[0],s)),Ws(ke(t[1],s))]}_samePt(t,e){return Pe(t,e)}_dropLegacySegments(){for(const t of this._serverCfg?.spaces||[])if(delete t.segments,Array.isArray(t.walls)){const e=lo(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]);t.walls=En(t.walls,t.rooms||[],Hs,1,e),t.walls.length||delete t.walls}}get _cfgWriting(){return this._writesPending>0}_writeConfig(){this._writesPending++,this._writeChain=this._writeChain.catch(()=>{}).then(async()=>{if(!this._serverCfg)return;this._dropLegacySegments();const t=await this.hass.callWS({type:"houseplan/config/set",config:this._serverCfg,expected_rev:this._cfgRev});this._cfgRev=t?.rev??this._cfgRev+1});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_roomAt(t){return this._spaceModel().rooms.find(e=>{const i=Se(e);return!!i&&Oe(t,i)})}_overlapRoom(t){return this._spaceModel().rooms.find(e=>{const i=Se(e);return!!i&&We(t,i)})}_pointInRoom(t,e){return e.poly?Ae(t,e.poly):null!=e.x&&t[0]>=e.x&&t[0]<=e.x+e.w&&t[1]>=e.y&&t[1]<=e.y+e.h}_markupClick(t){if(this._vacFit)return;if(!this._markup)return;if(this._suppressClick)return;if(this._drag||this._rlResize)return;const e=t.composedPath?.()||[];if(e.some(t=>t?.classList?.contains?.("roomlabel")||t?.classList?.contains?.("rlhandle")))return;const i=this._svgPoint(t);if("resize"===this._tool){if(this._rszDrag||e.some(t=>t?.classList?.contains?.("rszhandle")))return;const t=[...this._spaceModel().rooms].reverse().find(t=>this._pointInRoom(i,t));return void(this._rszSel=t?.id||null)}if("delroom"===this._tool)return void this._deleteWallClick(i);if("opening"===this._tool)return void this._openingClick(i,t.shiftKey);if("merge"===this._tool)return void this._mergeClick(i);if("wallthick"===this._tool)return void this._wallThickClick(i);if("openwall"===this._tool)return void this._openWallClick(i);if("split"===this._tool)return void this._splitClick(i,t.shiftKey);const s=this._snap(i,t),n=this._path.length>=3&&this._samePt(s,this._path[0]);if(!this._path.length)return void(this._path=[s]);const o=this._path[this._path.length-1];if(!this._samePt(s,o)){if(n){const t=this._overlapRoom(this._path);return t?void this._showToast(this._t("toast.room_overlap",{name:t.name||""})):(this._path=[...this._path,s],this._cursorPt=null,this._nameSel="",this._areaSel="",this._resetRoomDialogFields(),void(this._roomDialog=!0))}this._path=[...this._path,s]}}_rszRooms(){const t=[];for(const e of this._spaceModel().rooms){const i=e.id?Se(e):null;i&&t.push({id:e.id,poly:i})}return t}_rszOpenings(){return this._openingsR.map(t=>({id:t.id,x:t.rx,y:t.ry,length:t.rlen}))}_rszOpts(){return{minDim:this._cmToUnits(30),eps:.05*this._gridPitch}}_rszSnapshot(){const t=this._curSpaceCfg;return JSON.stringify({rooms:t?.rooms||[],openings:t?.openings||[],walls:t?.walls||[],open_spans:t?.open_spans||[]})}_rszRestore(t){const e=this._serverCfg?.spaces.find(t=>t.id===this._space);if(!e)return;const i=JSON.parse(t);e.rooms=i.rooms,e.openings=i.openings,Array.isArray(i.walls)&&i.walls.length?e.walls=i.walls:delete e.walls,Array.isArray(i.open_spans)&&i.open_spans.length?e.open_spans=i.open_spans:delete e.open_spans,this._cfgEpoch++,this.requestUpdate()}_rszApplyPreview(t,e){const i=this._rszDrag,s=this._serverCfg?.spaces.find(t=>t.id===this._space);if(!i||!s)return;const n=JSON.parse(i.snap),o={...s,rooms:n.rooms,openings:n.openings,walls:n.walls},r=this._spaceH;for(const[e,i]of Object.entries(t)){const t=o.rooms.find(t=>t.id===e);t&&(t.poly=i.map(t=>[t[0]/Pr,t[1]/r]),delete t.x,delete t.y,delete t.w,delete t.h)}for(const[t,i]of Object.entries(e)){const e=(o.openings||[]).find(e=>e.id===t);e&&(e.x=i[0]/Pr,e.y=i[1]/r)}this._rszPreview={space:this._space,sp:o},this._cfgEpoch++}_rszEdgeDown(t,e,i){if("resize"!==this._tool||this._rszDrag)return;t.stopPropagation(),t.preventDefault(),Nr(t);const s=this._rszRooms(),n=function(t,e,i){const s=t.find(t=>t.id===e);if(!s||!s.poly||s.poly.length<3)return null;if(i<0||i>=s.poly.length)return null;const n=[...s.poly[i]],o=[...s.poly[(i+1)%s.poly.length]];return{roomId:e,edge:i,a:n,b:o,n:Ji(s.poly,i)}}(s,e,i);n&&(this._rszDrag={kind:"edge",pid:t.pointerId,roomId:e,plan:n,rooms:s,openings:this._rszOpenings(),snap:this._rszSnapshot(),moved:!1,d:0,k:1,changed:[]})}_rszCornerDown(t,e,i,s){"resize"!==this._tool||this._rszDrag||(t.stopPropagation(),t.preventDefault(),Nr(t),this._rszDrag={kind:"scale",pid:t.pointerId,roomId:e,fixed:s,span0:Math.hypot(i[0]-s[0],i[1]-s[1])||1,rooms:this._rszRooms(),openings:this._rszOpenings(),snap:this._rszSnapshot(),moved:!1,d:0,k:1,changed:[]})}_rszMove(t){const e=this._rszDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const i=this._svgPoint(t);if("edge"===e.kind){const s=e.plan,n=(i[0]-s.a[0])*s.n[0]+(i[1]-s.a[1])*s.n[1],o=this._snap([s.a[0]+s.n[0]*n,s.a[1]+s.n[1]*n],t);let r=(o[0]-s.a[0])*s.n[0]+(o[1]-s.a[1])*s.n[1];if(r=function(t,e,i,s,n,o){if(!Number.isFinite(s)||Math.abs(s)<1e-9)return 0;const r=Math.sign(s);let a=Math.abs(s);const l=Math.max(n,1e-6);for(let s=0;s<4096&&a>1e-9;s++,a-=l){const s=r*a;if(cs(t,e,i,s,o))return s}return 0}(e.rooms,e.openings,s,r,this._gridPitch,this._rszOpts()),r===e.d&&e.moved)return;e.d=r,e.moved=!0;const a=rs(e.rooms,e.openings,s,r,this._rszOpts().eps);e.changed=Object.keys(a.polys),this._rszApplyPreview(a.polys,a.openings),this._rszLive=this._rszEdgeLabels(a,s)}else{const s=e.fixed,n=this._snap(i,t);let o=Math.hypot(n[0]-s[0],n[1]-s[1])/(e.span0||1);if(o=Math.max(.05,Math.min(20,o)),o=function(t,e,i,s,n,o){if(!Number.isFinite(n)||n<=0)return 1;if(ds(t,e,i,s,n,o))return n;let r=1,a=n;for(let n=0;n<28;n++){const n=(r+a)/2;ds(t,e,i,s,n,o)?r=n:a=n}return r}(e.rooms,e.openings,e.roomId,s,o,this._rszOpts()),o===e.k&&e.moved)return;e.k=o,e.moved=!0;const r=e.rooms.find(t=>t.id===e.roomId),a=e.rooms.filter(t=>t.id!==e.roomId).map(t=>t.poly),l=hs(r,e.openings,a,s,o,2*this._rszOpts().eps);e.changed=[e.roomId],this._rszApplyPreview({[e.roomId]:l.poly},l.openings),this._rszLive=this._rszScaleLabels(l.poly)}this.requestUpdate()}_rszUp(t){const e=this._rszDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const i=this._rszPreview;this._rszDrag=null,this._rszLive=null,this._rszPreview=null;if(!(e.moved&&("edge"===e.kind?Math.abs(e.d)>1e-9:Math.abs(e.k-1)>1e-9))||!i)return this._cfgEpoch++,void this.requestUpdate();const s=this._curSpaceCfg;if(s){s.rooms=i.sp.rooms,s.openings=i.sp.openings,Array.isArray(i.sp.walls)&&(i.sp.walls.length?s.walls=i.sp.walls:delete s.walls);for(const t of e.changed){const e=s.rooms.find(e=>e.id===t);e?.poly&&(e.poly=is(e.poly,1e-9))}const t=this._spaceH,n=[],o=[];for(const i of e.changed){const r=e.rooms.find(t=>t.id===i),a=s.rooms.find(t=>t.id===i);if(!r||!a?.poly)continue;const l=a.poly.map(e=>[e[0]*Pr,e[1]*t]);if(r.poly.length===l.length)for(let t=0;t30&&this._rszUndo.shift(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._saveConfig(),this.requestUpdate()}_rszCancelDrag(){this._rszDrag&&(this._rszDrag=null,this._rszLive=null,this._rszPreview=null,this._cfgEpoch++,this.requestUpdate())}_rszPointerCancel(t){const e=this._rszDrag;e&&e.pid===t.pointerId&&(t.stopPropagation(),this._rszCancelDrag())}_rszUndoPop(){for(let t=this._rszUndo.length-1;t>=0;t--){if(this._rszUndo[t].space!==this._space)continue;const[e]=this._rszUndo.splice(t,1);return this._rszRestore(e.snap),void this._saveConfig()}}_rszEdgeLabels(t,e){const i=this._rszDrag,s=[],n=t.polys[e.roomId]||i.rooms.find(t=>t.id===e.roomId).poly,o=n.length,r=e.edge,a=(r+1)%o;for(const[t,e]of[[n[(r-1+o)%o],n[r]],[n[r],n[a]],[n[a],n[(a+1)%o]]])s.push({x:(t[0]+e[0])/2,y:(t[1]+e[1])/2,text:this._fmtLen(t,e)});const l="mi"===this.hass?.config?.unit_system?.length,c=Object.keys(t.polys).length?Object.keys(t.polys):[e.roomId],h=this._spaceWalls,d=this._openPairs().flatMap(t=>t.segs);for(const e of c){const n=t.polys[e]||i.rooms.find(t=>t.id===e).poly,o=h.length&&Qn(Object.entries(t.polys).map(([t,e])=>({id:t,poly:e})),e,h,d,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)||n,r=Le(o);s.push({x:r[0],y:r[1],text:us(ps(o,this._gridPitch,this._cellCm),l),area:!0})}return s}_rszScaleLabels(t){const e="mi"===this.hass?.config?.unit_system?.length,i=t.map(t=>t[0]),s=t.map(t=>t[1]),n=Math.max(...i)-Math.min(...i),o=Math.max(...s)-Math.min(...s),r=this._spaceWalls,a=r.length&&this._rszSel&&Qn([{id:this._rszSel,poly:t}],this._rszSel,r,[],this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)||t,l=Le(a);return[{x:Math.min(...i),y:Math.min(...s),text:`${this._fmtLen([0,0],[n,0])} × ${this._fmtLen([0,0],[o,0])}`},{x:l[0],y:l[1],text:us(ps(a,this._gridPitch,this._cellCm),e),area:!0}]}_renderResizeLayer(t){const e=Math.max(.013*t.w,5),i=e/2,s=t=>t.toFixed(1),n=`M ${s(-.7*i)} 0 H ${s(.7*i)} M 0 ${s(-.22*i)} V ${s(-i)} M ${s(-.32*i)} ${s(-.6*i)} L 0 ${s(-i)} L ${s(.32*i)} ${s(-.6*i)} M 0 ${s(.22*i)} V ${s(i)} M ${s(-.32*i)} ${s(.6*i)} L 0 ${s(i)} L ${s(.32*i)} ${s(.6*i)}`,o=[],r=this._rszRooms();for(const t of r)for(let i=0;i`}_stageAspect(){const t=this._stageEl,e=this._baseVb();return t&&t.clientHeight?t.clientWidth/t.clientHeight:e[2]/e[3]}_viewOr(t){return this._view&&this._view.w?this._view:Xe(t,this._stageAspect())}_screenToVb(t,e){const i=this._stageEl,s=this._viewOr(this._baseVb()),n=i?.clientWidth||1,o=i?.clientHeight||1;return[s.x+t/n*s.w,s.y+e/o*s.h]}_clampView(t,e){const i=(t,e,i,s)=>{const n=1*Math.max(e,s),o=i-n,r=i+s-e+n;return Math.max(Math.min(o,r),Math.min(Math.max(o,r),t))};return{w:t.w,h:t.h,x:i(t.x,t.w,e.x,e.w),y:i(t.y,t.h,e.y,e.h)}}_applyView(t,e,i){const s=this._baseVb(),n=Xe(s,this._stageAspect()),o=Math.min(Ir.ZOOM_MAX,Math.max(Ir.ZOOM_MIN,t)),r=n.w/o,a=n.h/o,l=this._viewOr(s),c=e??l.x+l.w/2,h=i??l.y+l.h/2;this._zoom=o,this._view=this._clampView({x:c-r/2,y:h-a/2,w:r,h:a},n)}_bootWatch(){clearTimeout(this._bootTimer),this._bootStart=Date.now(),this._bootLastH=-1,this._bootLastChange=this._bootStart;const t=()=>{if(!this._booting)return;const e=Date.now(),i=this._stageEl?this._stageEl.clientHeight:0;i!==this._bootLastH&&(this._bootLastH=i,this._bootLastChange=e);const s=e-this._bootStart;s>=1200||s>=700&&i>0&&e-this._bootLastChange>=250?this._bootSettled():this._bootTimer=window.setTimeout(t,100)};this._bootTimer=window.setTimeout(t,100)}_bootSettled(){if(!this._booting)return;this._refitView(),this._booting=!1;const t=this._stageEl?.clientHeight??0;!this._config?.kiosk&&t>0&&this._warmPatch({hdrH:this._hdrH,stageH:t,vp:this._warmViewportState()},!0),this._bootFading=!0,this._bootTimer=window.setTimeout(()=>{this._bootFading=!1},220),this._bootSoft=!0,clearTimeout(this._bootSoftTimer),this._bootSoftTimer=window.setTimeout(()=>{this._bootSoft=!1},kr)}_bootSoftCancel(){this._bootSoft&&(clearTimeout(this._bootSoftTimer),this._bootSoft=!1)}_refitView(){if(!this._stageEl)return;const t=this._view;this._applyView(this._zoom,t?t.x+t.w/2:void 0,t?t.y+t.h/2:void 0),this.requestUpdate()}_zoomAt(t,e,i){const s=this._stageEl;if(!s)return;const n=Xe(this._baseVb(),this._stageAspect()),o=Math.min(Ir.ZOOM_MAX,Math.max(Ir.ZOOM_MIN,i)),r=s.clientWidth,a=s.clientHeight,l=this._screenToVb(t,e),c=n.w/o,h=n.h/o;this._zoom=o,this._view=this._clampView({x:l[0]-t/r*c,y:l[1]-e/a*h,w:c,h:h},n)}_onWheel(t){const e=this._stageEl;if(!e)return;t.preventDefault();const i=e.getBoundingClientRect(),s=t.deltaY<0?1.15:1/1.15;this._zoomAt(t.clientX-i.left,t.clientY-i.top,this._zoom*s),this._saveZoom()}_stepZoom(t){const e=this._stageEl;e&&(this._zoomAt(e.clientWidth/2,e.clientHeight/2,this._zoom*(t>0?1.4:1/1.4)),this._saveZoom())}_resetZoom(){const t=this._baseVb();this._zoom=1,this._view=Xe(t,this._stageAspect()),this._saveZoom()}_saveZoom(){if("view"===this._mode){this._zoomBySpace={...this._zoomBySpace,[this._space]:this._zoom};try{localStorage.setItem(Tr,JSON.stringify(this._zoomBySpace))}catch{}}}_restoreZoom(){const t=this._zoomBySpace[this._space]||1;this._zoom=t;const e=this._stageEl;if(e&&e.clientHeight){const e=this._baseVb();return this._applyView(t,e[0]+e[2]/2,e[1]+e[3]/2),void this.requestUpdate()}this._view=null,requestAnimationFrame(()=>{if(!this._stageEl)return;const e=this._baseVb();this._applyView(t,e[0]+e[2]/2,e[1]+e[3]/2),this.requestUpdate()})}_stagePointerDown(t){if(this._vacFit)return;if(this._kiosk&&(this._cyclePausedUntil=Date.now()+6e4,0===this._pointers.size?(this._swipeStart={x:t.clientX,y:t.clientY,id:t.pointerId},t.target.closest?.(".dev, .roomlabel, .oplock")||(clearTimeout(this._kioskHoldTimer),this._kioskHoldTimer=window.setTimeout(()=>{this._kioskDialog=!0,this._swipeStart=null},3e3))):(this._swipeStart=null,clearTimeout(this._kioskHoldTimer))),this._drag)return;if(this._markup&&t.target.closest?.(".roomlabel, .rlhandle, .rszhandle, .dev, .oplock, .op-hit, button"))return;if("devices"===this._mode&&t.target.closest(".dev"))return;if("decor"===this._mode&&this._decorPointerDown(t))return;this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY});const e=this._viewOr(this._baseVb());if(1===this._pointers.size)this._panStart={sx:t.clientX,sy:t.clientY,vx:e.x,vy:e.y},this._panLock=null,this._suppressClick=!1;else if(2===this._pointers.size){const t=[...this._pointers.values()],e=Math.hypot(t[0].x-t[1].x,t[0].y-t[1].y);this._pinchStart={dist:e,zoom:this._zoom},this._panStart=null,this._panLock=null}}get _swipeZone(){return this._kiosk&&this._zoom<=1.001&&this._model.length>1}_stagePointerMove(t){if(this._dtDrag?.pid!==t.pointerId)if(this._bdDrag?.pid!==t.pointerId)if(this._decorDraft?.pid!==t.pointerId)if(this._decorMove?.pid!==t.pointerId)if(this._pointers.has(t.pointerId)){if(this._pointers.set(t.pointerId,{x:t.clientX,y:t.clientY}),this._markup&&1===this._pointers.size&&this._markupMove(t),this._pinchStart&&this._pointers.size>=2){const t=[...this._pointers.values()],e=Math.hypot(t[0].x-t[1].x,t[0].y-t[1].y)/(this._pinchStart.dist||1),i=this._stageEl.getBoundingClientRect(),s=(t[0].x+t[1].x)/2-i.left,n=(t[0].y+t[1].y)/2-i.top;this._zoomAt(s,n,this._pinchStart.zoom*e),this._suppressClick=!0,this._saveZoom()}else if(this._panStart){const e=t.clientX-this._panStart.sx,i=t.clientY-this._panStart.sy;Math.abs(e)+Math.abs(i)>4&&(this._suppressClick=!0,clearTimeout(this._holdTimer)),null===this._panLock&&Math.abs(e)+Math.abs(i)>8&&(this._panLock=this._swipeZone&&Math.abs(e)>1.5*Math.abs(i)?"swipe":"pan");const s=this._stageEl;if("pan"===this._panLock&&s){const t=this._baseVb(),n=this._viewOr(t),o=Xe(t,this._stageAspect());this._view=this._clampView({x:this._panStart.vx-e/(s.clientWidth||1)*n.w,y:this._panStart.vy-i/(s.clientHeight||1)*n.h,w:n.w,h:n.h},o)}}}else this._markupMove(t);else this._decorMoveUpdate(t);else this._decorDraft={...this._decorDraft,b:this._snap(this._svgPoint(t),t)};else this._bdMove(t);else this._dtMove(t)}_stagePointerUp(t){if(this._kiosk){clearTimeout(this._kioskHoldTimer);const e=this._swipeStart;if(this._swipeStart=null,e&&e.id===t.pointerId){const i=t.clientX-e.x,s=t.clientY-e.y;if(Math.abs(i)+Math.abs(s)<8){const t=Date.now();t-this._lastTap<350&&this._resetZoom(),this._lastTap=t}const n="pan"===this._panLock?null:function(t,e,i,s,n,o=60){if(i>1.001||s.length<2)return null;if(Math.abs(t)t.id),this._space);n&&(this._slideTo(n,i<0?"left":"right"),this._saveNav(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._showKioskDots())}}if(this._dtDrag?.pid!==t.pointerId)if(this._bdDrag?.pid!==t.pointerId)if(this._decorDraft?.pid!==t.pointerId){if(this._decorMove?.pid===t.pointerId)return this._decorMove.moved&&this._saveConfig(),void(this._decorMove=null);this._pointers.delete(t.pointerId),this._pointers.size<2&&(this._pinchStart=null),0===this._pointers.size&&(this._panStart=null,this._panLock=null,setTimeout(()=>this._suppressClick=!1,0))}else this._decorCommitDraft();else this._bdUp();else this._dtUp()}_clickRoom(t){var e;!this._suppressClick&&t.area&&(e="/config/areas/area/"+t.area,history.pushState(null,"",e),Er(window,"location-changed",{replace:!1}))}_pointerDown(t,e){if("plan"===this._mode)return;if("view"===this._mode)return this._holdFired=!1,clearTimeout(this._holdTimer),void(this._holdTimer=window.setTimeout(()=>{this._holdFired=!0,this._infoCard=e},600));t.preventDefault();const i=this._pos(e);this._drag={id:e.id,sx:t.clientX,sy:t.clientY,ox:i.x,oy:i.y,moved:!1},Or(t),this._tip=null}_pointerMove(t,e){if(!this._drag||this._drag.id!==e.id)return;const i=this.renderRoot.querySelector(".stage");if(!i)return;const s=this._baseVb(),n=i.getBoundingClientRect(),o=this._viewOr(s),r=(t.clientX-this._drag.sx)/n.width*o.w,a=(t.clientY-this._drag.sy)/n.height*o.h;Math.abs(t.clientX-this._drag.sx)+Math.abs(t.clientY-this._drag.sy)>3&&(this._drag.moved=!0,clearTimeout(this._holdTimer));const l=Ws(this._drag.ox+r),c=Ws(this._drag.oy+a);this._savePos(e,l,c,t.shiftKey)}_pointerUp(t,e){if(clearTimeout(this._holdTimer),!this._drag||this._drag.id!==e.id)return;const i=this._drag.moved;this._drag=i?this._drag:null,i&&(this._selId=e.id,window.setTimeout(()=>this._drag=null,0))}_showToast(t){this._toast=t,clearTimeout(this._toastTimer),this._toastTimer=window.setTimeout(()=>{this._toast=""},3500)}get _noHover(){return Ir._noHoverMq||Ir._touchSeen}_notePointer(t){"touch"!==t.pointerType&&"pen"!==t.pointerType||(Ir._touchSeen=!0,this._tip&&(this._tip=null))}_showTip(t,e,i,s,n){this._noHover||this._drag||(this._tip={x:t.clientX,y:t.clientY,title:e,meta:i,lqi:s,temp:n})}get _gridPitch(){return Ls}get _cellCm(){const t=Number(this._curSpaceCfg?.cell_cm);return Number.isFinite(t)&&t>0?t:5}_fmtLen(t,e){const i=function(t,e,i,s){return Math.hypot(e[0]-t[0],e[1]-t[1])/i*s}(t,e,this._gridPitch,this._cellCm);return $e(i,"mi"===this.hass?.config?.unit_system?.length)}get _curSpaceCfg(){const t=this._rszPreview;return t&&t.space===this._space?t.sp:this._serverCfg?.spaces.find(t=>t.id===this._space)}get _renderCfg(){const t=this._rszPreview;return t&&this._serverCfg?{...this._serverCfg,spaces:this._serverCfg.spaces.map(e=>e.id===t.space?t.sp:e)}:this._serverCfg}get _spaceH(){return this._curSpaceCfg,Ar}get _segments(){const t=this._curSpaceCfg,e=this._spaceH;return Ce(t?.rooms||[]).map(t=>[t[0]*Ar,t[1]*e,t[2]*Ar,t[3]*e])}_savedNav(){try{return JSON.parse(localStorage.getItem(zr)||"null")}catch{return null}}_saveNav(){try{localStorage.setItem(zr,JSON.stringify({space:this._space,mode:this._mode}))}catch{}}_setMode(t){if(this._kiosk&&"view"!==t)return;if(this._mode===t)return;if(this._bootSoftCancel(),("plan"===t||"decor"===t)&&!this._norm)return void this._showToast(this._t("toast.markup_needs_server"));const e=!this._spaceModel().bg&&"view"===t!=("view"===this._mode);if("view"===this._mode&&"view"!==t){const t=this._view;this._viewModeSnap={space:this._space,zoom:this._zoom,cx:t?t.x+t.w/2:void 0,cy:t?t.y+t.h/2:void 0}}if(this._mode=t,e&&(this._zoom=1,this._view=null),"view"===t){const t=this._viewModeSnap;this._viewModeSnap=null,t&&t.space===this._space?(this._zoom=t.zoom,this._view=null,requestAnimationFrame(()=>{this._stageEl&&"view"===this._mode&&this._space===t.space&&(this._applyView(t.zoom,t.cx,t.cy),this._saveZoom(),this.requestUpdate())})):t&&this._restoreZoom()}this._path=[],this._cursorPt=null,this._tool="draw",this._mergeSel=null,this._mergeDialog=null,this._splitSel=null,this._pendingSplit=null,this._selId=null,this._rszSel=null,this._rszDrag=null,this._rszLive=null,this._rszPreview=null,this._rszUndo=[],this._tip=null,this._decorDraft=null,this._decorSel=null,this._decorTool="decor"===t&&this._curSpaceCfg?.plan_url?"backdrop":"select",this._bdDrag=null,this._dtDrag=null,this._dtBox=null,"plan"===t&&this._primeDrawWallField(),this._saveNav()}_primeDrawWallField(){null===this._drawWallField&&(this._drawWallField=kn(15,this._imperial))}get _drawWallFieldValue(){return null===this._drawWallField?kn(15,this._imperial):this._drawWallField}get _drawWallCm(){return $n(this._drawWallFieldValue,this._imperial)}_svgPoint(t){const e=this.renderRoot.querySelector(".stage").getBoundingClientRect();return this._screenToVb(t.clientX-e.left,t.clientY-e.top)}_snap(t,e=!1){const i="boolean"==typeof e?e:!!e?.shiftKey,s=this._gridPitch;return i?[Ws(t[0]),Ws(t[1])]:[Ws(ke(t[0],s)),Ws(ke(t[1],s))]}_samePt(t,e){return Pe(t,e)}_dropLegacySegments(){for(const t of this._serverCfg?.spaces||[])if(delete t.segments,Array.isArray(t.walls)){const e=lo(t.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]]);t.walls=En(t.walls,t.rooms||[],qs,1,e),t.walls.length||delete t.walls}}get _cfgWriting(){return this._writesPending>0}_writeConfig(){this._writesPending++,this._writeChain=this._writeChain.catch(()=>{}).then(async()=>{if(!this._serverCfg)return;this._dropLegacySegments();const t=await this.hass.callWS({type:"houseplan/config/set",config:this._serverCfg,expected_rev:this._cfgRev});this._cfgRev=t?.rev??this._cfgRev+1});return this._writeChain.finally(()=>{this._writesPending--})}_saveConfig(){this._cfgEpoch++,this._saveConfigDebounced()}_roomAt(t){return this._spaceModel().rooms.find(e=>{const i=Se(e);return!!i&&Oe(t,i)})}_overlapRoom(t){return this._spaceModel().rooms.find(e=>{const i=Se(e);return!!i&&We(t,i)})}_pointInRoom(t,e){return e.poly?Ae(t,e.poly):null!=e.x&&t[0]>=e.x&&t[0]<=e.x+e.w&&t[1]>=e.y&&t[1]<=e.y+e.h}_markupClick(t){if(this._vacFit)return;if(!this._markup)return;if(this._suppressClick)return;if(this._drag||this._rlResize)return;const e=t.composedPath?.()||[];if(e.some(t=>t?.classList?.contains?.("roomlabel")||t?.classList?.contains?.("rlhandle")))return;const i=this._svgPoint(t);if("resize"===this._tool){if(this._rszDrag||e.some(t=>t?.classList?.contains?.("rszhandle")))return;const t=[...this._spaceModel().rooms].reverse().find(t=>this._pointInRoom(i,t));return void(this._rszSel=t?.id||null)}if("delroom"===this._tool)return void this._deleteWallClick(i);if("opening"===this._tool)return void this._openingClick(i,t.shiftKey);if("merge"===this._tool)return void this._mergeClick(i);if("wallthick"===this._tool)return void this._wallThickClick(i);if("openwall"===this._tool)return void this._openWallClick(i);if("split"===this._tool)return void this._splitClick(i,t.shiftKey);const s=this._snap(i,t),n=this._path.length>=3&&this._samePt(s,this._path[0]);if(!this._path.length)return void(this._path=[s]);const o=this._path[this._path.length-1];if(!this._samePt(s,o)){if(n){const t=this._overlapRoom(this._path);return t?void this._showToast(this._t("toast.room_overlap",{name:t.name||""})):(this._path=[...this._path,s],this._cursorPt=null,this._nameSel="",this._areaSel="",this._resetRoomDialogFields(),void(this._roomDialog=!0))}this._path=[...this._path,s]}}_rszRooms(){const t=[];for(const e of this._spaceModel().rooms){const i=e.id?Se(e):null;i&&t.push({id:e.id,poly:i})}return t}_rszOpenings(){return this._openingsR.map(t=>({id:t.id,x:t.rx,y:t.ry,length:t.rlen}))}_rszOpts(){return{minDim:this._cmToUnits(30),eps:.05*this._gridPitch}}_rszSnapshot(){const t=this._curSpaceCfg;return JSON.stringify({rooms:t?.rooms||[],openings:t?.openings||[],walls:t?.walls||[],open_spans:t?.open_spans||[]})}_rszRestore(t){const e=this._serverCfg?.spaces.find(t=>t.id===this._space);if(!e)return;const i=JSON.parse(t);e.rooms=i.rooms,e.openings=i.openings,Array.isArray(i.walls)&&i.walls.length?e.walls=i.walls:delete e.walls,Array.isArray(i.open_spans)&&i.open_spans.length?e.open_spans=i.open_spans:delete e.open_spans,this._cfgEpoch++,this.requestUpdate()}_rszApplyPreview(t,e){const i=this._rszDrag,s=this._serverCfg?.spaces.find(t=>t.id===this._space);if(!i||!s)return;const n=JSON.parse(i.snap),o={...s,rooms:n.rooms,openings:n.openings,walls:n.walls,open_spans:n.open_spans};Array.isArray(n.open_spans)&&n.open_spans.length||delete o.open_spans;const r=this._spaceH;for(const[e,i]of Object.entries(t)){const t=o.rooms.find(t=>t.id===e);t&&(t.poly=i.map(t=>[t[0]/Ar,t[1]/r]),delete t.x,delete t.y,delete t.w,delete t.h)}for(const[t,i]of Object.entries(e)){const e=(o.openings||[]).find(e=>e.id===t);e&&(e.x=i[0]/Ar,e.y=i[1]/r)}const a=[],l=[];for(const t of i.changed){const e=i.rooms.find(e=>e.id===t),s=o.rooms.find(e=>e.id===t);if(!e||!s?.poly)continue;const n=s.poly.map(t=>[t[0]*Ar,t[1]*r]);if(e.poly.length===n.length)for(let t=0;t0?n:1,a=Math.max(.5*s,1e-9)*r,l=new Set,c=[];for(const n of t){let t=o.get(n.key)||"";if(!t){const o=Tn([n],r)[0];if(o)for(let n=0;n1.000001)continue;if(Jn(o.x,o.y,l[0],l[1],c[0],c[1])>a)continue;const m=h[0]+(d[0]-h[0])*Math.max(0,Math.min(1,g)),f=h[1]+(d[1]-h[1])*Math.max(0,Math.min(1,g)),[v,b]=Mn(h,d),y=Math.max(s*r,1e-6);t=Dn([m-v*y,f-b*y],[m+v*y,f+b*y],s,r);break}}t||(t=n.key),l.has(t)||(l.add(t),c.push({key:t,cm:n.cm}))}return c}(o.walls,a,l,this._wallKeyPitch,Ar))}this._rszPreview={space:this._space,sp:o},this._cfgEpoch++}_rszEdgeDown(t,e,i){if("resize"!==this._tool||this._rszDrag)return;t.stopPropagation(),t.preventDefault(),Or(t);const s=this._rszRooms(),n=function(t,e,i){const s=t.find(t=>t.id===e);if(!s||!s.poly||s.poly.length<3)return null;if(i<0||i>=s.poly.length)return null;const n=[...s.poly[i]],o=[...s.poly[(i+1)%s.poly.length]];return{roomId:e,edge:i,a:n,b:o,n:Ji(s.poly,i)}}(s,e,i);n&&(this._rszDrag={kind:"edge",pid:t.pointerId,roomId:e,plan:n,rooms:s,openings:this._rszOpenings(),snap:this._rszSnapshot(),moved:!1,d:0,k:1,changed:[]})}_rszCornerDown(t,e,i,s){"resize"!==this._tool||this._rszDrag||(t.stopPropagation(),t.preventDefault(),Or(t),this._rszDrag={kind:"scale",pid:t.pointerId,roomId:e,fixed:s,span0:Math.hypot(i[0]-s[0],i[1]-s[1])||1,rooms:this._rszRooms(),openings:this._rszOpenings(),snap:this._rszSnapshot(),moved:!1,d:0,k:1,changed:[]})}_rszMove(t){const e=this._rszDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const i=this._svgPoint(t);if("edge"===e.kind){const s=e.plan,n=(i[0]-s.a[0])*s.n[0]+(i[1]-s.a[1])*s.n[1],o=this._snap([s.a[0]+s.n[0]*n,s.a[1]+s.n[1]*n],t);let r=(o[0]-s.a[0])*s.n[0]+(o[1]-s.a[1])*s.n[1];if(r=function(t,e,i,s,n,o){if(!Number.isFinite(s)||Math.abs(s)<1e-9)return 0;const r=Math.sign(s);let a=Math.abs(s);const l=Math.max(n,1e-6);for(let s=0;s<4096&&a>1e-9;s++,a-=l){const s=r*a;if(cs(t,e,i,s,o))return s}return 0}(e.rooms,e.openings,s,r,this._gridPitch,this._rszOpts()),r===e.d&&e.moved)return;e.d=r,e.moved=!0;const a=rs(e.rooms,e.openings,s,r,this._rszOpts().eps);e.changed=Object.keys(a.polys),this._rszApplyPreview(a.polys,a.openings),this._rszLive=this._rszEdgeLabels(a,s)}else{const s=e.fixed,n=this._snap(i,t);let o=Math.hypot(n[0]-s[0],n[1]-s[1])/(e.span0||1);if(o=Math.max(.05,Math.min(20,o)),o=function(t,e,i,s,n,o){if(!Number.isFinite(n)||n<=0)return 1;if(ds(t,e,i,s,n,o))return n;let r=1,a=n;for(let n=0;n<28;n++){const n=(r+a)/2;ds(t,e,i,s,n,o)?r=n:a=n}return r}(e.rooms,e.openings,e.roomId,s,o,this._rszOpts()),o===e.k&&e.moved)return;e.k=o,e.moved=!0;const r=e.rooms.find(t=>t.id===e.roomId),a=e.rooms.filter(t=>t.id!==e.roomId).map(t=>t.poly),l=hs(r,e.openings,a,s,o,2*this._rszOpts().eps);e.changed=[e.roomId],this._rszApplyPreview({[e.roomId]:l.poly},l.openings),this._rszLive=this._rszScaleLabels(l.poly)}this.requestUpdate()}_rszUp(t){const e=this._rszDrag;if(!e||e.pid!==t.pointerId)return;t.stopPropagation();const i=this._rszPreview;this._rszDrag=null,this._rszLive=null,this._rszPreview=null;if(!(e.moved&&("edge"===e.kind?Math.abs(e.d)>1e-9:Math.abs(e.k-1)>1e-9))||!i)return this._cfgEpoch++,void this.requestUpdate();const s=this._curSpaceCfg;if(s){s.rooms=i.sp.rooms,s.openings=i.sp.openings,Array.isArray(i.sp.walls)&&(i.sp.walls.length?s.walls=i.sp.walls:delete s.walls),Array.isArray(i.sp.open_spans)&&i.sp.open_spans.length?s.open_spans=i.sp.open_spans:delete s.open_spans;for(const t of e.changed){const e=s.rooms.find(e=>e.id===t);e?.poly&&(e.poly=is(e.poly,1e-9))}this._commitOpenSpans(),Array.isArray(s.walls)&&s.walls.length&&(s.walls=En(s.walls,s.rooms||[],qs,1,this._cfgOpenCuts()),s.walls.length||delete s.walls)}this._rszUndo.push({space:this._space,snap:e.snap}),this._rszUndo.length>30&&this._rszUndo.shift(),this._suppressClick=!0,setTimeout(()=>this._suppressClick=!1,0),this._saveConfig(),this.requestUpdate()}_rszCancelDrag(){this._rszDrag&&(this._rszDrag=null,this._rszLive=null,this._rszPreview=null,this._cfgEpoch++,this.requestUpdate())}_rszPointerCancel(t){const e=this._rszDrag;e&&e.pid===t.pointerId&&(t.stopPropagation(),this._rszCancelDrag())}_rszUndoPop(){for(let t=this._rszUndo.length-1;t>=0;t--){if(this._rszUndo[t].space!==this._space)continue;const[e]=this._rszUndo.splice(t,1);return this._rszRestore(e.snap),void this._saveConfig()}}_rszEdgeLabels(t,e){const i=this._rszDrag,s=[],n=t.polys[e.roomId]||i.rooms.find(t=>t.id===e.roomId).poly,o=n.length,r=e.edge,a=(r+1)%o;for(const[t,e]of[[n[(r-1+o)%o],n[r]],[n[r],n[a]],[n[a],n[(a+1)%o]]])s.push({x:(t[0]+e[0])/2,y:(t[1]+e[1])/2,text:this._fmtLen(t,e)});const l="mi"===this.hass?.config?.unit_system?.length,c=Object.keys(t.polys).length?Object.keys(t.polys):[e.roomId],h=this._spaceWalls,d=this._openPairs().flatMap(t=>t.segs);for(const e of c){const n=t.polys[e]||i.rooms.find(t=>t.id===e).poly,o=h.length&&Qn(Object.entries(t.polys).map(([t,e])=>({id:t,poly:e})),e,h,d,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)||n,r=Le(o);s.push({x:r[0],y:r[1],text:us(ps(o,this._gridPitch,this._cellCm),l),area:!0})}return s}_rszScaleLabels(t){const e="mi"===this.hass?.config?.unit_system?.length,i=t.map(t=>t[0]),s=t.map(t=>t[1]),n=Math.max(...i)-Math.min(...i),o=Math.max(...s)-Math.min(...s),r=this._spaceWalls,a=r.length&&this._rszSel&&Qn([{id:this._rszSel,poly:t}],this._rszSel,r,[],this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)||t,l=Le(a);return[{x:Math.min(...i),y:Math.min(...s),text:`${this._fmtLen([0,0],[n,0])} × ${this._fmtLen([0,0],[o,0])}`},{x:l[0],y:l[1],text:us(ps(a,this._gridPitch,this._cellCm),e),area:!0}]}_renderResizeLayer(t){const e=Math.max(.013*t.w,5),i=e/2,s=t=>t.toFixed(1),n=`M ${s(-.7*i)} 0 H ${s(.7*i)} M 0 ${s(-.22*i)} V ${s(-i)} M ${s(-.32*i)} ${s(-.6*i)} L 0 ${s(-i)} L ${s(.32*i)} ${s(-.6*i)} M 0 ${s(.22*i)} V ${s(i)} M ${s(-.32*i)} ${s(.6*i)} L 0 ${s(i)} L ${s(.32*i)} ${s(.6*i)}`,o=[],r=this._rszRooms();for(const t of r)for(let i=0;ithis._rszEdgeDown(e,t.id,i)}
@pointermove=${t=>this._rszMove(t)}
@pointerup=${t=>this._rszUp(t)}
@@ -2645,7 +2645,7 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
@pointermove=${t=>this._rszMove(t)}
@pointerup=${t=>this._rszUp(t)}
@pointercancel=${t=>this._rszPointerCancel(t)}
- @lostpointercapture=${t=>this._rszPointerCancel(t)}>`),o.push(B``)}return B`${o}`}get _openingsR(){const t=this._curSpaceCfg,e=this._spaceH;return(t?.openings||[]).map(t=>({...t,rx:t.x*Pr,ry:t.y*e,rlen:t.length*Pr}))}_cmToUnits(t){return t/this._cellCm*this._gridPitch}get _decorList(){const t=this._curSpaceCfg;return Array.isArray(t?.decor)?t.decor:[]}get _decorH(){return Pr}_decorPointerDown(t){const e=this._decorTool;if("select"===e||"erase"===e?t.target.closest?.(".dshape"):null)return!0;if("line"===e||"rect"===e||"ellipse"===e){t.preventDefault();const i=this._snap(this._svgPoint(t),t);return this._decorDraft={kind:e,a:i,b:i,pid:t.pointerId},Nr(t),!0}if("text"===e){const e=this._snap(this._svgPoint(t),t);return this._decorTextDialog={x:Bs(e[0]/Pr),y:Bs(e[1]/this._decorH),text:"",color:this._decorStyle.color},!0}if("furniture"===e)return!!this._furnPalette&&(t.preventDefault(),this._furnPlace(this._svgPoint(t),t),!0);if(this._decorSel=null,this._bdMovable){const e=this._bdRect,i=this._svgPoint(t);if(i[0]>=e.x&&i[0]<=e.x+e.w&&i[1]>=e.y&&i[1]<=e.y+e.h)return t.preventDefault(),this._bdStart(t)}return!1}_decorCommitDraft(){const t=this._decorDraft;if(this._decorDraft=null,!t)return;const e=.5*this._gridPitch;if(Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])t.id!==e.id),this._decorSel===e.id&&(this._decorSel=null),this._saveConfig(),void this.requestUpdate()}this._decorSel=e.id,this._decorMove={id:e.id,start:this._svgPoint(t),orig:JSON.parse(JSON.stringify(e)),pid:t.pointerId,moved:!1},Nr(t)}}_decorMoveUpdate(t){const e=this._decorMove;if("furniture"===e.orig?.kind)return void this._furnMoveUpdate(t);const i=this._svgPoint(t),s=e.orig,n=("line"===s.kind?s.x1:s.x)*Pr,o=("line"===s.kind?s.y1:s.y)*this._decorH,r=this._snap([n+(i[0]-e.start[0]),o+(i[1]-e.start[1])],t);let a=(r[0]-n)/Pr,l=(r[1]-o)/this._decorH;const c=e.orig,h="line"===c.kind?Math.min(c.x1,c.x2):c.x,d="line"===c.kind?Math.min(c.y1,c.y2):c.y,p="line"===c.kind?Math.abs(c.x2-c.x1):c.w||0,u="line"===c.kind?Math.abs(c.y2-c.y1):c.h||0,_=Os;a=Math.max(-_-h,Math.min(_-h-p,a)),l=Math.max(-_-d,Math.min(_-d-u,l)),(a||l)&&(e.moved=!0);this._curSpaceCfg.decor=this._decorList.map(t=>{if(t.id!==e.id)return t;const i=e.orig;return"line"===t.kind?{...t,x1:i.x1+a,y1:i.y1+l,x2:i.x2+a,y2:i.y2+l}:{...t,x:i.x+a,y:i.y+l}}),this.requestUpdate()}_decorShapeDbl(t){"decor"===this._mode&&"select"===this._decorTool&&"text"===t.kind&&this._decorOpenText(t)}_decorOpenText(t){this._decorTextDialog={id:t.id,x:t.x,y:t.y,text:t.text,color:t.color,entity:t.entity||"",attr:t.attr||"",unit:t.unit||""}}_decorTextLink(t){const e={},i=(t.entity||"").trim();if(!i)return e;e.entity=i;const s=(t.attr||"").trim();s&&(e.attr=s);const n=(t.unit||"").trim();return n&&(e.unit=n),e}_decorSaveText(){const t=this._decorTextDialog,e=String(t?.text??"").replace(/\r\n?/g,"\n").trim();if(!t||!e)return void(this._decorTextDialog=null);const i=this._curSpaceCfg,s=this._decorTextLink(t);if(t.id)i.decor=this._decorList.map(i=>{if(i.id!==t.id)return i;const{entity:n,attr:o,unit:r,...a}=i;return{...a,text:e,color:t.color,...s}});else{const n="dc"+Date.now().toString(36)+Math.random().toString(36).slice(2,5);i.decor=[...this._decorList,{id:n,kind:"text",x:t.x,y:t.y,text:e,color:t.color,...s}],this._decorSel=n}this._decorTextDialog=null,this._saveConfig(),this.requestUpdate()}get _dtSel(){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel)return null;const t=this._decorList.find(t=>t.id===this._decorSel);return!t||"text"!==t.kind&&"furniture"!==t.kind?null:t}_dtPivot(t){return"furniture"===t.kind?[(t.x+t.w/2)*Pr,(t.y+t.h/2)*this._decorH]:[t.x*Pr,t.y*this._decorH]}_dtApply(t,e){const i=this._curSpaceCfg;i&&(i.decor=this._decorList.map(i=>{if(i.id!==t)return i;const{size:s,...n}=i,o={...n};return void 0!==e.scale?o.scale=Number(e.scale.toFixed(4)):void 0===i.scale&&void 0!==s&&(o.scale=pi(i)),void 0!==e.angle&&(e.angle?o.angle=Number(e.angle.toFixed(2)):delete o.angle),o}),this._cfgEpoch++,this.requestUpdate())}_dtStart(t,e,i){const s=this._dtSel;if(!s)return;t.stopPropagation(),t.preventDefault();const[n,o]=this._dtPivot(s),r=this._svgPoint(t),a="furniture"===s.kind;this._dtDrag={id:s.id,kind:e,pid:t.pointerId,ax:n,ay:o,r0:Math.hypot(r[0]-n,r[1]-o),a0:180*Math.atan2(r[1]-o,r[0]-n)/Math.PI,scale0:a?1:pi(s),angle0:Number(s.angle)||0,sgx:i?.[0],sgy:i?.[1],orig:a?{x:s.x*Pr,y:s.y*this._decorH,w:s.w*Pr,h:s.h*this._decorH,angle:Number(s.angle)||0}:void 0,moved:!1},Nr(t)}_dtMove(t){const e=this._dtDrag;if(!e)return;const i=this._svgPoint(t);if("scale"===e.kind&&e.orig){const s=t.shiftKey?0:this._gridPitch,n=s>0?s:.25*this._gridPitch,o=function(t,e,i,s,n,o=0,r=1e-6){const a=(Number(t.angle)||0)*Math.PI/180,l=Math.cos(a),c=Math.sin(a),h=-Math.sin(a),d=Math.cos(a),p=t.x+t.w/2,u=t.y+t.h/2,_=e>0?-t.w/2:t.w/2,g=i>0?-t.h/2:t.h/2,m=p+_*l+g*h,f=u+_*c+g*d,v=s-m,b=n-f;let y=(v*l+b*c)*(e>0?1:-1),w=(v*h+b*d)*(i>0?1:-1);return o>0&&(y=Math.round(y/o)*o,w=Math.round(w/o)*o),y=Math.max(r,y),w=Math.max(r,w),{x:m+(e>0?y/2:-y/2)*l+(i>0?w/2:-w/2)*h-y/2,y:f+(e>0?y/2:-y/2)*c+(i>0?w/2:-w/2)*d-w/2,w:y,h:w}}(e.orig,e.sgx??1,e.sgy??1,i[0],i[1],s,n);return(Math.abs(o.w-e.orig.w)>1e-6||Math.abs(o.h-e.orig.h)>1e-6)&&(e.moved=!0),void this._furnApplyBox(e.id,o)}if("scale"===e.kind){const t=Math.hypot(i[0]-e.ax,i[1]-e.ay);if(e.r0<1e-6)return;const s=Math.min(20,Math.max(.15,e.scale0*(t/e.r0)));return Math.abs(s-e.scale0)>1e-6&&(e.moved=!0),void this._dtApply(e.id,{scale:s})}const s=180*Math.atan2(i[1]-e.ay,i[0]-e.ax)/Math.PI;let n=e.angle0+(s-e.a0);t.shiftKey||(n=5*Math.round(n/5)),n=(n%360+360)%360,n>180&&(n-=360),Math.abs(n-e.angle0)>1e-6&&(e.moved=!0),this._dtApply(e.id,{angle:n})}_dtUp(){const t=this._dtDrag;this._dtDrag=null,t?.moved&&this._saveConfig(),this.requestUpdate()}_dtMeasure(){const t=this._dtSel;if(!t)return void(this._dtBox&&(this._dtBox=null,this.requestUpdate()));let e;if("furniture"===t.kind)e={id:t.id,x:t.x*Pr,y:t.y*this._decorH,w:t.w*Pr,h:t.h*this._decorH};else{const i=this.renderRoot.querySelector(`text.dtext[data-id="${t.id}"]`);if(!i||"function"!=typeof i.getBBox)return;let s;try{s=i.getBBox()}catch{return}if(!s||!s.width&&!s.height)return;e={id:t.id,x:s.x,y:s.y,w:s.width,h:s.height}}const i=this._dtBox;i&&i.id===e.id&&Math.abs(i.x-e.x)<.01&&Math.abs(i.y-e.y)<.01&&Math.abs(i.w-e.w)<.01&&Math.abs(i.h-e.h)<.01||(this._dtBox=e,this.requestUpdate())}_decorDeleteSel(){if(!this._decorSel)return;this._curSpaceCfg.decor=this._decorList.filter(t=>t.id!==this._decorSel),this._decorSel=null,this._saveConfig(),this.requestUpdate()}get _furnWalls(){return this._segments}get _furnWallReach(){return 6*this._gridPitch}_furnFieldValue(t){return Math.round(100*(this._imperial?t/30.48:t/100))/100}_furnFieldToCm(t){return e=this._imperial?30.48*t:100*t,Number.isFinite(e)?Math.max(1,Math.min(1e4,e)):1;var e}_furnPick(t){const e=function(t){const e=dn(t);return e?{w:e.w,h:e.h}:{w:60,h:60}}(t);this._furnPalette={symbol:t,w:e.w,h:e.h}}_furnPlace(t,e){const i=this._furnPalette,s=this._curSpaceCfg;if(!i||!s)return;const n=Pr,o=this._decorH,r=gn(pn(i.w,this._cellCm,this._gridPitch,n)),a=gn(pn(i.h,this._cellCm,this._gridPitch,n)),l=this._snap(t,e);let c=l[0],h=l[1],d=0;if(!e.shiftKey){const t=bn(c,h,a*o,this._furnWalls,this._furnWallReach,this._gridPitch);t&&(c=t.cx,h=t.cy,d=t.angle)}const p="df"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),u={id:p,kind:"furniture",symbol:i.symbol,x:Bs(c/n-r/2),y:Bs(h/o-a/2),w:r,h:a,color:this._decorStyle.color,width:this._decorStyle.width};d&&(u.angle=Number(d.toFixed(2))),s.decor=[...this._decorList,u],this._decorSel=p,this._decorTool="select",this._furnPalette=null,this._saveConfig(),this.requestUpdate()}_furnMoveUpdate(t){const e=this._decorMove,i=e.orig,s=this._curSpaceCfg;if(!s)return;const n=Pr,o=this._decorH,r=this._svgPoint(t),a=(i.x+i.w/2)*n+(r[0]-e.start[0]),l=(i.y+i.h/2)*o+(r[1]-e.start[1]);let c,h,d=Number(i.angle)||0;const p=t.shiftKey?null:bn(a,l,i.h*o,this._furnWalls,this._furnWallReach,this._gridPitch);if(p)c=p.cx/n-i.w/2,h=p.cy/o-i.h/2,d=p.angle;else{const e=this._snap([a-i.w/2*n,l-i.h/2*o],t);c=e[0]/n,h=e[1]/o}c=Bs(c),h=Bs(h),(Math.abs(c-i.x)>1e-9||Math.abs(h-i.y)>1e-9||Math.abs(d-(Number(i.angle)||0))>1e-9)&&(e.moved=!0),s.decor=this._decorList.map(t=>{if(t.id!==e.id)return t;const i={...t,x:c,y:h};return d?i.angle=Number(d.toFixed(2)):delete i.angle,i}),this.requestUpdate()}_furnApplyBox(t,e){const i=this._curSpaceCfg;if(!i)return;const s=Pr,n=this._decorH;i.decor=this._decorList.map(i=>i.id===t?{...i,x:Bs(e.x/s),y:Bs(e.y/n),w:gn(e.w/s),h:gn(e.h/n)}:i),this._cfgEpoch++,this.requestUpdate()}get _furnLive(){const t=this._dtDrag;if(!t||"scale"!==t.kind||!t.orig)return null;const e=this._decorList.find(e=>e.id===t.id);if(!e||"furniture"!==e.kind)return null;const i=Pr,s=this._decorH,n=e.w*i,o=e.h*s,r=function(t,e,i,s,n){const o=t+i/2,r=e+s/2,a=(Number(n)||0)*Math.PI/180,l=Math.cos(a),c=Math.sin(a),h=(t,e)=>{const i=t-o,s=e-r;return[o+i*l-s*c,r+i*c+s*l]};return[h(t,e),h(t+i,e),h(t+i,e+s),h(t,e+s)]}(e.x*i,e.y*s,n,o,Number(e.angle)||0),a=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],l=a(r[0],r[1]),c=a(r[0],r[3]);return[{x:l[0],y:l[1],text:this._fmtLen([0,0],[n,0])},{x:c[0],y:c[1],text:this._fmtLen([0,0],[0,o])}]}_renderFurnPalette(){const t=this._furnPalette,e=this._t(this._imperial?"gs.unit_ft":"gs.unit_m");return W`t.stopPropagation()}>
+ @lostpointercapture=${t=>this._rszPointerCancel(t)}>`),o.push(B`
`)}return B`${o}`}get _openingsR(){const t=this._curSpaceCfg,e=this._spaceH;return(t?.openings||[]).map(t=>({...t,rx:t.x*Ar,ry:t.y*e,rlen:t.length*Ar}))}_cmToUnits(t){return t/this._cellCm*this._gridPitch}get _decorList(){const t=this._curSpaceCfg;return Array.isArray(t?.decor)?t.decor:[]}get _decorH(){return Ar}_decorPointerDown(t){const e=this._decorTool;if("select"===e||"erase"===e?t.target.closest?.(".dshape"):null)return!0;if("line"===e||"rect"===e||"ellipse"===e){t.preventDefault();const i=this._snap(this._svgPoint(t),t);return this._decorDraft={kind:e,a:i,b:i,pid:t.pointerId},Or(t),!0}if("text"===e){const e=this._snap(this._svgPoint(t),t);return this._decorTextDialog={x:Bs(e[0]/Ar),y:Bs(e[1]/this._decorH),text:"",color:this._decorStyle.color},!0}if("furniture"===e)return!!this._furnPalette&&(t.preventDefault(),this._furnPlace(this._svgPoint(t),t),!0);if(this._decorSel=null,this._bdMovable){const e=this._bdRect,i=this._svgPoint(t);if(i[0]>=e.x&&i[0]<=e.x+e.w&&i[1]>=e.y&&i[1]<=e.y+e.h)return t.preventDefault(),this._bdStart(t)}return!1}_decorCommitDraft(){const t=this._decorDraft;if(this._decorDraft=null,!t)return;const e=.5*this._gridPitch;if(Math.hypot(t.b[0]-t.a[0],t.b[1]-t.a[1])
t.id!==e.id),this._decorSel===e.id&&(this._decorSel=null),this._saveConfig(),void this.requestUpdate()}this._decorSel=e.id,this._decorMove={id:e.id,start:this._svgPoint(t),orig:JSON.parse(JSON.stringify(e)),pid:t.pointerId,moved:!1},Or(t)}}_decorMoveUpdate(t){const e=this._decorMove;if("furniture"===e.orig?.kind)return void this._furnMoveUpdate(t);const i=this._svgPoint(t),s=e.orig,n=("line"===s.kind?s.x1:s.x)*Ar,o=("line"===s.kind?s.y1:s.y)*this._decorH,r=this._snap([n+(i[0]-e.start[0]),o+(i[1]-e.start[1])],t);let a=(r[0]-n)/Ar,l=(r[1]-o)/this._decorH;const c=e.orig,h="line"===c.kind?Math.min(c.x1,c.x2):c.x,d="line"===c.kind?Math.min(c.y1,c.y2):c.y,p="line"===c.kind?Math.abs(c.x2-c.x1):c.w||0,u="line"===c.kind?Math.abs(c.y2-c.y1):c.h||0,_=Os;a=Math.max(-_-h,Math.min(_-h-p,a)),l=Math.max(-_-d,Math.min(_-d-u,l)),(a||l)&&(e.moved=!0);this._curSpaceCfg.decor=this._decorList.map(t=>{if(t.id!==e.id)return t;const i=e.orig;return"line"===t.kind?{...t,x1:i.x1+a,y1:i.y1+l,x2:i.x2+a,y2:i.y2+l}:{...t,x:i.x+a,y:i.y+l}}),this.requestUpdate()}_decorShapeDbl(t){"decor"===this._mode&&"select"===this._decorTool&&"text"===t.kind&&this._decorOpenText(t)}_decorOpenText(t){this._decorTextDialog={id:t.id,x:t.x,y:t.y,text:t.text,color:t.color,entity:t.entity||"",attr:t.attr||"",unit:t.unit||""}}_decorTextLink(t){const e={},i=(t.entity||"").trim();if(!i)return e;e.entity=i;const s=(t.attr||"").trim();s&&(e.attr=s);const n=(t.unit||"").trim();return n&&(e.unit=n),e}_decorSaveText(){const t=this._decorTextDialog,e=String(t?.text??"").replace(/\r\n?/g,"\n").trim();if(!t||!e)return void(this._decorTextDialog=null);const i=this._curSpaceCfg,s=this._decorTextLink(t);if(t.id)i.decor=this._decorList.map(i=>{if(i.id!==t.id)return i;const{entity:n,attr:o,unit:r,...a}=i;return{...a,text:e,color:t.color,...s}});else{const n="dc"+Date.now().toString(36)+Math.random().toString(36).slice(2,5);i.decor=[...this._decorList,{id:n,kind:"text",x:t.x,y:t.y,text:e,color:t.color,...s}],this._decorSel=n}this._decorTextDialog=null,this._saveConfig(),this.requestUpdate()}get _dtSel(){if("decor"!==this._mode||"select"!==this._decorTool||!this._decorSel)return null;const t=this._decorList.find(t=>t.id===this._decorSel);return!t||"text"!==t.kind&&"furniture"!==t.kind?null:t}_dtPivot(t){return"furniture"===t.kind?[(t.x+t.w/2)*Ar,(t.y+t.h/2)*this._decorH]:[t.x*Ar,t.y*this._decorH]}_dtApply(t,e){const i=this._curSpaceCfg;i&&(i.decor=this._decorList.map(i=>{if(i.id!==t)return i;const{size:s,...n}=i,o={...n};return void 0!==e.scale?o.scale=Number(e.scale.toFixed(4)):void 0===i.scale&&void 0!==s&&(o.scale=pi(i)),void 0!==e.angle&&(e.angle?o.angle=Number(e.angle.toFixed(2)):delete o.angle),o}),this._cfgEpoch++,this.requestUpdate())}_dtStart(t,e,i){const s=this._dtSel;if(!s)return;t.stopPropagation(),t.preventDefault();const[n,o]=this._dtPivot(s),r=this._svgPoint(t),a="furniture"===s.kind;this._dtDrag={id:s.id,kind:e,pid:t.pointerId,ax:n,ay:o,r0:Math.hypot(r[0]-n,r[1]-o),a0:180*Math.atan2(r[1]-o,r[0]-n)/Math.PI,scale0:a?1:pi(s),angle0:Number(s.angle)||0,sgx:i?.[0],sgy:i?.[1],orig:a?{x:s.x*Ar,y:s.y*this._decorH,w:s.w*Ar,h:s.h*this._decorH,angle:Number(s.angle)||0}:void 0,moved:!1},Or(t)}_dtMove(t){const e=this._dtDrag;if(!e)return;const i=this._svgPoint(t);if("scale"===e.kind&&e.orig){const s=t.shiftKey?0:this._gridPitch,n=s>0?s:.25*this._gridPitch,o=function(t,e,i,s,n,o=0,r=1e-6){const a=(Number(t.angle)||0)*Math.PI/180,l=Math.cos(a),c=Math.sin(a),h=-Math.sin(a),d=Math.cos(a),p=t.x+t.w/2,u=t.y+t.h/2,_=e>0?-t.w/2:t.w/2,g=i>0?-t.h/2:t.h/2,m=p+_*l+g*h,f=u+_*c+g*d,v=s-m,b=n-f;let y=(v*l+b*c)*(e>0?1:-1),w=(v*h+b*d)*(i>0?1:-1);return o>0&&(y=Math.round(y/o)*o,w=Math.round(w/o)*o),y=Math.max(r,y),w=Math.max(r,w),{x:m+(e>0?y/2:-y/2)*l+(i>0?w/2:-w/2)*h-y/2,y:f+(e>0?y/2:-y/2)*c+(i>0?w/2:-w/2)*d-w/2,w:y,h:w}}(e.orig,e.sgx??1,e.sgy??1,i[0],i[1],s,n);return(Math.abs(o.w-e.orig.w)>1e-6||Math.abs(o.h-e.orig.h)>1e-6)&&(e.moved=!0),void this._furnApplyBox(e.id,o)}if("scale"===e.kind){const t=Math.hypot(i[0]-e.ax,i[1]-e.ay);if(e.r0<1e-6)return;const s=Math.min(20,Math.max(.15,e.scale0*(t/e.r0)));return Math.abs(s-e.scale0)>1e-6&&(e.moved=!0),void this._dtApply(e.id,{scale:s})}const s=180*Math.atan2(i[1]-e.ay,i[0]-e.ax)/Math.PI;let n=e.angle0+(s-e.a0);t.shiftKey||(n=5*Math.round(n/5)),n=(n%360+360)%360,n>180&&(n-=360),Math.abs(n-e.angle0)>1e-6&&(e.moved=!0),this._dtApply(e.id,{angle:n})}_dtUp(){const t=this._dtDrag;this._dtDrag=null,t?.moved&&this._saveConfig(),this.requestUpdate()}_dtMeasure(){const t=this._dtSel;if(!t)return void(this._dtBox&&(this._dtBox=null,this.requestUpdate()));let e;if("furniture"===t.kind)e={id:t.id,x:t.x*Ar,y:t.y*this._decorH,w:t.w*Ar,h:t.h*this._decorH};else{const i=this.renderRoot.querySelector(`text.dtext[data-id="${t.id}"]`);if(!i||"function"!=typeof i.getBBox)return;let s;try{s=i.getBBox()}catch{return}if(!s||!s.width&&!s.height)return;e={id:t.id,x:s.x,y:s.y,w:s.width,h:s.height}}const i=this._dtBox;i&&i.id===e.id&&Math.abs(i.x-e.x)<.01&&Math.abs(i.y-e.y)<.01&&Math.abs(i.w-e.w)<.01&&Math.abs(i.h-e.h)<.01||(this._dtBox=e,this.requestUpdate())}_decorDeleteSel(){if(!this._decorSel)return;this._curSpaceCfg.decor=this._decorList.filter(t=>t.id!==this._decorSel),this._decorSel=null,this._saveConfig(),this.requestUpdate()}get _furnWalls(){return this._segments}get _furnWallReach(){return 6*this._gridPitch}_furnFieldValue(t){return Math.round(100*(this._imperial?t/30.48:t/100))/100}_furnFieldToCm(t){return e=this._imperial?30.48*t:100*t,Number.isFinite(e)?Math.max(1,Math.min(1e4,e)):1;var e}_furnPick(t){const e=function(t){const e=dn(t);return e?{w:e.w,h:e.h}:{w:60,h:60}}(t);this._furnPalette={symbol:t,w:e.w,h:e.h}}_furnPlace(t,e){const i=this._furnPalette,s=this._curSpaceCfg;if(!i||!s)return;const n=Ar,o=this._decorH,r=gn(pn(i.w,this._cellCm,this._gridPitch,n)),a=gn(pn(i.h,this._cellCm,this._gridPitch,n)),l=this._snap(t,e);let c=l[0],h=l[1],d=0;if(!e.shiftKey){const t=bn(c,h,a*o,this._furnWalls,this._furnWallReach,this._gridPitch);t&&(c=t.cx,h=t.cy,d=t.angle)}const p="df"+Date.now().toString(36)+Math.random().toString(36).slice(2,5),u={id:p,kind:"furniture",symbol:i.symbol,x:Bs(c/n-r/2),y:Bs(h/o-a/2),w:r,h:a,color:this._decorStyle.color,width:this._decorStyle.width};d&&(u.angle=Number(d.toFixed(2))),s.decor=[...this._decorList,u],this._decorSel=p,this._decorTool="select",this._furnPalette=null,this._saveConfig(),this.requestUpdate()}_furnMoveUpdate(t){const e=this._decorMove,i=e.orig,s=this._curSpaceCfg;if(!s)return;const n=Ar,o=this._decorH,r=this._svgPoint(t),a=(i.x+i.w/2)*n+(r[0]-e.start[0]),l=(i.y+i.h/2)*o+(r[1]-e.start[1]);let c,h,d=Number(i.angle)||0;const p=t.shiftKey?null:bn(a,l,i.h*o,this._furnWalls,this._furnWallReach,this._gridPitch);if(p)c=p.cx/n-i.w/2,h=p.cy/o-i.h/2,d=p.angle;else{const e=this._snap([a-i.w/2*n,l-i.h/2*o],t);c=e[0]/n,h=e[1]/o}c=Bs(c),h=Bs(h),(Math.abs(c-i.x)>1e-9||Math.abs(h-i.y)>1e-9||Math.abs(d-(Number(i.angle)||0))>1e-9)&&(e.moved=!0),s.decor=this._decorList.map(t=>{if(t.id!==e.id)return t;const i={...t,x:c,y:h};return d?i.angle=Number(d.toFixed(2)):delete i.angle,i}),this.requestUpdate()}_furnApplyBox(t,e){const i=this._curSpaceCfg;if(!i)return;const s=Ar,n=this._decorH;i.decor=this._decorList.map(i=>i.id===t?{...i,x:Bs(e.x/s),y:Bs(e.y/n),w:gn(e.w/s),h:gn(e.h/n)}:i),this._cfgEpoch++,this.requestUpdate()}get _furnLive(){const t=this._dtDrag;if(!t||"scale"!==t.kind||!t.orig)return null;const e=this._decorList.find(e=>e.id===t.id);if(!e||"furniture"!==e.kind)return null;const i=Ar,s=this._decorH,n=e.w*i,o=e.h*s,r=function(t,e,i,s,n){const o=t+i/2,r=e+s/2,a=(Number(n)||0)*Math.PI/180,l=Math.cos(a),c=Math.sin(a),h=(t,e)=>{const i=t-o,s=e-r;return[o+i*l-s*c,r+i*c+s*l]};return[h(t,e),h(t+i,e),h(t+i,e+s),h(t,e+s)]}(e.x*i,e.y*s,n,o,Number(e.angle)||0),a=(t,e)=>[(t[0]+e[0])/2,(t[1]+e[1])/2],l=a(r[0],r[1]),c=a(r[0],r[3]);return[{x:l[0],y:l[1],text:this._fmtLen([0,0],[n,0])},{x:c[0],y:c[1],text:this._fmtLen([0,0],[0,o])}]}_renderFurnPalette(){const t=this._furnPalette,e=this._t(this._imperial?"gs.unit_ft":"gs.unit_m");return W`t.stopPropagation()}>
${this._t("furn.title")}
@@ -2680,7 +2680,7 @@ const t=globalThis,e=t.ShadowRoot&&(void 0===t.ShadyCSS||t.ShadyCSS.nativeShadow
@input=${e=>this._furnPalette={...t,h:this._furnFieldToCm(Number(e.target.value))}} />
${this._t("furn.place_hint")}
`:W`
${this._t("furn.pick_hint")}
`}
-
`}get _bdBase(){const t=this._curSpaceCfg;return t?.plan_url?{...Ps(t.plan_aspect,Pr)}:null}get _bdRect(){const t=this._curSpaceCfg;return t?.plan_url?Rs(t,Pr):null}get _bdParams(){const t=this._curSpaceCfg,e=Number(t?.plan_x),i=Number(t?.plan_y),s=Number(t?.plan_scale);return{dx:Number.isFinite(e)?e:0,dy:Number.isFinite(i)?i:0,k:Number.isFinite(s)&&s>0?s:1}}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&("select"===this._decorTool||"backdrop"===this._decorTool)}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(t,e,i){const s=this._curSpaceCfg;s&&(s.plan_x=Number(Bs(t).toFixed(6)),s.plan_y=Number(Bs(e).toFixed(6)),s.plan_scale=Number(Math.min(100,Math.max(As,i)).toFixed(6)),this._cfgEpoch++,this.requestUpdate())}_bdStart(t,e){const i=this._bdBase,s=this._bdRect;if(!i||!s)return!1;const n=this._svgPoint(t),o=e?e[0]:0,r=e?e[1]:0,a=o>0?s.x:s.x+s.w,l=r>0?s.y:s.y+s.h;return this._bdDrag={kind:e?"scale":"move",pid:t.pointerId,sx:n[0],sy:n[1],base:i,p0:this._bdParams,fx:a,fy:l,sgx:o,sgy:r,moved:!1},Nr(t),!0}_bdMove(t){const e=this._bdDrag;if(!e)return;const i=this._svgPoint(t),s=e.base;if("move"===e.kind){const n=s.x+e.p0.dx*Pr,o=s.y+e.p0.dy*Pr,r=this._snap([n+(i[0]-e.sx),o+(i[1]-e.sy)],t);return(Math.abs(r[0]-n)>1e-9||Math.abs(r[1]-o)>1e-9)&&(e.moved=!0),void this._bdApply((r[0]-s.x)/Pr,(r[1]-s.y)/Pr,e.p0.k)}const n=s.w||1,o=s.h||1;let r=Math.max(Math.abs(i[0]-e.fx)/n,Math.abs(i[1]-e.fy)/o);if(!t.shiftKey){const t=n>=o,i=ke(t?e.fx+e.sgx*r*n:e.fy+e.sgy*r*o,this._gridPitch),s=Math.abs(i-(t?e.fx:e.fy))/(t?n:o);s>0&&(r=s)}r=Math.min(100,Math.max(As,r)),Math.abs(r-e.p0.k)>1e-9&&(e.moved=!0);const a=e.sgx>0?e.fx:e.fx-r*n,l=e.sgy>0?e.fy:e.fy-r*o;this._bdApply((a-s.x)/Pr,(l-s.y)/Pr,r)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const t=this._bdParams;return 0!==t.dx||0!==t.dy||1!==t.k}_bdReset(){const t=this._curSpaceCfg;t&&(delete t.plan_x,delete t.plan_y,delete t.plan_scale,this._bdDrag=null,this._saveConfig(),this._showToast(this._t("decor.backdrop_reset_done")),this.requestUpdate())}_bdUp(){const t=this._bdDrag;this._bdDrag=null,t?.moved&&this._saveConfig(),this.requestUpdate()}get _bdLive(){if(!this._bdDrag)return null;const t=this._bdRect;return t?{x:t.x+t.w/2,y:t.y+t.h/2,text:`${this._fmtLen([0,0],[t.w,0])} × ${this._fmtLen([0,0],[0,t.h])}`}:null}_renderBackdropFrame(t){const e=this._bdRect;if(!this._bdActive||!e)return V;const i=.02*Math.max(t.w,t.h),s=i/4;return B`
+ `}get _bdBase(){const t=this._curSpaceCfg;return t?.plan_url?{...Ps(t.plan_aspect,Ar)}:null}get _bdRect(){const t=this._curSpaceCfg;return t?.plan_url?Rs(t,Ar):null}get _bdParams(){const t=this._curSpaceCfg,e=Number(t?.plan_x),i=Number(t?.plan_y),s=Number(t?.plan_scale);return{dx:Number.isFinite(e)?e:0,dy:Number.isFinite(i)?i:0,k:Number.isFinite(s)&&s>0?s:1}}get _bdActive(){return"decor"===this._mode&&!!this._bdRect&&("select"===this._decorTool||"backdrop"===this._decorTool)}get _bdMovable(){return"decor"===this._mode&&"backdrop"===this._decorTool&&!!this._bdRect}_bdApply(t,e,i){const s=this._curSpaceCfg;s&&(s.plan_x=Number(Bs(t).toFixed(6)),s.plan_y=Number(Bs(e).toFixed(6)),s.plan_scale=Number(Math.min(100,Math.max(As,i)).toFixed(6)),this._cfgEpoch++,this.requestUpdate())}_bdStart(t,e){const i=this._bdBase,s=this._bdRect;if(!i||!s)return!1;const n=this._svgPoint(t),o=e?e[0]:0,r=e?e[1]:0,a=o>0?s.x:s.x+s.w,l=r>0?s.y:s.y+s.h;return this._bdDrag={kind:e?"scale":"move",pid:t.pointerId,sx:n[0],sy:n[1],base:i,p0:this._bdParams,fx:a,fy:l,sgx:o,sgy:r,moved:!1},Or(t),!0}_bdMove(t){const e=this._bdDrag;if(!e)return;const i=this._svgPoint(t),s=e.base;if("move"===e.kind){const n=s.x+e.p0.dx*Ar,o=s.y+e.p0.dy*Ar,r=this._snap([n+(i[0]-e.sx),o+(i[1]-e.sy)],t);return(Math.abs(r[0]-n)>1e-9||Math.abs(r[1]-o)>1e-9)&&(e.moved=!0),void this._bdApply((r[0]-s.x)/Ar,(r[1]-s.y)/Ar,e.p0.k)}const n=s.w||1,o=s.h||1;let r=Math.max(Math.abs(i[0]-e.fx)/n,Math.abs(i[1]-e.fy)/o);if(!t.shiftKey){const t=n>=o,i=ke(t?e.fx+e.sgx*r*n:e.fy+e.sgy*r*o,this._gridPitch),s=Math.abs(i-(t?e.fx:e.fy))/(t?n:o);s>0&&(r=s)}r=Math.min(100,Math.max(As,r)),Math.abs(r-e.p0.k)>1e-9&&(e.moved=!0);const a=e.sgx>0?e.fx:e.fx-r*n,l=e.sgy>0?e.fy:e.fy-r*o;this._bdApply((a-s.x)/Ar,(l-s.y)/Ar,r)}get _bdMoved(){if("decor"!==this._mode||!this._bdRect)return!1;const t=this._bdParams;return 0!==t.dx||0!==t.dy||1!==t.k}_bdReset(){const t=this._curSpaceCfg;t&&(delete t.plan_x,delete t.plan_y,delete t.plan_scale,this._bdDrag=null,this._saveConfig(),this._showToast(this._t("decor.backdrop_reset_done")),this.requestUpdate())}_bdUp(){const t=this._bdDrag;this._bdDrag=null,t?.moved&&this._saveConfig(),this.requestUpdate()}get _bdLive(){if(!this._bdDrag)return null;const t=this._bdRect;return t?{x:t.x+t.w/2,y:t.y+t.h/2,text:`${this._fmtLen([0,0],[t.w,0])} × ${this._fmtLen([0,0],[0,t.h])}`}:null}_renderBackdropFrame(t){const e=this._bdRect;if(!this._bdActive||!e)return V;const i=.02*Math.max(t.w,t.h),s=i/4;return B`
${[[-1,-1,"nwse"],[1,-1,"nesw"],[1,1,"nwse"],[-1,1,"nesw"]].map(([t,n,o])=>{const r=t<0?e.x:e.x+e.w,a=n<0?e.y:e.y+e.h;return B`this._dtStart(i,"scale",[t,e])}>`)}
- `}_renderDecorLayer(){const t=Pr,e=this._decorH,i="decor"===this._mode,s=this._decorList.map(s=>{const n="dshape"+(i&&this._decorSel===s.id?" dsel":""),o=t=>this._decorShapeDown(t,s),r=()=>this._decorShapeDbl(s);if("line"===s.kind)return B``}_renderDecorLayer(){const t=Ar,e=this._decorH,i="decor"===this._mode,s=this._decorList.map(s=>{const n="dshape"+(i&&this._decorSel===s.id?" dsel":""),o=t=>this._decorShapeDown(t,s),r=()=>this._decorShapeDbl(s);if("line"===s.kind)return B``;if("rect"===s.kind)return B``)}
${i?i.segs.map(t=>B``):V}
- `}_openCuts(){const t=this._curSpaceCfg;return mo(this._spaceModel().rooms,t?.open_spans,Pr,.02*this._gridPitch)}_openPairs(){const t=this._openCuts();if(!t.length)return[];const e=this._spaceModel().rooms.filter(t=>t.id),i=.02*this._gridPitch,s=[];for(let n=0;n{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return l.some(t=>Bi(e,t)<4*i)});c.length&&s.push({a:e[n],b:e[o],segs:c})}return s}_commitOpenSpans(t){const e=this._curSpaceCfg;if(!e)return;const i=.02*this._gridPitch;this._cfgEpoch++;const s=this._spaceModel().rooms;let n=lo(e.open_spans);n.length&&t?.old.length?n=function(t,e,i,s){const n=lo(t);if(!n.length)return[];if(e.length!==i.length)return n;const o=[];for(const t of n){const n=ro(t,s),r=[n[0],n[1]],a=[n[2],n[3]];let l=r,c=a;for(let t=0;t{const e=co(t,[s[0],s[1],n[0],n[1]]);if(e.d>.001)return t;const i=h[0]-o[0],r=h[1]-o[1];return[o[0]+i*e.t,o[1]+r*e.t]};if(co([(r[0]+a[0])/2,(r[1]+a[1])/2],[s[0],s[1],n[0],n[1]]).d<.01){l=d(r),c=d(a);break}}o.push(oo(l,c,s))}return o}(n,t.old,t.next,Pr):n.length||(n=fo(mo(s,null,Pr,i),Pr)),n=function(t,e,i,s){const n=lo(t);if(!n.length)return[];const o=uo(e,s);if(!o.length)return[];const r=[],a=Math.max(4*s,1e-6);for(const t of n){const e=ro(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const r=(t[0]-n)*p+(t[1]-l)*u,c=(t[2]-n)*p+(t[3]-l)*u,h=Math.max(0,Math.min(r,c)),g=Math.min(d,Math.max(r,c));if(g-ht.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t){const t=e[e.length-1];t&&i.lo<=t.hi+a?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const t of e){const e=[n+p*t.lo,l+u*t.lo],s=[n+p*t.hi,l+u*t.hi];Math.hypot(s[0]-e[0],s[1]-e[1])ro(t,Pr)))}_persistOpenCuts(t){const e=this._curSpaceCfg;if(!e)return;const i=fo(t,Pr);i.length?e.open_spans=i:delete e.open_spans,function(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),r=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tBi(i,t)<4*s)){r(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}(e.rooms||[],this._spaceModel().rooms,t,.02*this._gridPitch)}_closeOpenSpan(t){const e=this._curSpaceCfg;if(!e)return;const i=.02*this._gridPitch,s=function(t,e,i){const s=[(e[0]+e[2])/2,(e[1]+e[3])/2];return t.filter(t=>{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return Math.hypot(e[0]-s[0],e[1]-s[1])>4*i})}(this._openCuts(),t,i);let n=this._normalizeWalls(e.walls,s);if(!(Zn(this._spaceModel().rooms,n,s,t,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)>0)){const e=[];for(const t of Xn(this._spaceModel().rooms,n,s,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr))t.open||e.push([t.a[0],t.a[1],t.b[0],t.b[1]]);n=bo(n,t,e,this._wallKeyPitch,Pr,15),n=this._normalizeWalls(n,s)}n.length?e.walls=n:delete e.walls,this._persistOpenCuts(s),this._showToast(this._t("toast.openwall_closed_span")),this._saveConfig(),this.requestUpdate()}_openWallClick(t){const e=6*this._gridPitch,i=.02*this._gridPitch,s=this._openCuts();if(this._openWallAnchor){const{p:n,edge:o}=this._openWallAnchor,r=ho(po(t,o,yo(o,s,i),this._gridPitch,1.5*this._gridPitch),o),a=Math.hypot(r[0]-n[0],r[1]-n[1]);if(this._openWallAnchor=null,a<.5*this._gridPitch)return void this._showToast(this._t("toast.openwall_short"));if(Bi(t,o)>e)return void this._showToast(this._t("toast.openwall_pick"));const l=[n[0],n[1],r[0],r[1]],c=[...s,l],h=this._curSpaceCfg;if(!h)return;const d=this._normalizeWalls(h.walls,c);d.length?h.walls=d:delete h.walls;const p=(h.openings||[]).length;return h.openings=function(t,e,i,s){return t?.length?t.filter(t=>Bi([Number(t.x)*i,Number(t.y)*i],e)>s||!Nn([e[0],e[1]],[e[2],e[3]],Number(t.angle)||0)):t?t.slice():[]}(h.openings,l,Pr,e),(h.openings||[]).lengththis._pointInRoom(t,e));if(!a)return;if(!confirm(this._t("confirm.delete_room",{name:a.name})))return;const l=this._curSpaceCfg;l&&(l.rooms=l.rooms.filter(t=>t.id!==a.id),this._commitOpenSpans(),this._saveConfig(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())}get _wallKeyPitch(){return Hs}get _spaceWalls(){const t=this._curSpaceCfg?.walls;return Array.isArray(t)?t:[]}_cfgOpenCuts(){return lo(this._curSpaceCfg?.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]])}_intervalCm(t){return Zn(this._spaceModel().rooms,this._spaceWalls,this._openCuts(),t,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)}_normalizeWalls(t,e){const i=function(t,e,i,s,n,o,r=1){if(!e?.length)return[];const a=[],l=new Set;for(const c of Xn(t,e,i,s,n,o,r))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),a.push({key:c.key,cm:c.cm}));return a}(this._spaceModel().rooms,t,e,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr);return En(i,this._curSpaceCfg?.rooms||[],Hs,1,e.map(t=>[t[0]/Pr,t[1]/Pr,t[2]/Pr,t[3]/Pr]))}_paperShapes(t){const e=this._spaceWalls;if(!e.length)return Me(t);const i=this._openPairs().flatMap(t=>t.segs);return so(t,e,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)}_thickWallCuts(){const t=this._spaceWalls;if(!t.length)return[];const e=this._openPairs().flatMap(t=>t.segs);return function(t,e,i,s,n,o,r=1){if(!e?.length)return[];const a=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Yn(t,c.id,e,i,s,n,o,r);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const u=Dn(e,i,s,r);if(a.has(u))continue;a.add(u);const _=xn(p,n,o),[g,m]=qn(d,t),f=-g,v=-m,b=_/2,y=[[e[0]+f*b,e[1]+v*b],[i[0]+f*b,i[1]+v*b],[i[0]+g*b,i[1]+m*b],[e[0]+g*b,e[1]+m*b]];l.push({key:u,kind:c,cm:p,quad:y,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}(this._spaceModel().rooms,t,e,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]])}_wallThickHit(t){const e=6*this._gridPitch,i=this._openCuts();let s=null;for(const n of Xn(this._spaceModel().rooms,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr)){const i=Bi(t,[n.a[0],n.a[1],n.b[0],n.b[1]]);i<=e&&(!s||i0?xn(e,this._cellCm,this._gridPitch):3*this._gridPitch,s=Math.max(i/2,1.25*this._gridPitch);let n="";for(const e of t.segs)n+=(n?" ":"")+Fn([[e[0],e[1]],[e[2],e[3]]],s,!1);return{segs:t.segs,open:t.open,d:n}}_wallThickClick(t){const e=this._wallThickHit(t);if(!e)return void this._showToast(this._t("toast.wallthick_pick"));if(e.open)return void this._showToast(this._t("toast.wallthick_open"));const i=e.cm,s=this._viewOr(this._baseVb()),n=(e.a[0]+e.b[0])/2,o=(e.a[1]+e.b[1])/2;this._wallDialog={a:e.a,b:e.b,value:kn(i,this._imperial),roomId:e.roomId,sx:(n-s.x)/s.w*100,sy:(o-s.y)/s.h*100}}_wallThickApply(t){const e=this._wallDialog;if(!e)return;const i=this._curSpaceCfg;if(!i)return;const s=$n(e.value,this._imperial),n=this._openCuts();let o;o=t&&e.roomId?In(i.walls,this._spaceModel().rooms,e.roomId,s,this._wallKeyPitch,n,Pr):On(i.walls,e.a,e.b,s,this._wallKeyPitch,Pr),o=this._normalizeWalls(o,n),o.length?i.walls=o:delete i.walls,this._wallDialog=null,this._showToast(this._t(null==s?"toast.wallthick_cleared":"toast.wallthick_set")),this._saveConfig(),this.requestUpdate()}_wallHatchDefs(t){if(!this._spaceWalls.length&&!this._markup)return B``;const e=Math.max(.4,1/Math.max(this._zoom,.4)),i=t||"var(--hp-muted, #607d8b)";return B`
+ `}_openCuts(){const t=this._curSpaceCfg;return mo(this._spaceModel().rooms,t?.open_spans,Ar,.02*this._gridPitch)}_openPairs(){const t=this._openCuts();if(!t.length)return[];const e=this._spaceModel().rooms.filter(t=>t.id),i=.02*this._gridPitch,s=[];for(let n=0;n{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return l.some(t=>Bi(e,t)<4*i)});c.length&&s.push({a:e[n],b:e[o],segs:c})}return s}_commitOpenSpans(t){const e=this._curSpaceCfg;if(!e)return;const i=.02*this._gridPitch;this._cfgEpoch++;const s=this._spaceModel().rooms;let n=lo(e.open_spans);n.length&&t?.old.length?n=wo(n,t.old,t.next,Ar):n.length||(n=fo(mo(s,null,Ar,i),Ar)),n=function(t,e,i,s){const n=lo(t);if(!n.length)return[];const o=uo(e,s);if(!o.length)return[];const r=[],a=Math.max(4*s,1e-6);for(const t of n){const e=ro(t,i),n=e[0],l=e[1],c=e[2]-n,h=e[3]-l,d=Math.hypot(c,h);if(d4*s||o>4*s)continue;const r=(t[0]-n)*p+(t[1]-l)*u,c=(t[2]-n)*p+(t[3]-l)*u,h=Math.max(0,Math.min(r,c)),g=Math.min(d,Math.max(r,c));if(g-ht.lo-e.lo||t.hi-e.hi);const e=[];for(const i of t){const t=e[e.length-1];t&&i.lo<=t.hi+a?t.hi=Math.max(t.hi,i.hi):e.push({...i})}for(const t of e){const e=[n+p*t.lo,l+u*t.lo],s=[n+p*t.hi,l+u*t.hi];Math.hypot(s[0]-e[0],s[1]-e[1])ro(t,Ar)))}_persistOpenCuts(t){const e=this._curSpaceCfg;if(!e)return;const i=fo(t,Ar);i.length?e.open_spans=i:delete e.open_spans,function(t,e,i,s){for(const e of t||[])e.open_to&&delete e.open_to;if(!i.length)return;const n=(e||[]).filter(t=>t?.id);new Map(n.map(t=>[t.id,t]));const o=new Map((t||[]).filter(t=>t?.id).map(t=>[t.id,t])),r=(t,e)=>{const i=o.get(t),s=o.get(e);i&&s&&((i.open_to||[]).includes(e)||(i.open_to=[...i.open_to||[],e]),(s.open_to||[]).includes(t)||(s.open_to=[...s.open_to||[],t]))};for(let t=0;tBi(i,t)<4*s)){r(n[t].id,n[e].id);break}}}for(const e of t||[])e.open_to&&!e.open_to.length&&delete e.open_to}(e.rooms||[],this._spaceModel().rooms,t,.02*this._gridPitch)}_closeOpenSpan(t){const e=this._curSpaceCfg;if(!e)return;const i=.02*this._gridPitch,s=function(t,e,i){const s=[(e[0]+e[2])/2,(e[1]+e[3])/2];return t.filter(t=>{const e=[(t[0]+t[2])/2,(t[1]+t[3])/2];return Math.hypot(e[0]-s[0],e[1]-s[1])>4*i})}(this._openCuts(),t,i);let n=this._normalizeWalls(e.walls,s);if(!(Zn(this._spaceModel().rooms,n,s,t,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)>0)){const e=[];for(const t of Xn(this._spaceModel().rooms,n,s,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar))t.open||e.push([t.a[0],t.a[1],t.b[0],t.b[1]]);n=bo(n,t,e,this._wallKeyPitch,Ar,15),n=this._normalizeWalls(n,s)}n.length?e.walls=n:delete e.walls,this._persistOpenCuts(s),this._showToast(this._t("toast.openwall_closed_span")),this._saveConfig(),this.requestUpdate()}_openWallClick(t){const e=6*this._gridPitch,i=.02*this._gridPitch,s=this._openCuts();if(this._openWallAnchor){const{p:n,edge:o}=this._openWallAnchor,r=ho(po(t,o,yo(o,s,i),this._gridPitch,1.5*this._gridPitch),o),a=Math.hypot(r[0]-n[0],r[1]-n[1]);if(this._openWallAnchor=null,a<.5*this._gridPitch)return void this._showToast(this._t("toast.openwall_short"));if(Bi(t,o)>e)return void this._showToast(this._t("toast.openwall_pick"));const l=[n[0],n[1],r[0],r[1]],c=[...s,l],h=this._curSpaceCfg;if(!h)return;const d=this._normalizeWalls(h.walls,c);d.length?h.walls=d:delete h.walls;const p=(h.openings||[]).length;return h.openings=function(t,e,i,s){return t?.length?t.filter(t=>Bi([Number(t.x)*i,Number(t.y)*i],e)>s||!Nn([e[0],e[1]],[e[2],e[3]],Number(t.angle)||0)):t?t.slice():[]}(h.openings,l,Ar,e),(h.openings||[]).lengththis._pointInRoom(t,e));if(!a)return;if(!confirm(this._t("confirm.delete_room",{name:a.name})))return;const l=this._curSpaceCfg;l&&(l.rooms=l.rooms.filter(t=>t.id!==a.id),this._commitOpenSpans(),this._saveConfig(),this._regSignature="",this._maybeRebuildDevices(),this.requestUpdate())}get _wallKeyPitch(){return qs}get _spaceWalls(){const t=this._curSpaceCfg?.walls;return Array.isArray(t)?t:[]}_cfgOpenCuts(){return lo(this._curSpaceCfg?.open_spans).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]])}_intervalCm(t){return Zn(this._spaceModel().rooms,this._spaceWalls,this._openCuts(),t,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)}_normalizeWalls(t,e){const i=function(t,e,i,s,n,o,r=1){if(!e?.length)return[];const a=[],l=new Set;for(const c of Xn(t,e,i,s,n,o,r))!c.open&&c.cm>0&&!l.has(c.key)&&(l.add(c.key),a.push({key:c.key,cm:c.cm}));return a}(this._spaceModel().rooms,t,e,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar);return En(i,this._curSpaceCfg?.rooms||[],qs,1,e.map(t=>[t[0]/Ar,t[1]/Ar,t[2]/Ar,t[3]/Ar]))}_paperShapes(t){const e=this._spaceWalls;if(!e.length)return Me(t);const i=this._openPairs().flatMap(t=>t.segs);return so(t,e,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)}_thickWallCuts(){const t=this._spaceWalls;if(!t.length)return[];const e=this._openPairs().flatMap(t=>t.segs);return function(t,e,i,s,n,o,r=1){if(!e?.length)return[];const a=new Set,l=[];for(const c of t||[]){if(!c?.id)continue;const h=Yn(t,c.id,e,i,s,n,o,r);if(!h)continue;const d=h.poly;for(let t=0;t0))continue;const u=Dn(e,i,s,r);if(a.has(u))continue;a.add(u);const _=xn(p,n,o),[g,m]=Hn(d,t),f=-g,v=-m,b=_/2,y=[[e[0]+f*b,e[1]+v*b],[i[0]+f*b,i[1]+v*b],[i[0]+g*b,i[1]+m*b],[e[0]+g*b,e[1]+m*b]];l.push({key:u,kind:c,cm:p,quad:y,a:[e[0],e[1]],b:[i[0],i[1]],depthUnits:_})}}return l}(this._spaceModel().rooms,t,e,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar).map(t=>[t.a[0],t.a[1],t.b[0],t.b[1]])}_wallThickHit(t){const e=6*this._gridPitch,i=this._openCuts();let s=null;for(const n of Xn(this._spaceModel().rooms,this._spaceWalls,i,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar)){const i=Bi(t,[n.a[0],n.a[1],n.b[0],n.b[1]]);i<=e&&(!s||i0?xn(e,this._cellCm,this._gridPitch):3*this._gridPitch,s=Math.max(i/2,1.25*this._gridPitch);let n="";for(const e of t.segs)n+=(n?" ":"")+Fn([[e[0],e[1]],[e[2],e[3]]],s,!1);return{segs:t.segs,open:t.open,d:n}}_wallThickClick(t){const e=this._wallThickHit(t);if(!e)return void this._showToast(this._t("toast.wallthick_pick"));if(e.open)return void this._showToast(this._t("toast.wallthick_open"));const i=e.cm,s=this._viewOr(this._baseVb()),n=(e.a[0]+e.b[0])/2,o=(e.a[1]+e.b[1])/2;this._wallDialog={a:e.a,b:e.b,value:kn(i,this._imperial),roomId:e.roomId,sx:(n-s.x)/s.w*100,sy:(o-s.y)/s.h*100}}_wallThickApply(t){const e=this._wallDialog;if(!e)return;const i=this._curSpaceCfg;if(!i)return;const s=$n(e.value,this._imperial),n=this._openCuts();let o;o=t&&e.roomId?In(i.walls,this._spaceModel().rooms,e.roomId,s,this._wallKeyPitch,n,Ar):On(i.walls,e.a,e.b,s,this._wallKeyPitch,Ar),o=this._normalizeWalls(o,n),o.length?i.walls=o:delete i.walls,this._wallDialog=null,this._showToast(this._t(null==s?"toast.wallthick_cleared":"toast.wallthick_set")),this._saveConfig(),this.requestUpdate()}_wallHatchDefs(t){if(!this._spaceWalls.length&&!this._markup)return B``;const e=Math.max(.4,1/Math.max(this._zoom,.4)),i=t||"var(--hp-muted, #607d8b)";return B`
- `}_renderWallBodies(t){if(t&&!t.showBorders&&!this._markup)return B``;const e=this._spaceWalls;if(!e.length)return B``;const i=this._openPairs().flatMap(t=>t.segs),s=(this._curSpaceCfg?.openings||[]).map(t=>({x:Number(t.x)*Pr,y:Number(t.y)*Pr,angle:Number(t.angle)||0,length:(Number(t.length)>0?Number(t.length):.9)*Pr})),n=eo(this._spaceModel().rooms,e,i,s,this._wallKeyPitch,this._cellCm,this._gridPitch,Pr);if(!n)return B``;const o=this._stageEl,r=this._viewOr(this._baseVb()),a=o&&o.clientWidth&&r.w?o.clientWidth/r.w:1,l=t?.color||"var(--hp-muted)",c=yn(n.depthUnits,a),h=this._fillColors.wall_fill;return B`
+
`}_renderWallBodies(t){if(t&&!t.showBorders&&!this._markup)return B``;const e=this._spaceWalls;if(!e.length)return B``;const i=this._openPairs().flatMap(t=>t.segs),s=(this._curSpaceCfg?.openings||[]).map(t=>({x:Number(t.x)*Ar,y:Number(t.y)*Ar,angle:Number(t.angle)||0,length:(Number(t.length)>0?Number(t.length):.9)*Ar})),n=eo(this._spaceModel().rooms,e,i,s,this._wallKeyPitch,this._cellCm,this._gridPitch,Ar);if(!n)return B``;const o=this._stageEl,r=this._viewOr(this._baseVb()),a=o&&o.clientWidth&&r.w?o.clientWidth/r.w:1,l=t?.color||"var(--hp-muted)",c=yn(n.depthUnits,a),h=this._fillColors.wall_fill;return B`
- `:W``}_openingClick(t,e=!1){const i=1.5*this._gridPitch,s=this._openingsR.find(e=>Math.hypot(t[0]-e.rx,t[1]-e.ry)<=Math.max(e.rlen/2,i));if(s)return void this._editOpening(s);const n=De(t,this._spaceModel().rooms,i);if(!n)return void this._showToast(this._t("toast.opening_no_wall"));if(function(t,e,i,s,n){for(const o of s)if(!(Bi([t,e],o)>n)&&Nn([o[0],o[1]],[o[2],o[3]],i))return!0;return!1}(n.x,n.y,n.angle,this._openCuts(),i))return void this._showToast(this._t("toast.opening_on_virtual"));const o=this._opRuler(n,this._cmToUnits(90),e);this._openingDialog={type:"door",lengthCm:90,contact:"",lock:"",invert:!1,flipH:!1,flipV:!1,x:o.x,y:o.y,angle:o.angle},this._cursorPt=null}_editOpening(t){this._openingDialog={id:t.id,type:t.type,lengthCm:Math.round(t.rlen/this._gridPitch*this._cellCm),contact:t.contact||"",lock:t.lock||"",invert:!!t.invert,flipH:!!t.flip_h,flipV:!!t.flip_v,x:t.rx,y:t.ry,angle:t.angle}}_opPointerDown(t,e){if("plan"===this._mode&&"resize"!==this._tool){t.preventDefault(),t.stopPropagation();try{Nr(t)}catch{}this._opDrag={id:e.id,moved:!1,sx:t.clientX,sy:t.clientY,dirty:!1}}}_opPointerMove(t,e){if(!this._opDrag||this._opDrag.id!==e.id)return;if(Math.abs(t.clientX-this._opDrag.sx)+Math.abs(t.clientY-this._opDrag.sy)<=3)return;const i=De(this._svgPoint(t),this._spaceModel().rooms,4*this._gridPitch);if(!i)return;this._opDrag.moved=!0;const s=this._curSpaceCfg,n=s?.openings?.find(t=>t.id===e.id);if(!n)return;const o=this._opRuler(i,n.length*Pr,t.shiftKey);this._opMeasure=o.measure;const r=o.x/Pr,a=o.y/this._spaceH;n.x===r&&n.y===a&&n.angle===i.angle||(this._opDrag.dirty=!0),n.x=r,n.y=a,n.angle=i.angle,this.requestUpdate()}_opRuler(t,e,i){const s=this._spaceModel().rooms,n=this._gridPitch/2;let o=t.x,r=t.y,a=Te([o,r],t.angle,e,s,n);if(!a||!a.centered||i||o===a.wallCenter[0]&&r===a.wallCenter[1]){if(a&&!i){const[i,l]=a.wallA,[c,h]=a.wallB,d=c-i,p=h-l,u=Math.hypot(d,p);if(u>0){const c=this._gridPitch,h=Math.min(e/2,u/2);let _=Math.round(((o-i)*d+(r-l)*p)/u/c)*c;_=Math.max(h,Math.min(u-h,_)),o=i+_/u*d,r=l+_/u*p,a=Te([o,r],t.angle,e,s,n)||a}}}else[o,r]=a.wallCenter,a=Te([o,r],t.angle,e,s,n);if(!a)return{x:o,y:r,angle:t.angle,measure:null};const l="mi"===this.hass?.config?.unit_system?.length,c=(t,e)=>({x:e[0],y:e[1],text:$e(t/this._gridPitch*this._cellCm,l)});return{x:o,y:r,angle:t.angle,measure:{labels:[c(a.sideA,a.midA),c(a.sideB,a.midB)],guide:a.centered&&!i?{x:a.wallCenter[0],y:a.wallCenter[1],angle:t.angle}:null}}}_opPointerUp(t,e){if(!this._opDrag||this._opDrag.id!==e.id)return;const i=this._opDrag.moved;this._opMeasure=null,i&&this._opDrag.dirty&&this._saveConfig(),i?window.setTimeout(()=>this._opDrag=null,0):this._opDrag=null}_opClick(t,e){"plan"===this._mode&&"resize"===this._tool||(t.stopPropagation(),this._opDrag?.moved||"plan"===this._mode&&this._editOpening(e))}_saveOpening(){const t=this._openingDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._spaceH,s={id:t.id||"o"+Date.now().toString(36),type:t.type,x:t.x/Pr,y:t.y/i,angle:t.angle,length:this._cmToUnits(Math.max(20,t.lengthCm))/Pr,contact:t.contact||null,lock:"door"===t.type&&t.lock||null,invert:t.invert||void 0,flip_h:t.flipH||void 0,flip_v:t.flipV||void 0};e.openings=e.openings||[];const n=e.openings.findIndex(t=>t.id===s.id);n>=0?e.openings[n]=s:e.openings.push(s),this._saveConfig(),this._openingDialog=null,this.requestUpdate()}_deleteOpening(){const t=this._openingDialog,e=this._curSpaceCfg;t?.id&&e?.openings&&(e.openings=e.openings.filter(e=>e.id!==t.id),this._saveConfig(),this._openingDialog=null,this.requestUpdate())}_contactCandidates(){const t=[];for(const e of Object.keys(this.hass.states)){const i=e.split(".")[0];if("binary_sensor"!==i&&"cover"!==i)continue;const s=this.hass.states[e],n=["door","window","opening","garage_door","garage"].includes(s?.attributes?.device_class||"");("cover"!==i||n)&&t.push([e,s?.attributes?.friendly_name||e,n?0:1])}return t.sort((t,e)=>t[2]-e[2]||t[1].localeCompare(e[1])).map(([t,e])=>({value:t,label:e}))}_lockCandidates(){return Object.keys(this.hass.states).filter(t=>t.startsWith("lock.")).map(t=>({value:t,label:this.hass.states[t]?.attributes?.friendly_name||t})).sort((t,e)=>t.label.localeCompare(e.label))}_mergeClick(t){const e=this._spaceModel().rooms,i=[...e].reverse().find(e=>this._pointInRoom(t,e));if(!i?.id)return;const s=i.id;if(!this._mergeSel||this._mergeSel===s)return void(this._mergeSel=this._mergeSel===s?null:s);const n=e.find(t=>t.id===this._mergeSel),o=n?Se(n):null,r=Se(i),a=o&&r?Ve(o,r):null;if(!a)return this._showToast(this._t("toast.merge_not_adjacent")),void(this._mergeSel=null);this._mergeDialog={aId:this._mergeSel,bId:s,poly:a,pick:"a"},this._mergeSel=null}_commitMerge(){const t=this._mergeDialog,e=this._curSpaceCfg;if(!t||!e)return;const i=this._spaceH,s="a"===t.pick?t.aId:t.bId,n="a"===t.pick?t.bId:t.aId,o=e.rooms.find(t=>t.id===s);o?(o.poly=t.poly.map(t=>[t[0]/Pr,t[1]/i]),delete o.x,delete o.y,delete o.w,delete o.h,e.rooms=e.rooms.filter(t=>t.id!==n),this._commitOpenSpans(),this._saveConfig(),this._mergeDialog=null,this._regSignature="",this._maybeRebuildDevices(),this._showToast(this._t("toast.rooms_merged",{name:o.name||""}))):this._mergeDialog=null}_splitClick(t,e=!1){const i=this._spaceModel().rooms;if(!this._splitSel){const e=[...i].reverse().find(e=>this._pointInRoom(t,e));if(!e?.id)return;return void(this._splitSel={roomId:e.id,pts:[]})}const s=i.find(t=>t.id===this._splitSel.roomId),n=s?Se(s):null;if(!s||!n)return void(this._splitSel=null);const o=.02*this._gridPitch,r=6*this._gridPitch,a=Ee(t,n),l=a&&!e&&function(t,e,i){let s=null,n=1/0;for(let o=0;o